calculation of histogram only from the foreground

Hi,
I am stuck with this idea and code for the past three months, I have tried n number of codes but all was a failure. I would like to calculate the histogram only from the foreground image, and I have to split the histogram into two one below the middle value and one part above the middle value, all this has to be done without including the background. I am attaching my image with my code please do help with the code. I have also asked in this forum in different ways, but none of the help worked in my project, so I requesting to have a correction of my code.

Antworten (1)

Image Analyst
Image Analyst am 13 Jun. 2020
Three months, oh my gosh. Well here's something I whipped together in about 15 minutes that does what I think you asked for. First it finds masks for the face and background. Then, for each color channel, it computes the mean and median. Then it masks the image by the values above and below the median and computes the histogram for each masked image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
fprintf('Beginning to run %s.m ...\n', mfilename);
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in image.
folder = pwd;
baseFileName = 'originalimg.jpg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the RGB image full size.
subplot(4, 4, 1);
imshow(rgbImage, []);
axis('on', 'image');
caption = sprintf('Original Image : "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
hFig1 = gcf;
hFig1.Units = 'Normalized';
hFig1.WindowState = 'maximized';
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
hFig1.Name = 'Demo by Image Analyst';
% Threshold the image to find the background.
[backgroundMask, maskedRGBImage] = createMask(rgbImage);
% Take the largest 4 blobs only.
backgroundMask = bwareafilt(backgroundMask, 4);
% Fill holes
backgroundMask = imfill(backgroundMask, 'holes');
% Display the binary image.
subplot(4, 4, 2);
imshow(backgroundMask, []);
axis('on', 'image');
caption = sprintf('Background Mask Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Get the face mask
faceMask = imfill(~backgroundMask, 'holes');
% Display the binary image.
subplot(4, 4, 3);
imshow(faceMask, []);
axis('on', 'image');
caption = sprintf('Face Mask Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Extract the individual red, green, and blue color channels using imsplit() (introduced in R2018b).
[redChannel, greenChannel, blueChannel] = imsplit(rgbImage);
% Display the color images along the left edge of the figure.
% Display the red image.
subplot(4, 4, 5);
imshow(redChannel, []);
axis('on', 'image');
caption = sprintf('Red Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Display the green image.
subplot(4, 4, 9);
imshow(greenChannel, []);
axis('on', 'image');
caption = sprintf('Green Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Display the blue image.
subplot(4, 4, 13);
imshow(blueChannel, []);
axis('on', 'image');
caption = sprintf('Blue Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Get the histogram of each channel.
redCounts = imhist(redChannel);
greenCounts = imhist(greenChannel);
blueCounts = imhist(blueChannel);
% Display the red histogram.
subplot(4, 4, 6);
bar(redCounts);
title('Red Histogram', 'FontSize', fontSize);
xlabel('Red Gray Level', 'FontSize', fontSize);
ylabel('Counts', 'FontSize', fontSize);
grid on;
% Find the mean and median and plot the mean in red and the median in blue.
aveR = mean(redChannel(faceMask))
medR = median(redChannel(faceMask))
xline(aveR, 'Color', 'r', 'LineWidth', 2);
xline(double(medR), 'Color', 'm', 'LineWidth', 2);
% Display the green histogram.
subplot(4, 4, 10);
bar(greenCounts);
title('Green Histogram', 'FontSize', fontSize);
xlabel('Green Gray Level', 'FontSize', fontSize);
ylabel('Counts', 'FontSize', fontSize);
grid on;
% Find the mean and median and plot the mean in red and the median in blue.
aveG = mean(greenChannel(faceMask))
medG = median(greenChannel(faceMask))
xline(aveG, 'Color', 'r', 'LineWidth', 2);
xline(double(medG), 'Color', 'b', 'LineWidth', 2); % xline() cannot take integers for some bizarre reason so must cast it to double.
% Display the blue histogram.
subplot(4, 4, 14);
bar(blueCounts);
title('Blue Histogram', 'FontSize', fontSize);
xlabel('Blue Gray Level', 'FontSize', fontSize);
ylabel('Counts', 'FontSize', fontSize);
grid on;
% Find the mean and median and plot the mean in red and the median in blue.
aveB = mean(blueChannel(faceMask))
medB = median(blueChannel(faceMask))
xline(aveB, 'Color', 'r', 'LineWidth', 2);
xline(double(medB), 'Color', 'b', 'LineWidth', 2);
% Get the masks for each color above and below the median.
brightMaskR = (redChannel > medR) & faceMask;
brightMaskG = (greenChannel > medG) & faceMask;
brightMaskB = (blueChannel > medB) & faceMask;
darkMaskR = (redChannel <= medR) & faceMask;
darkMaskG = (greenChannel <= medG) & faceMask;
darkMaskB = (blueChannel <= medB) & faceMask;
% Mask the gray scale images.
% Mask the image using bsxfun() function to multiply the mask by each channel individually. Works for gray scale as well as RGB Color images.
brightR = bsxfun(@times, redChannel, cast(brightMaskR, 'like', redChannel));
brightG = bsxfun(@times, greenChannel, cast(brightMaskG, 'like', greenChannel));
brightB = bsxfun(@times, blueChannel, cast(brightMaskB, 'like', blueChannel));
darkR = bsxfun(@times, redChannel, cast(darkMaskR, 'like', redChannel));
darkG = bsxfun(@times, greenChannel, cast(darkMaskG, 'like', greenChannel));
darkB = bsxfun(@times, blueChannel, cast(darkMaskB, 'like', blueChannel));
% Display the the bright and dark mask images.
% Display bright and dark Red images.
subplot(4, 4, 7);
imshow(brightR);
axis('on', 'image');
caption = sprintf('Red Bright Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
subplot(4, 4, 8);
imshow(darkR);
axis('on', 'image');
caption = sprintf('Red Dark Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Display bright and dark Green images.
subplot(4, 4, 11);
imshow(brightG);
axis('on', 'image');
caption = sprintf('Green Bright Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
subplot(4, 4, 12);
imshow(darkG);
axis('on', 'image');
caption = sprintf('Green Dark Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Display bright and dark Blue images.
subplot(4, 4, 15);
imshow(brightB);
axis('on', 'image');
caption = sprintf('Blue Bright Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
subplot(4, 4, 16);
imshow(darkB);
axis('on', 'image');
caption = sprintf('Blue Dark Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Get the histogram above and below the median values for each color channel
upperHistR = imhist(redChannel(brightMaskR));
lowerHistR = imhist(redChannel(darkMaskR));
upperHistG = imhist(redChannel(brightMaskG));
lowerHistG = imhist(redChannel(darkMaskG));
upperHistB = imhist(redChannel(brightMaskB));
lowerHistB = imhist(redChannel(darkMaskB));
% % Measure the colors
% propsR = regionprops('table', backgroundMask, redChannel, 'MeanIntensity')
% propsG = regionprops('table', backgroundMask,greenChannel, 'MeanIntensity')
% propsB = regionprops('table', backgroundMask, blueChannel, 'MeanIntensity')
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 13-Jun-2020
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.000;
channel1Max = 1.000;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 0.026;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.918;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end

14 Kommentare

@image analyst. Thank you but I don't want to separate it in different colors I want to use the same color image ... find a median value of the color image histogram split them into two. Lower and upper rectified. The code I attached does that fine but includes background.so I want a code to remove the background getting involved.
What do you mean by "color image histogram"? Do you mean the histogram of every color channel (R, G, and B) separately? Do you mean the histogram of everything, regardless of whether it came from the R, G, or B channel (which would be strange)? Color image histogram is a very ambiguous term which you have not yet defined.
And I AM using the same color image - the color image you attached. Why do you think I'm not? Exactly what is "the same color image" if it's not the same image you attached???
And I DID split the histogram(s) into two. The dark side of the histogram, and the bright side of the histogram with the median being the splitting point. So what exactly do you mean by "split the histogram into two one below the middle value and one part above the middle value" if it's not what I just described?
And what does "rectified" mean in the context of a histogram - I have no idea. To me, it means upright or aligned in the vertical direction, or to make something correct. But I don't know how that applies to the histograms. They are what they are - a distribution of intensity values. How do you "rectify" it?
Oh sorry I wasn't aware of this. Thank you so much I don't have any issues now. Thanks for prompt help .
@Image Analyst: did you try my code ? what I am trying to find using my code is correct, but it should come without including the background. I technically need to work on DKL space to create this split histogram in the LM axis. I have the conversion matrix for that.
Now I am trying to explain it like how I understood, I have to fnd a median value of the original image in histogram, then I hve to collect the light pixels lesser than median should to be in lower rectified and pixels with higher pixels than the median will be in higher rectified, I am doing this image manipulation to get an illusion. Thats why i dont what the pixels of background to be used involved in the analysis. Did I explain it bettr?
Hi , I am attaching my final image histogram and will explain you my problem, in the attachd figure (2,3,1) I dont the want the grey background i want the background to be white as the other figure background.
Image Analyst
Image Analyst am 15 Jun. 2020
Bearbeitet: Image Analyst am 15 Jun. 2020
It looks like you're operating just one the gray scale image, not the color image. I'm not really sure I understand why you're doing the operations you're doing. I showed you how to get a background mask and to just look in the face/non-background mask. I'll maybe take another look at your code tomorrow.
And I still don't understand why you call the histogram rectified. Here is what I get from dictionary.com for rectified and I can't see any definition that corresponds to what you're doing:
rectify
[ rek-tuh-fahy ]
verb (used with object), rec·ti·fied, rec·ti·fy·ing.
  1. to make, put, or set right; remedy; correct: He sent them a check to rectify his account.
  2. to put right by adjustment or calculation, as an instrument or a course at sea.
  3. Chemistry. to purify (especially a spirit or liquor) by repeated distillation.
  4. Electricity. to change (an alternating current) into a direct current.
  5. to determine the length of (a curve).
  6. Astronomy, Geography. to adjust (a globe) for the solution of any proposed problem.
@Image Analyst: sorry I couldnot respond immidiately, i spoke with my professor. He cleared my doubts, so i have to work on the image converted to DKL space, and work on x and y axis, the x axis is the LM space, and y axis is the yv space & Z is light dark pixels. So the term rectification means - lower-rectified image, half of the pixels at lighter greys than the median should be set to median grey, while the other half with lower grey-level than the median were not modified. And this is vice versa for the upper half rectified face. ANd I have to work with the foreground only. I will attach the DKL image, the masking using color thresholding will not work with DKL image.
I was completely working on a wrong concept for 3 months. could you help me with this ?
sorry for all the confusions
I don't know what the DKL space or LM space is. It looks like your attached DKL image is simply an RGB image with the background masked to zero. I don't use DKL space. Mostly I use HSV color space when I need to do color segmentation. I could give a demo to do that median assignment stuff for a gray scale image if you want that.
grayImage = imread('cameraman.tif');
subplot(2, 2, 1);
imshow(grayImage);
medianGrayLevel = median(grayImage(:))
mask = grayImage > medianGrayLevel;
subplot(2, 2, 2);
imshow(mask);
lowerRectifiedImage = grayImage; % Initialize.
lowerRectifiedImage(mask) = medianGrayLevel;
subplot(2, 2, 3);
imshow(lowerRectifiedImage);
Similar for the upper rectified image - just use < instead of > to get the mask. Then you could apply that to each color channel. Otherwise, it sounds like you have a good mentor in your professor, who hopefully knows MATLAB.
Hi@Imageanalyst: I have a doubt, could you tell if this idea looks sensible like, i have an RGB image and i want to look at the brigtness level and the rectification some pixels below and above my median value.
I have no idea. It's not something I'd personally want to do, but if it does what you need/want it to do, then fine, do it.
very bad and longly description
please express short and usefull!!!!
The description that was given was,
First it finds masks for the face and background. Then, for each color channel,
it computes the mean and median. Then it masks the image by the values above
and below the median and computes the histogram for each masked image.
And you are saying that is too long ??

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by