【问题标题】:Detecting center point of cross using Matlab使用Matlab检测十字中心点
【发布时间】:2011-01-15 13:47:00
【问题描述】:

您好,我有一张如上图所示的图片。我是否可以检测十字的中心点并使用 Matlab 输出结果?谢谢。

【问题讨论】:

    标签: matlab image-processing computer-vision


    【解决方案1】:

    刚刚遇到了同样的问题,找到了其他的解决方法,想分享一下:

    假设图像文件名为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.现在我建议两种寻找中心的方法:

    • Find find centroid(找到白色星团的质心)
    • 用霍夫变换求两条直线,并求交点

    两种解决方案都返回亚像素结果。

    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)
    

    霍夫变换结果:

    【讨论】:

      【解决方案2】:

      这个怎么样;

      a) 转换为二进制只是为了让算法更快。

      b) 对结果数组执行查找

      c) 选择具有最低/最高行/列索引的元素(然后您将有四个点可供选择

      d) 现在继续搜索邻居

      • 有一个全局搜索条件,如果搜索没有导致多次迭代,则选择的点为假,并选择另一个极值点

      e) 沿着相邻点前进,您将到达一个可能存在三个邻居的点。那是您的交叉点

      【讨论】:

        【解决方案3】:

        我只是喜欢这些关于如何在不首先定义该东西是什么的情况下找到东西的讨论!但是,如果我不得不猜测,我会建议原始灰度图像的center of mass

        【讨论】:

        • 我认为 OP 的意思是十字架的两条线相交的点。
        【解决方案4】:

        我认为有一种更简单的方法可以解决这个问题。形成十字准线的线等长。因此它在所有方向上都是对称的。因此,如果我们进行简单的水平和垂直线扫描,以找到形成十字准线的线的末端。这些值的中位数将给出中心的 x 和 y 坐标。简单的几何图形。

        【讨论】:

        • 我认为这是一个好主意,但您需要先将其转换为二进制映射。转换后,您可以逐行遍历整个图像。只需跟踪其中包含 1 的最远的上、下、左和右点。然后在最后找到四个点的平均值。好主意。
        【解决方案5】:

        给你。我假设您拥有图像工具箱,因为如果您没有,那么您可能不应该尝试做这种事情。但是,我相信所有这些功能都可以通过卷积来实现。我在你上面展示的图像上做了这个过程,得到了点 (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 做到这一点,但我认为这种方法效果很好。您可能还需要根据图片进行调整。如果需要,我可以包含每个步骤的图像。

        【讨论】:

        • 如果您对确定中心的亚像素精度感兴趣,这只是第一步。使用确定的中心,您可以收集两条线的 x 和 y。现在,您可以使用 polyfit 计算每条线的斜率和交点。由此,您可以计算交点。
        • 有时我得到的不仅仅是一个像素。有没有办法减少数字,直到我得到 1 个结果?谢谢。
        • @Veronica 您是剩余两个像素还是剩余两个以上像素?
        • 有时我得到 2 有时是 3。谢谢。
        • @Veronica 是相邻的 2 或 3 个像素吗?
        【解决方案6】:

        我将从使用灰度图像映射开始。最暗的点在十字架上,因此区分最高值是一个起点。区分后,将所有较低的点设置为白色,其余的保持不变。这将使十字架上的点和图像中的点之间的对比度最大化。接下来是提出一个过滤器,用于确定具有最高平均值的位置。我会用 NxM 数组遍历整个图像,并在中心点取平均值。创建这些均值的新数组,您应该在交叉点处具有最高均值。我很想知道其他人会如何尝试这个!

        【讨论】:

        • NxM 数组步进...你指的是结构元素的卷积吗?
        • 技术上是的。在存在极值地标的情况下,这只是一种用于特征提取的快速编码方法,在这种情况下是 X 的黑色。几年前我遇到了这个问题。在验证 CT 扫描的定位时,将金属球放置在某些点上,这会导致重建图像中出现条纹。定位这些位置就足以找到极值。因此,可以使用圆形代替矩形来确定图像的位置和比例。
        猜你喜欢
        • 1970-01-01
        • 2013-01-14
        • 2010-09-21
        • 2015-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        • 2011-09-01
        相关资源
        最近更新 更多