Colo alteration image acquisition GUI

2 Ansichten (letzte 30 Tage)
Mariottide
Mariottide am 20 Apr. 2012
Bearbeitet: DGM am 3 Okt. 2024
Hi to everybody,
I have a GUI which must acquire images from a web cam, and show two images in two windows.
In the first axes i show the original frame, and in the second axes, i 'd like to show the image after a short elaboration. In this second image i got problems, only if i make it show the raw 'shot' (see below) i got a correct output (the same as the first window), in all the other cases (as in the one reported below) i get a reddish image in false color.Even using the img2bw conversion, the image in the second windows is in the same absurd colors..
Below i report the callback text, in the OpFn I just inizialise the acquisition. Nowhere in the code is a reference to this axes, or other instructions that could be in some way related to this.
start(handles.video1);
for j=1:200
shot=getsnapshot(handles.video1);
imshow(shot);
image(shot, 'Parent',handles.axes1);
R = shot(:,:,1); %to show only the red channel
image(R, 'Parent',handles.axes2);
end
Thak you for your help mario

Antworten (1)

DGM
DGM am 30 Sep. 2024
Bearbeitet: DGM am 3 Okt. 2024
If you want to use image() instead of imshow(), you'll need to read the synopsis. RGB inputs are rendered in truecolor, and are dependent on no other information other than the ranges implied by the numeric class (which are handled internally).
inpict = imread('peppers.png');
% this is displayed in color, since it's MxNx3
image(inpict);
Single-channel inputs might be intensity (grayscale) or indexed-color images, but they are always treated as colormapped images. By default, image() operates using 'direct' colormapping, where the integer values in the array are mapped directly to the row indices of the current figure colormap. That's how indexed-color images are handled, but it incidentally works for integer-class grayscale images if the colormap is an appropriate length for the given class. That wouldn't have been the default case in R2012a. While this is obviously colormapped, it's at least not blown out, but it would have been if the same code were run in an older version due to the different default map lengths.
% this is displayed in pseudocolor, since it's MxNx1
% and the default colormap is probably still parula()
% this coincidentally works because the image is uint8 (256 discrete levels)
% and the modern default map length is 256 instead of 64
R = inpict(:,:,1); % to show only the red channel
image(R);
If you want a gray colormap instead of whatever the current default is, you need to specify one of the correct length.
% specify a gray colormap of the correct length
% this only works for integer-class inputs
figure
image(R);
ncolors = diff(getrangefromclass(R)); % get the map length
colormap(gray(ncolors)) % explicitly specify the map length
Why not just call gray() without any arguments and let it magically set the map without all that extra work? Because it won't work half the time. When called like this, colormap generator tools query the figure to get its current map length, or the default map length. Even if you clear the figure, you will get a completely unpredictable map length unless you explicitly specify it. In older versions like R2012a, the default map length is 64, so even a virgin figure will cause map generators to return maps that are too short for uint8 image display.
% don't ever trust implicitly generated maps to be the right length
figure % a new figure
colormap(jet(64)) % we were doing something else before
% ... and so on
clf % but we cleared it
image(R); % then we do the same thing as before
colormap(gray) % but it doesn't work because we were lazy
Otherwise, for intensity images on other scales (e.g. unit-scale float), you would have to specify 'scaled' for the 'cdatamapping' property -- or just use imagesc() instead of image(), and you'd have to set the corresponding limits for clim(). Unlike the case with RGB inputs, the class-appropriate limits are not used, since the input is presumed to be arbitrarily-scaled. By default, the data extrema are used, so if you want to use the dynamic range expected of the class, you need to explicitly specify it.
% using scaled colormapping for handling intensity images
% without needing to pretend it's an indexed-color image
figure
crange = getrangefromclass(R); % get clim
imagesc(R,crange); % specify clim
colormap(gray(256)) % map length only needs to be visually adequate
You can avoid all that baloney by just expanding single-channel images so that they're handled as RGB. No class-dependent properties need to be derived or specified explicitly.
% if you want to avoid issues with colormapping
% just expand single channel inputs
image(repmat(R,[1 1 3]));
Takeaways:
  • RGB images only need to be properly scaled for their class
  • Single-channel images are colormapped, and the mapping can be either direct or scaled
  • The integer values of a direct colormapped image map directly to colormap rows. The numeric class determines whether the indexing is zero-based (integer-class) or one-based (float-class).
  • In scaled colormapping, the endpoints of the colormap correspond to the limits specified in clim().
  • Default colormap lengths have changed over the years
  • Colormap generator tools should be used with an explicit length parameter unless you understand how the defaults are derived.

Community Treasure Hunt

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

Start Hunting!

Translated by