Reputation: 4124
I wrote a matlab function that accepts image and returns the vector of historgam. I would like to also return a vector of gray levels ranging from 0 to 255.
Here's my code:
function h = myimhist(im)
histogram=zeros(1,256);
h = imread(im);
[row,col]=size(h);
for x=1:1:row
for y=1:1:col
if h(x,y) < 1
continue;
else
t=h(x,y);
end
histogram(t)=histogram(t)+1;
end
end
subplot(1,2,1);
imshow(uint8(h));
title('Original Image');
subplot(1,2,2);
bar(histogram);
title('Histogarm of image');
end
How can I get a vector of gray level ? I think the header should be
function [h,c] = myimhist(im)
Upvotes: 0
Views: 192
Reputation: 104535
If you just want to return a 256 element vector that goes from 0 to 255, do this:
c = 0 : 255;
However, if you want c
to contain only those intensities that exist in the image, try doing the following:
c = 0 : 255;
c(histogram == 0) = [];
This removes the intensities in c
where there was no histogram count.
If I can nitpick your code, a more efficient way of computing the histogram would be to loop over every possible intensity, use logical indexing and compute the sum
. Also, I think you meant to return the histogram, and not the image. Your image is stored in h
, yet your histogram is stored in histogram
. Therefore, your function declaration should return histogram
and not h
.
As such, try something like this:
function [histogram,c] = myimhist(im)
h = imread(im);
%// Change
histogram = zeros(1, 256);
for idx = 0 : 255
histogram(idx) = sum(sum(h == idx));
end
c = 0 : 255;
% c(histogram == 0) = []; %// Depending on what you want
subplot(1,2,1);
imshow(h);
title('Original Image');
subplot(1,2,2);
bar(histogram);
title('Histogram of image');
end
You have an unnecessary casting to uint8
when you're showing the image. Your image will already be of type uint8
. This is of course assuming that your histogram calculation is only restricted to [0-255]
, which should be the case as that is what your code is assuming.
The above code will loop over every possible intensity, find those locations in your image that are equal to that intensity and sum up all occurrences. We need to use two sum
calls as calling sum
on a matrix will find the sum over every column. To find the total sum of the matrix, we would call sum
on this result.
If you want to escape using loops all together, consider using bsxfun
with two sum
calls:
function [histogram,c] = myimhist(im)
h = imread(im);
pix_counts = bsxfun(@eq, h, permute(c, [3 1 2]));
histogram = squeeze(sum(sum(pix_counts, 1), 2));
c = 0 : 255;
% c(histogram == 0) = []; %// Depending on what you want
subplot(1,2,1);
imshow(h);
title('Original Image');
subplot(1,2,2);
bar(histogram);
title('Histogram of image');
end
bsxfun
with the eq
function is used such that we create a 3D matrix of counts where each slice tells you the locations of those pixels in your image that match a particular intensity. Therefore, the first slice tells you those locations that match intensity 0, the second slice tells you those locations that match intensity 1 and so on. When we're done, all we need to do is add up the elements in each slice individually. This can be done by summing over the rows of each slice first, followed by summing over the columns last. It doesn't matter what operation you do first. You could even sum over the columns first, followed by the rows last. What will result is a single 3D vector, and we want this to be a 1D vector, which is why squeeze
is used.
Upvotes: 1