【发布时间】:2011-01-15 13:47:00
【问题描述】:
您好,我有一张如上图所示的图片。我是否可以检测十字的中心点并使用 Matlab 输出结果?谢谢。
【问题讨论】:
标签: matlab image-processing computer-vision
您好,我有一张如上图所示的图片。我是否可以检测十字的中心点并使用 Matlab 输出结果?谢谢。
【问题讨论】:
标签: matlab image-processing computer-vision
刚刚遇到了同样的问题,找到了其他的解决方法,想分享一下:
假设图像文件名为pict1.jpg。
1.读取输入图像,裁剪相关部分并转换为灰度:
origI = imread('pict1.jpg'); %Read input image
I = origI(32:304, 83:532, :); %Crop relevant part
I = im2double(rgb2gray(I)); %Covert to Grayscale and to double (set pixel range [0, 1]).
2.用鲁棒的方法将图像转换为二值图像:
%Subtract from each pixel the median of its 21x21 neighbors
%Emphasize pixels that are deviated from surrounding neighbors
medD = abs(I - medfilt2(I, [21, 21], 'symmetric'));
%Set threshold to 5 sigma of medD
thresh = std2(medD(:))*5;
%Convert image to binary image using above threshold
BW = im2bw(medD, thresh);
黑白图片:
3.现在我建议两种寻找中心的方法:
两种解决方案都返回亚像素结果。
3.1.Find cross center using regionprops(寻找质心):
%Find centroid of the cross (centroid of the cluster)
s = regionprops(BW, 'centroid');
centroids = cat(1, s.Centroid);
figure;imshow(BW);
hold on, plot(centroids(:,1), centroids(:,2), 'b*', 'MarkerSize', 15), hold off
%Display cross center in original image
figure;imshow(origI), hold on, plot(82+centroids(:,1), 31+centroids(:,2), 'b*', 'MarkerSize', 15), hold off
质心结果(BW 图像):
质心结果(原图):
3.2 通过两条线的交点找到交叉中心(使用Hough transform):
%Create the Hough transform using the binary image.
[H,T,R] = hough(BW);
%ind peaks in the Hough transform of the image.
P = houghpeaks(H,2,'threshold',ceil(0.3*max(H(:))));
x = T(P(:,2)); y = R(P(:,1));
%Find lines and plot them.
lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);
figure, imshow(BW), hold on
L = cell(1, length(lines));
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
%http://robotics.stanford.edu/~birch/projective/node4.html
%Find lines in homogeneous coordinates (using cross product):
L{k} = cross([xy(1,1); xy(1,2); 1], [xy(2,1); xy(2,2); 1]);
end
%https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
%Lines intersection in homogeneous coordinates (using cross product):
p = cross(L{1}, L{2});
%Convert from homogeneous coordinate to euclidean coordinate (divide by last element).
p = p./p(end);
plot(p(1), p(2), 'x', 'LineWidth', 1, 'Color', 'white', 'MarkerSize', 15)
霍夫变换结果:
【讨论】:
这个怎么样;
a) 转换为二进制只是为了让算法更快。
b) 对结果数组执行查找
c) 选择具有最低/最高行/列索引的元素(然后您将有四个点可供选择
d) 现在继续搜索邻居
e) 沿着相邻点前进,您将到达一个可能存在三个邻居的点。那是您的交叉点
【讨论】:
我只是喜欢这些关于如何在不首先定义该东西是什么的情况下找到东西的讨论!但是,如果我不得不猜测,我会建议原始灰度图像的center of mass。
【讨论】:
我认为有一种更简单的方法可以解决这个问题。形成十字准线的线等长。因此它在所有方向上都是对称的。因此,如果我们进行简单的水平和垂直线扫描,以找到形成十字准线的线的末端。这些值的中位数将给出中心的 x 和 y 坐标。简单的几何图形。
【讨论】:
给你。我假设您拥有图像工具箱,因为如果您没有,那么您可能不应该尝试做这种事情。但是,我相信所有这些功能都可以通过卷积来实现。我在你上面展示的图像上做了这个过程,得到了点 (139,286),其中 138 是行,268 是列。
1.将图像转换为二值图像:
bw = bw2im(img, .25);
其中 img 是原始图像。根据图像,您可能需要调整第二个参数(范围从 0 到 1),以便只得到十字。不要担心十字架没有完全连接,因为我们会在下一步中解决这个问题。
2.扩大图像以连接部分。我不得不这样做两次,因为我必须将二进制图像转换的阈值设置得如此之低(图像的某些部分非常暗)。膨胀本质上只是在现有白色像素周围添加像素(我还将在将二进制图像发送到 bwmorph 时反转二进制图像,因为这些操作是针对值为 1 的白色像素进行的)。
bw2 = bwmorph(~bw, 'dilate', 2);
最后一个参数表示做扩张操作的次数。
3.将图像缩小到一个点。
bw3 = bwmorph(bw2, 'shrink',Inf);
同样,最后一个参数表示执行该操作的次数。在这种情况下,我输入了 Inf,它会缩小直到只有一个像素是白色的(也就是 1)。
4.找到仍为 1 的像素。
[i,j] = find(bw3);
这里,i 是行,j 是 bw3 中像素的列,使得 bw3(i,j) 等于 1。所有其他像素在 bw3 中应为 0。
可能还有其他方法可以用 bwmorph 做到这一点,但我认为这种方法效果很好。您可能还需要根据图片进行调整。如果需要,我可以包含每个步骤的图像。
【讨论】:
我将从使用灰度图像映射开始。最暗的点在十字架上,因此区分最高值是一个起点。区分后,将所有较低的点设置为白色,其余的保持不变。这将使十字架上的点和图像中的点之间的对比度最大化。接下来是提出一个过滤器,用于确定具有最高平均值的位置。我会用 NxM 数组遍历整个图像,并在中心点取平均值。创建这些均值的新数组,您应该在交叉点处具有最高均值。我很想知道其他人会如何尝试这个!
【讨论】: