我写了一个matlab函数,它接受图像并返回historgam的向量。我还想返回一个灰度级为0到255的矢量。
这是我的代码:
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
如何获得灰度矢量? 我认为标题应该是
function [h,c] = myimhist(im)
答案 0 :(得分:1)
如果您只想返回一个从0到255的256个元素向量,请执行以下操作:
c = 0 : 255;
但是,如果您希望c
仅包含图像中存在的强度,请尝试执行以下操作:
c = 0 : 255;
c(histogram == 0) = [];
这消除了c
中没有直方图计数的强度。
如果我能挑选你的代码,更有效的计算直方图的方法是循环遍历每个可能的强度,使用逻辑索引并计算sum
。另外,我认为你的意思是返回直方图,而不是图像。您的图片存储在h
中,但您的直方图存储在histogram
中。因此,您的函数声明应该返回histogram
而不是h
。
因此,尝试这样的事情:
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
当您显示图像时,您需要对uint8
进行不必要的投射。您的图片已经是uint8
类型。这当然假设您的直方图计算仅限于[0-255]
,这应该是您的代码所假设的情况。
上面的代码将循环遍历每个可能的强度,找到图像中与该强度相等的那些位置并总结所有出现的位置。我们需要使用两个sum
调用,因为在矩阵上调用sum
会在每列上找到总和。要查找矩阵的总和,我们会在此结果上调用sum
。
如果您想要一起使用循环,请考虑使用bsxfun
进行两次sum
来电:
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
使用带有eq
函数的 bsxfun
,以便我们创建 3D矩阵计数,其中每个切片告诉您这些位置图像中与特定强度匹配的像素。因此,第一个切片会告诉您那些匹配强度为0的位置,第二个切片会告诉您那些匹配强度1的位置,依此类推。当我们完成后,我们需要做的就是单独添加每个切片中的元素。这可以通过首先对每个切片的行求和,然后对最后的列求和来完成。你先做什么操作并不重要。您甚至可以先对列进行求和,然后是最后一行。结果是单个3D矢量,我们希望它是一维矢量,这就是使用squeeze
的原因。