计算图像中每行的像素数

时间:2014-09-04 03:55:19

标签: image matlab image-processing line

对于项目,我需要找到图像中线条之间的点距离。我想到的方法是将图像转换为二进制图像,并计算每行中黑色背景的白色像素数。我附上了我的代码,只要线条完全笔直,它就能正常工作。

顺便说一下,这是一个将要分析的样本图像。我计划变成二进制/运行线检测算法,以找到线中两个绿色条带的边界,因为它们之间的距离是关注的。

(http://i.imgur.com/Q5Ef0eJ.jpg)

im = imread('http://i.imgur.com/lc8ESac.png'); %// Read image
imBinary = double(im2bw(im)); %// Just in case - Convert to binary, 
                              %// then make double for sum
histogram = sum(imBinary,2); %// Compute row-wise histograms
stem(1:size(imBinary,1), histogram); %// Plot this histogram
xlabel('Row number');
ylabel('White pixel count');
grid;
diffs = diff([0; histogram]);
threshold = 100; %// Define threshold here 
rows = find(diffs >= threshold);

此代码返回直方图,峰之间的距离表示线之间的间距。

为了解决弯曲线的问题,我正在考虑使用一种分析图像列(例如100像素)的方法,然后循环直到它遍历整个图像(0-100列,然后是101-200)直到图像的宽度。)

我的伪代码在这里:

for (loop through rows) 
    for (loop for coloumns) 
        count pixels at p(row, col) 
    end loop for columns 
    column counter = column counter - 1
    if column counter <= 0 then save the number of pixels counter and set column counter = 10
end row loop 

然而,作为一名ChemE专业,编码不是我的强项,我在循环方面非常困难。

我只是希望能够将上述代码合并到这个循环中,这样它就可以将弯曲的线条分成许多伪直线,以便能够计算出“平均”或一系列离散线间距。

非常感谢!

2 个答案:

答案 0 :(得分:0)

我的生活中从未运行过Matlab,所以我无法告诉你Matlab中的确切代码行......但是我可以告诉你如何删除非水平行。

您只需将图像与适当的水平方向内核进行卷积,因此根据您的需要,内核将是:

0       0       0
0.33    0.33    0.33
0       0       0

因此,输出图像中的每个像素基本上都成为其自身及其左右邻居的平均值。

开始图片

enter image description here

ImageMagick命令:

convert lines.png -convolve "0,0,0,0.33,0.33,0.33,0,0,0" -threshold 99.99% horiz.jpg

结束图片

enter image description here

顺便说一下,你的线实际上是5个像素的厚度,所以你可能需要运行一个更大的内核去除它们,比如9x9,其中所有系数都是零,除了中间(第5)行,它们都是1/9 (即0.111)。

我使用ImageMagick通过此命令将图像调整为一个像素宽的垂直列:

convert lines.png -resize 1x844! -threshold 50% txt:

,它给出了以下输出,显示您的白线位于顶部偏移149,218,476行。

...
0,144: (0,0,0)  #000000  black
0,145: (0,0,0)  #000000  black
0,146: (0,0,0)  #000000  black
0,147: (255,255,255)  #FFFFFF  white
0,148: (255,255,255)  #FFFFFF  white
0,149: (255,255,255)  #FFFFFF  white    <- Centre of your line
0,150: (255,255,255)  #FFFFFF  white
0,151: (255,255,255)  #FFFFFF  white
0,152: (0,0,0)  #000000  black
0,153: (0,0,0)  #000000  black
0,154: (0,0,0)  #000000  black
...
0,213: (0,0,0)  #000000  black
0,214: (0,0,0)  #000000  black
0,215: (0,0,0)  #000000  black
0,216: (255,255,255)  #FFFFFF  white
0,217: (255,255,255)  #FFFFFF  white
0,218: (255,255,255)  #FFFFFF  white    <- Centre of your line
0,219: (255,255,255)  #FFFFFF  white
0,220: (255,255,255)  #FFFFFF  white
0,221: (0,0,0)  #000000  black
0,222: (0,0,0)  #000000  black
0,223: (0,0,0)  #000000  black
...
0,471: (0,0,0)  #000000  black
0,472: (0,0,0)  #000000  black
0,473: (0,0,0)  #000000  black
0,474: (255,255,255)  #FFFFFF  white
0,475: (255,255,255)  #FFFFFF  white
0,476: (255,255,255)  #FFFFFF  white    <- Centre of your line
0,477: (255,255,255)  #FFFFFF  white
0,478: (255,255,255)  #FFFFFF  white
0,479: (0,0,0)  #000000  black
0,480: (0,0,0)  #000000  black
0,481: (0,0,0)  #000000  black
...

这是&#34; squidged&#34;图像 - 在红色背景上,所以你可以看到它:

enter image description here

答案 1 :(得分:0)

卷入你的直方图:

h_accu = conv(histogram,(1:10)/10);
figure;plot(h_accu)

此处10用作窗口大小,应根据线条的直线度进行调整。

顺便说一句,查找这些行的更常用方法是hough transform