Histogram?

Hi, may I know why I failed to show the histogram of the image? Thanks
I=imread('1.jpg');
H=hist(I);
figure, imshow(H);
I'm new in this part, can anyone tell me which part I did wrong? thanks :)

Respuestas (4)

the cyclist
the cyclist el 9 de Mayo de 2012

0 votos

As you have coded this, H is not a grayscale image (which is what the command imshow shows.) H is simply the count of events in I.
Try just
hist(I)
to see the histogram. (I doubt that is really what you want, but try it and see.)

2 comentarios

Superb
Superb el 10 de Mayo de 2012
Thanks, but it's give me an error
??? Error using ==> times
Integers can only be combined with integers of the same class, or scalar
doubles.
Error in ==> hist at 78
xx = miny + binwidth*(0:x);
Error in ==> Try at 29
hist(I);
Walter Roberson
Walter Roberson el 10 de Mayo de 2012
hist(double(I))

Iniciar sesión para comentar.

Wayne King
Wayne King el 9 de Mayo de 2012

0 votos

Are you trying this on a RGB (3D) image? or is it uint8 gray scale?
Do you have the Image Processing Toolbox?
I = imread('pout.tif');
imhist(I)
At any rate, don't use imshow(H), just
hist(I)

4 comentarios

Superb
Superb el 10 de Mayo de 2012
Hi, I tried but then it give me this error
??? Error using ==> times
Integers can only be combined with integers of the same class, or scalar
doubles.
Error in ==> hist at 78
xx = miny + binwidth*(0:x);
Error in ==> Try at 29
hist(I);
Superb
Superb el 10 de Mayo de 2012
This is the code I used
I1b = imcrop(imread('1.jpg'),[1372 979 176 148]);
hist(I1b);
Superb
Superb el 10 de Mayo de 2012
and the original image is RGB, then i crop it, but it's still in RGB, thank :)
Superb
Superb el 10 de Mayo de 2012
Even if I tried like this, it also give same error
I1a=imread('1.jpg');
hist(I1a);

Iniciar sesión para comentar.

Geoff
Geoff el 10 de Mayo de 2012

0 votos

It's sorta weird to take the histogram of a 2D image... I don't know what it's going to tell you... Well, maybe it's not weird but anyway, you need to either convert your ints to doubles, or specify a non-double bucket range. I would use the latter:
hist(I, 0:255);
But then, as I said before, this is weird. I might be interested in only the intensities regardless of colour:
hist(I(:), 0:255);
Or I might want to preserve the colour (however many channels) and compute the histogram for each channel over the whole image:
hist( reshape(I, [], size(I,3)), 0:255 );
Don't be fooled by the coloured bars... MatLab defaults to Blue, Green, Red... But if your image channels are Red, Green, Blue this will be misleading.
[edit] Okay.. well, fine:
% Quick'n'dirty hack around default colours for RGB data
hist( fliplr(reshape(I, [], size(I,3))), 0:255 );

6 comentarios

Superb
Superb el 10 de Mayo de 2012
Hi, thanks, I found another way, but don't know why there is so many method, can I know is that the code below is correct too? TQ :)
imhist(I(:,:,1));
Geoff
Geoff el 10 de Mayo de 2012
That's only giving you the red channel of your image, but yes. The function imhist(), as Wayne King said, is from the Image Processing Toolbox.
The reason there is more than one way to express an idea in computer language is the same reason there is more than one way to express an idea in human language.
Superb
Superb el 11 de Mayo de 2012
Thanks Geoff, how can we know it's red channel or blue or green? Which argument show that? Because I thought it's RGB and now 1 is in B? Not sure, can help with this? Thanks:)
Image Analyst
Image Analyst el 11 de Mayo de 2012
do this:
[rows columns numberOfColorChannels] = size(yourImage);
if numberOfColorChannels = 3, it's an RGB image. If so,
redChannel = yourImage(:, :, 1); % Extract Red Channel.,
greenChannel = yourImage(:, :, 2); % Extract GreenChannel.,
blueChannel = yourImage(:, :, 3); % Extract BlueChannel.
if numberOfColorChannels = 1 then it's a gray scale (monochrome) image.
Superb
Superb el 11 de Mayo de 2012
Thanks Image Analyst, I got it and know it's differentiate by number 1 to 3.
if numberOfColorChannels = 1 then it's a gray scale (monochrome) image.
What do you mean by 1? Where to put this "1" if I wanted to show the hist of gray scale image? :)
Also, what is the ":" in 2 front arguments means, (:,:,1)? Can it be (1,:,:)? Why there is 3 empty spaces to fill in? What are them actually? Thanks again :)
Geoff
Geoff el 15 de Mayo de 2012
Oh, I didn't see this comment. If you just have a grayscale image, you don't need that 3rd dimension because all you have is a 2D matrix representing a single colour in an image. The 3rd dimension is used for colour images, where (for RGB at least) index 1 represents red, 2 is green, 3 is blue.
When you use the ':' operator while indexing it means "all elements in this dimension". So, yourImage(:,:,2) means "all rows and columns of the blue channel". It is a shortcut for yourImage(1:end, 1:end, 2).

Iniciar sesión para comentar.

Image Analyst
Image Analyst el 16 de Mayo de 2012

0 votos

Here, just run my demo:
% Program to read in all the RGB color images in a folder and
% display the histograms of each color channel.
% By ImageAnalyst, Feb. 2011
%----------------------------------------------------------
function RGB_Histogram_Demo()
% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
clc; % Clear command window.
clear; % Delete all variables.
close all; % Close all figure windows except those created by imtool.
imtool close all; % Close all figure windows created by imtool.
workspace; % Make sure the workspace panel is showing.
fontSize = 16;
try
% Read in standard MATLAB color demo images.
% Construct the folder name where the demo images live.
imagesFolder = fullfile(matlabroot, '\toolbox\images\imdemos');
if ~exist(imagesFolder, 'dir')
% That folder didn't exist. Ask user to specify folder.
message = sprintf('Please browse to your image folder');
button = questdlg(message, 'Specify Folder', 'OK', 'Cancel', 'OK');
drawnow; % Refresh screen to get rid of dialog box remnants.
if strcmpi(button, 'Cancel')
return;
else
imagesFolder = uigetdir();
if imagesFolder == 0
% Exit if uer clicked Cancel.
return;
end
end
end
% Read the directory to get a list of images.
filePattern = [imagesFolder, '\*.jpg'];
jpegFiles = dir(filePattern);
filePattern = [imagesFolder, '\*.tif'];
tifFiles = dir(filePattern);
filePattern = [imagesFolder, '\*.png'];
pngFiles = dir(filePattern);
filePattern = [imagesFolder, '\*.bmp'];
bmpFiles = dir(filePattern);
% Add more extensions if you need to.
imageFiles = [jpegFiles; tifFiles; pngFiles; bmpFiles];
% Bail out if there aren't any images in that folder.
numberOfImagesProcessed = 0;
numberOfImagesToProcess = length(imageFiles);
if numberOfImagesToProcess <= 0
message = sprintf('I did not find any JPG, TIF, PNG, or BMP images in the folder\n%s\nClick OK to Exit.', imagesFolder);
uiwait(msgbox(message));
return;
end
% Create a figure for our images.
figure;
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
% Preallocate arrays to hold the mean intensity values of all the images.
redChannel_Mean = zeros(numberOfImagesToProcess, 1);
greenChannel_Mean = zeros(numberOfImagesToProcess, 1);
blueChannel_Mean = zeros(numberOfImagesToProcess, 1);
% We'll be skipping monochrome and indexed images
% and just looking at true color images.
% Keep track of how many we actually look at.
numberOfImagesToProcess2 = numberOfImagesToProcess;
% Loop though all images, calculating and displaying the histograms.
% and then getting the means of the Red, green, and blue channels.
for k = 1 : numberOfImagesToProcess
% Read in this one file.
baseFileName = imageFiles(k).name;
fullFileName = fullfile(imagesFolder, baseFileName);
rgbImage = imread(fullFileName);
% Check to see that it is a color image (3 dimensions).
% Skip it if it is not true RGB color.
if ndims(rgbImage) < 3
% Skip monochrome or indexed images.
fprintf('Skipped %s. It is a grayscale or indexed image.\n', baseFileName);
% Decrement the number of images that we'll report that we need to look at.
numberOfImagesToProcess2 = numberOfImagesToProcess2 - 1;
continue;
end
% If we get to here, it's a true color image.
subplot(3, 3, 1);
imshow(rgbImage, []);
[rows columns numberOfColorBands] = size(rgbImage);
% Create a title for the image.
caption = sprintf('Original Color Image\n%s\n%d rows by %d columns by %d color channels', ...
baseFileName, rows, columns, numberOfColorBands);
% If there are underlines in the name, title() converts the next character to a subscript.
% To avoid this, replace underlines by spaces.
caption = strrep(caption, '_', ' ');
title(caption, 'FontSize', fontSize);
drawnow; % Force it to update, otherwise it waits until after the conversion to double.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Red image:
subplot(3, 3, 4);
imshow(redChannel, []); % Display the image.
% Compute mean
redChannel_Mean(k) = mean(redChannel(:));
caption = sprintf('Red Image. Mean = %6.2f', redChannel_Mean(k));
title(caption, 'FontSize', fontSize);
% Compute and display the histogram for the Red image.
pixelCountRed = PlotHistogramOfOneColorChannel(redChannel, 7, 'Histogram of Red Image', 'r');
% Green image:
subplot(3, 3, 5);
imshow(greenChannel, []); % Display the image.
% Compute mean
greenChannel_Mean(k) = mean(greenChannel(:));
caption = sprintf('Green Image. Mean = %6.2f', greenChannel_Mean(k));
title(caption, 'FontSize', fontSize);
% Compute and display the histogram for the Green image.
pixelCountGreen = PlotHistogramOfOneColorChannel(greenChannel, 8, 'Histogram of Green Image', 'g');
% Blue image:
subplot(3, 3, 6);
imshow(blueChannel, []); % Display the image.
numberOfImagesProcessed = numberOfImagesProcessed + 1;
% Compute mean
blueChannel_Mean(k) = mean(blueChannel(:));
caption = sprintf('Blue Image. Mean = %6.2f', blueChannel_Mean(k));
title(caption, 'FontSize', fontSize);
% Compute and display the histogram for the Blue image.
pixelCountBlue = PlotHistogramOfOneColorChannel(blueChannel, 9, 'Histogram of Blue Image', 'b');
% Plot all three histograms on the same plot.
subplot(3, 3, 2:3);
lineWidth = 2;
hold off;
plot(pixelCountRed, 'r', 'LineWidth', lineWidth);
hold on;
grid on;
plot(pixelCountGreen, 'g', 'LineWidth', lineWidth);
plot(pixelCountBlue, 'b', 'LineWidth', lineWidth);
title('All the Color Histograms (Superimposed)', 'FontSize', fontSize);
% Set the x axis range manually to be 0-255.
xlim([0 255]);
% Prompt user to continue, unless they're at the last image.
if k < numberOfImagesToProcess
promptMessage = sprintf('Currently displaying image #%d of a possible %d:\n%s\n\nDo you want to\nContinue processing, or\nCancel processing?',...
numberOfImagesProcessed, numberOfImagesToProcess2, baseFileName);
button = questdlg(promptMessage, 'Continue?', 'Continue', 'Cancel', 'Continue');
if strcmp(button, 'Cancel')
break;
end
end
end
% Crop off any unassigned values:
redChannel_Mean = redChannel_Mean(1:numberOfImagesProcessed);
greenChannel_Mean = greenChannel_Mean(1:numberOfImagesProcessed);
blueChannel_Mean = blueChannel_Mean(1:numberOfImagesProcessed);
% Print to command window
fprintf(1, ' Filename, Red Mean, Green Mean, Blue Mean\n');
for k = 1 : length(redChannel_Mean)
baseFileName = imageFiles(k).name;
fprintf(1, '%24s %6.2f, %6.2f, %6.2f\n', ...
baseFileName, redChannel_Mean(k), greenChannel_Mean(k), blueChannel_Mean(k));
end
if numberOfImagesProcessed == 1
caption = sprintf('Done with demo!\n\nProcessed 1 image.\nCheck out the command window for the results');
else
caption = sprintf('Done with demo!\n\nProcessed %d images.\nCheck out the command window for the results', numberOfImagesProcessed);
end
msgbox(caption);
catch ME
errorMessage = sprintf('Error in function RGB_Hist_Demo.\n.\n\nError Message:\n%s', ME.message);
uiwait(warndlg(errorMessage));
end
%----------------------------------------------------------
% Plots a bar chart of the histogram of the color channel.
function pixelCount = PlotHistogramOfOneColorChannel(oneColorChannel, subplotNumber, caption, color)
try
% Let's get its histogram into 256 bins.
[pixelCount grayLevels] = imhist(oneColorChannel, 256);
subplot(3, 3, subplotNumber);
bar(grayLevels, pixelCount, 'FaceColor', color);
title(caption, 'FontSize', 16);
grid on;
% Set the x axis range manually to be 0-255.
xlim([0 255]);
catch ME
errorMessage = sprintf('Error in function PlotHistogramOfOneColorChannel.\n.\n\nError Message:\n%s', ME.message);
uiwait(warndlg(errorMessage));
end
return;

10 comentarios

deniel munthe
deniel munthe el 16 de Mayo de 2012
what parts are taking pictures?
Image Analyst
Image Analyst el 16 de Mayo de 2012
You can step through it with the debugger to see what each line is doing. The line that "takes" the picture (actually reads it off the hard drive) is rgbImage = imread(fullFileName);
Maria
Maria el 29 de Jul. de 2012
Editada: Maria el 29 de Jul. de 2012
@ Image Analyst I have a question on your code I have debugged your code I want to ask that the histograms that it generates are accumulated result of all images of red green and blue channels or does it produce the histograms for a single image if it does for single image how can we accumulate red, green and blue channels of more than 1 images in 3 histograms. I mean red channels of all images in 1 histogram and so on. Further more I also want a code for calculating Gaussian Distribution for each of the histogram to provide mean pixel intensity.Please help me in doing so.Thanks and Regards.
Image Analyst
Image Analyst el 29 de Jul. de 2012
The histograms are for each individual image. If you want, you can accumulate the pixel counts into an array, though you might want to normalize by the number of pixels in the image so that a huge image doesn't swamp the histogram from a small image. For calculating it's Gaussian distribution, what's wrong with just calculating the mean and standard deviation? If you do that from the histogram rather than from the image pixel values, be sure you use the correct formula. You obviously just can take the mean of the pixel counts
meanGLfromHist = sum( graylevels .* pixelCounts) / sum(pixelCounts);
meanGLfromImage = mean2(redChannel);
Those should be close though maybe not exact if you have less histogram bins than gray levels in your image. ALternatively you can use a least squares fit, like the demo below, though it's not the best way to do it.
% Demo to fit a histogram to a Gaussian
% Uses a linear least squares fit to the log of the counts.
% Fit is only approximate. The amplitude seems to be a bit low.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSizeTitle = 20;
fontSizeLabel = 13;
% Make up some sample Gaussian distributed data.
numberOfSamples = 5000;
y = 2*randn(numberOfSamples,1) + 10;
[counts bins] = hist(y(:), 100);
% Plot it.
subplot(3,1,1);
bar(bins, counts, 'BarWidth', 1);
ylabel('Counts', 'FontSize', fontSizeLabel);
xlabel('Bin Value', 'FontSize', fontSizeLabel);
title('Random Sample Data', 'FontSize', fontSizeTitle);
grid on;
xLimits = xlim();
yLimits = ylim();
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]); % Maximize figure.
% Do a least squares fit of the histogram to a Gaussian.
% Assume y = A*exp(-(x-mu)^2/sigma^2)
% Take log of both sides
% log(y) = (-1/sigma^2)*x^2 + (2*mu/sigma^2)*x + (log(A)-mu^2/sigma^2)
% Which is the same as
% lny = a1*x^2 + a2*x + a3
% Now do the least squares fit.
% Don't include and zero bins in the data because log doesn't like 0.
nonZeroBins = counts > 0;
lny = log(counts(nonZeroBins));
coeffs = polyfit(bins(nonZeroBins), lny, 2)
% Find the Gaussian parameters from the least squares parameters.
sigma = sqrt(-1/coeffs(1))
mu = coeffs(2) * sigma^2/2
amplitude = exp(coeffs(3) + mu^2/sigma^2)
% Now we have all 3 Gaussian parameters,
% so reconstruct the data from the Gaussian model.
xModeled = linspace(bins(1), bins(end), 100);
yModeled = amplitude * exp(-(xModeled - mu).^2 / sigma^2);
% Plot it.
subplot(3,1,2);
plot(xModeled, yModeled, 'r-', 'LineWidth', 2);
ylabel('Counts', 'FontSize', fontSizeLabel);
xlabel('Bin Value', 'FontSize', fontSizeLabel);
title('Modeled Data', 'FontSize', fontSizeTitle);
grid on;
% Set up the x axis the same
xlim(xLimits);
ylim(yLimits);
% Now plot both on the same plot
subplot(3,1,3);
bar(bins, counts, 'BarWidth', 1);
hold on;
plot(xModeled, yModeled, 'r-', 'LineWidth', 2);
ylabel('Counts', 'FontSize', fontSizeLabel);
xlabel('Bin Value', 'FontSize', fontSizeLabel);
title('Both Actual and Modeled Data', 'FontSize', fontSizeTitle);
grid on;
% Set up the x axis the same
xlim(xLimits);
ylim(yLimits);
Maria
Maria el 30 de Jul. de 2012
Editada: Maria el 30 de Jul. de 2012
ok for creating an array is it fine if do redChannel=[redChannel ; redC] where redC is the red channel of current kth image and redChannel is an accumulated of all previous images and sending this redChannel to the function PlotHistogramOfOneColorChannel(....),is it ok? and what do you mean by normalize by number of pixels? Also I didn't get your explanation about Gaussian Distribution, Could you please explain it again but in layman terms.Thanks
Image Analyst
Image Analyst el 30 de Jul. de 2012
The histogram is the number of pixels with certain gray levels. What do you plan on doing if you look at the histogram of one image that is 240 x 320 pixels, and another image that is 2672x4008 pixels? The latter one has WAY more pixels than the first one. When you accumulate histograms, how do you want to handle that? If you just simply add them without normalizing, the small image histogram will barely register at all - it won't affect your cumulative overall average histogram because there are so few pixels. So maybe you want to normalize the counts so that it's a percentage of the total number of pixels rather than the actual number of pixels.
Maybe I didn't understand what you mean by getting the Gaussian Distribution. If my demo doesn't do that, then what do you mean? Why not just take the mean and stddev of the actual pixel values? The mean and stddev define a Gaussian equation. What more do you need?
Maria
Maria el 30 de Jul. de 2012
Editada: Maria el 30 de Jul. de 2012
Oh actually images are of same size.
Probably I am confused about my problem ok let me give you the reference to my problem
On 2nd page of this research paper there is a title 'Reliable color segmentation' and If you read the first paragraph you would understand what I am trying to do, though I have to do things which are mentioned further in same paragraph but I am stuck at this level.Please help me out.Regards
Maria
Maria el 30 de Jul. de 2012
So for this problem I am taking video frames, saving them into the directory and them grabbing them 1 by 1 again and applying your code to create histogram.
Ryan
Ryan el 30 de Jul. de 2012
Editada: Ryan el 30 de Jul. de 2012
I found this document through Google about Gaussians that may help you (it's a direct link to a word document): www.cs.moravian.edu/~csalter/GaussianDist_3.1.doc
I believe what they (Microsoft) are doing is along the lines of what Image Analyst suggests in using the mean and std dev of the histogram, but they are most likely normalizing it first to have an area of 1.
Maria
Maria el 30 de Jul. de 2012
I think your demo works fine but could you please see my problem which I mentioned above and verify the solution I am trying. If there is something wrong with the way i am trying to do could please rectify it.If you want me to send my code I'll post it too.Thanks a lot and sorry for bothering you.

Iniciar sesión para comentar.

Etiquetas

Preguntada:

el 9 de Mayo de 2012

Community Treasure Hunt

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

Start Hunting!

Translated by