Search code examples
matlabimage-processingrgbgrayscaleroi

How to find and highlight the brightest region an image in Matlab?


Dears,

I would like to kindly ask you for support. My goal is to find the brightest region of the RGB image and highlight it without additional tools. Please see my example below.

rgbImage = imread( 'Zoom1_WhiteImage.png' );
imshow(rgbImage);

[rows, columns, numberOfColorChannels] = size(rgbImage)

[x, y] = meshgrid(1:columns, 1:rows);
% Extract the individual red, green, and blue color channels.
% Need to cast to double or else x and y will be clipped to 255 when we concatenate them.
if numberOfColorChannels == 1
    % Leave as gray scale.
    % Get array listing [r, g, b, x, y].  Using (:) will turn all the 2-D arrays into column vectors.
    output = [rgbImage(:), x(:), y(:)];
else
    redChannel = double(rgbImage(:, :, 1));
    greenChannel = double(rgbImage(:, :, 2));
    blueChannel = double(rgbImage(:, :, 3));
    % Get array listing [r, g, b, x, y].  Using (:) will turn all the 2-D arrays into column vectors.
    output = [redChannel(:), greenChannel(:), blueChannel(:), x(:), y(:)];
end

[rows, columns] = find(rgbImage == 155);
imshow(rgbImage);
hold on

Unfortunately, I am struggling with how to proceed with the plot of the points that should overlay the grey image.

Would you be so kind and help me to finish the code, please?


Solution

  • I'd recommend you read about logical indexing in MATLAB - it's a very powerful concept, and it allows you to skip most of the things you're trying to do by flattening the arrays, and creating separate arrays of indices with meshgrid. Here is an article that addresses logical indexing down at the bottom, for example.

    I've modified and added to your code so it accomplishes the job using logical indexing. I tested this in R2019b.

    rgbImage = imread( 'Zoom1_WhiteImage.png' );
    imshow(rgbImage);
    
    [rows, columns, numberOfColorChannels] = size(rgbImage)
    
    % This is unnecessary - the 'find' command will generate the indices 
    %   without you preparing a matrix of them:
    % [x, y] = meshgrid(1:columns, 1:rows);   
    
    if numberOfColorChannels == 1
        % No need to flatten the image, or combine it with indices:
        %output = [rgbImage(:), x(:), y(:)];
    
        brightness = rgbImage;  % For a 1 channel image, brightness is the same as the original pixel value.
    
    else
    %     redChannel = double(rgbImage(:, :, 1));
    %     greenChannel = double(rgbImage(:, :, 2));
    %     blueChannel = double(rgbImage(:, :, 3));
        % Get array listing [r, g, b, x, y].  Using (:) will turn all the 2-D arrays into column vectors.
    %     output = [redChannel(:), greenChannel(:), blueChannel(:), x(:), y(:)];
    
        % For an RGB image, the brightness can be estimated in various ways, here's one standard formula: 
        brightness = (0.2126*rgbImage(:, :, 1) + 0.7152*rgbImage(:, :, 2) + 0.0722*rgbImage(:, :, 3));
    end
    
    % Establish a brightness threshold - pixels brighter than this value will
    % be highlighted
    threshold = 215;
    
    % Create a zero-filled mask of equal size to the image to hold the
    % information of which pixels met the brightness criterion:
    mask = zeros(rows, columns, 'logical');
    
    % Assign "1" to any mask pixels whose corresponding image pixel met the
    % brightness criterion:
    mask(brightness > threshold) = 1;
    
    figure;
    % Overlay and display mask. imoverlay was introduced in R2017, but the 
    % syntax has changed a bit, so check the version you're using. You can also
    % use imfuse, or imshowpair, or make your own image blending algorithm, 
    % depending on how you want it to look.
    imshow(imoverlay(rgbImage, mask, 'red'));
    hold on