Matlab Live Integrated Spectrometer

2 次查看(过去 30 天)
Bera
Bera 2025-3-19
回答: sanidhyak 2025-9-2
Hey All
As the title suggests, I'm essentially working on a live spectrometer code and I'm having some issues with having it get displayed.
I have provided the code I'm using alongside the error message I keep getting.
Error Message:
Warning: Arrays have incompatible sizes for this operation.
In Raster_SpecificQD_LEDFinderGUI/previewCallback (line 902)
In Raster_SpecificQD_LEDFinderGUI>@(obj,event,hImage)previewCallback(app,obj,event,hImage) (line 2055) In imaqdevice.preview>localInvokeAppData (line 353) In imaqdevice.preview>localUpdateWindow (line 331) In Raster_SpecificQD_LEDFinderGUI/StartStopLiveSpectrumButtonValueChanged (line 2060) In matlab.apps.AppBase>@(source,event)executeCallback(ams,app,callback,requiresEventData,event) (line 62)
function previewCallback(app,obj,event,hImage)
try
% Get the latest frame
Emission_Reading_Img = event.Data;
% Ensure image dimensions match preview
if size(Emission_Reading_Img) ~= size(app.ImagePreview.CData)
set(app.ImagePreview, 'CData', zeros(size(Emission_Reading_Img)));
end
% Convert to grayscale if needed
if size(Emission_Reading_Img, 3) == 3
Emission_Reading_Img = rgb2gray(Emission_Reading_Img);
end
% Update live preview image
set(app.ImagePreview, 'CData', Emission_Reading_Img);
% Process spectrum
height = size(Emission_Reading_Img, 1);
central_row = app.ROI_Middle_Pixel;
window_size = round(height * app.ROI_Percentage_Decimal);
valid_rows = max(1, central_row - window_size) : min(height, central_row + window_size);
% Compute spectrum sum and subtract background
spectrum_sum = sum(Emission_Reading_Img(valid_rows, :), 1);
background_Img = sum(app.background_img(valid_rows, :), 1);
spectrum_sum = spectrum_sum - background_Img;
% Update spectrum plot
if isempty(app.PlotHandle) || ~isvalid(app.PlotHandle)
app.PlotHandle = plot(app.SpectrumAxes, app.wvlength, spectrum_sum, 'b');
xlabel(app.SpectrumAxes, 'Wavelength (nm)');
ylabel(app.SpectrumAxes, 'Arb. Counts');
else
set(app.PlotHandle, 'YData', spectrum_sum);
end
drawnow limitrate;
catch ME
warning('Acquisition Error: %s', ME.message);
end
% Value changed function: StartStopLiveSpectrumButton
function StartStopLiveSpectrumButtonValueChanged(app, event)
% Load background average (if not already loaded)
if ~isfield(app, 'background_img')
app.background_img = app.data.background_img;
end
% % check if background photos have been snapped
% pass = BackgroundPhotoExistenceCheck(app,"Live Spectrum");
% if pass ~= 1
% app.StartStopLiveSpectrumButton.Value = 0;
% return
% end
if app.StartStopLiveSpectrumButton.Value % Button is toggled on
app.StartStopLiveSpectrumButton.Enable = "off";
app.Sound_Button_pressed()
app.StartStopLiveSpectrumButton.BackgroundColor = 'g';
% Create the figure and axes for the live spectrum display
screenSize = get(0, 'ScreenSize'); % gets pixel resolution of screen
dimensions_ASI = app.vid_ASI.VideoResolution; % Get the resolution of the video input
width = dimensions_ASI(1); % Video width
height = dimensions_ASI(2); % Video height
% Shrink the figure to a fraction of the original resolution
figWidth = round(width / 8);
figHeight = round(height / 8);
% Position the window on the screen (shifted right and centered vertically)
left = (screenSize(3) - figWidth) * 0.75;
bottom = (screenSize(4) - figHeight) / 2;
% Create a figure with specified dimensions and position
app.spectrumFig = figure('Name', 'Live Spectrum Display','Units', 'pixels', 'Position', [left, bottom, figWidth, figHeight], "NumberTitle", "off",'WindowStyle', 'modal');
% Create axes within the figure (slightly smaller for padding)
app.spectrumAxes = axes('Units', 'pixels', 'Position', [10, 10, figWidth - 20, figHeight - 20]);
app.PlotHandle = plot(app.spectrumAxes, nan, nan); % Initialize with empty data
xlabel(app.spectrumAxes, 'Wavelength (nm)');
ylabel(app.spectrumAxes, 'Arb. Counts');
% set to new camera settings
reinitialize_ASI_Camera(app,"immediate")
% Create the image object for preview
resolution = app.vid_ASI.VideoResolution;
nbands = app.vid_ASI.NumberOfBands;
app.ImagePreview = image(app.spectrumAxes,zeros(resolution(2), resolution(1), nbands));
% Set the callback function for updating the preview window
setappdata(app.ImagePreview,'UpdatePreviewWindowFcn',@(obj,event,hImage) previewCallback(app,obj,event,hImage));
% Start the preview
preview(app.vid_ASI, app.ImagePreview);
app.StartStopLiveSpectrumButton.Enable = "on";
pause(2)
else % Button is toggled off
% Stop the preview and clean up
app.StartStopLiveSpectrumButton.Enable = "off";
app.Sound_Button_pressed()
app.StartStopLiveSpectrumButton.BackgroundColor = app.DefaultColour;
% set camera settings back to the old version
reinitialize_ASI_Camera(app,"")
if ~isempty(app.vid_ASI) && isvalid(app.vid_ASI)
stoppreview(app.vid_ASI);
end
% Close the spectrum figure if it exists
if ~isempty(app.spectrumFig) && ishandle(app.spectrumFig)
close(app.spectrumFig);
app.spectrumFig = []; % Clear the figure handle
end
app.StartStopLiveSpectrumButton.Enable = "on";
pause(2)
end
end

回答(1 个)

sanidhyak
sanidhyak 2025-9-2
Hi @Bera,
I understand that you are trying to implement a live spectrometer in MATLAB, but you are facing the mentioned issue with it. This issue actually occurs in the “previewCallback” function because you are comparing the dimensions of the incoming video frame (“event.Data”) and the preview image data (“app.ImagePreview.CData”) using the “~=” operator. MATLAB interprets this as an element-wise comparison, which fails if the two arrays have different numbers of dimensions.
To resolve this, you should use “isequal” instead of “~=” when comparing sizes. Kindly refer to the corrected code snippet below:
function previewCallback(app,obj,event,hImage)
try
% Get the latest frame
Emission_Reading_Img = event.Data;
% Ensure preview has the same size
if ~isequal(size(Emission_Reading_Img), size(app.ImagePreview.CData))
set(app.ImagePreview, 'CData', zeros(size(Emission_Reading_Img), 'like', Emission_Reading_Img));
end
% Convert to grayscale if needed
if size(Emission_Reading_Img, 3) == 3
Emission_Reading_Img = rgb2gray(Emission_Reading_Img);
end
% Update live preview image
set(app.ImagePreview, 'CData', Emission_Reading_Img);
% Process spectrum
height = size(Emission_Reading_Img, 1);
central_row = app.ROI_Middle_Pixel;
window_size = round(height * app.ROI_Percentage_Decimal);
valid_rows = max(1, central_row - window_size) : min(height, central_row + window_size);
% Compute spectrum sum and subtract background
spectrum_sum = sum(Emission_Reading_Img(valid_rows, :), 1);
background_Img = sum(app.background_img(valid_rows, :), 1);
% Resize background if needed
if ~isequal(size(spectrum_sum), size(background_Img))
background_Img = background_Img(1:min(end, numel(spectrum_sum)));
end
spectrum_sum = spectrum_sum - background_Img;
% Update spectrum plot
if isempty(app.PlotHandle) || ~isvalid(app.PlotHandle)
app.PlotHandle = plot(app.SpectrumAxes, app.wvlength, spectrum_sum, 'b');
xlabel(app.SpectrumAxes, 'Wavelength (nm)');
ylabel(app.SpectrumAxes, 'Arb. Counts');
else
set(app.PlotHandle, 'YData', spectrum_sum);
end
drawnow limitrate;
catch ME
warning('Acquisition Error: %s', ME.message);
end
end
In this, the main change is:
if ~isequal(size(Emission_Reading_Img), size(app.ImagePreview.CData))
This will ensures that MATLAB checks the dimensions safely, avoiding the incompatible size warning you are getting in your code.
For further reference, kindly refer to the following official documentation:
Cheers & Happy Coding!

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by