找到Canny边缘输出的最大欧氏距离并在点之间绘制一条直线

时间:2014-02-02 06:38:35

标签: matlab image-processing

我是Matlab的新手,我正在开展一个项目,我想在图像的最远两个边缘之间画一条线。 我首先使用Canny边缘检测算法来获得边缘。 在向量中存储边界。 然后,我计算了矢量中存储的所有像素中的欧几里德距离。 我遇到的问题是存储这个欧几里德距离的最大值,并在这两个像素之间绘制一条线。

这是一个示例图像:
enter image description here

代码:

im = edge(gray,'canny',0.3);
subplot(2,2,3);imshow(im);title('Canny Output');
figure
imagesc(im)
hold on

[B,L] = bwboundaries(im,'noholes');
for l=1:length(B)-1
    for m=l+1:length(B)-1
        for j=1:length(B{l})
            for k=1:length(B{m})
                a(j,k) = abs(B{l}(j,2) - B{m}(k,2));
                b(j,k) = abs(B{l}(j,1) - B{m}(k,1));
                c(j,k) = sqrt(sum(a(j,k)*a(j,k),b(j,k)*b(j,k)));
                [~,idx] = max(c(j,k));
                [x,y] = ind2sub(size(c),idx);
                p1.l = [B{l}(x,2),B{l}(x,1)];
                p2.m = [B{m}(y,2),B{m}(y,1)];
                plot([p1.l(1),p2.m(1)],[p1.l(2),p2.m(2)],'Color','g','LineWidth',2)
                clear a b c x y idx
            end
        end
    end
end

1 个答案:

答案 0 :(得分:0)

这在MATLAB中很容易实现,也很快(至少对于小图像) 如果您有二进制边缘图像,则需要将白色像素视为2D空间中的点,并查找与最大距离对应的坐标。 MATLAB可以使用带有一些额外参数的pdist2函数轻松完成此操作 看看以下代码:

img = imread( 'image.bmp');
[ y, x] = find( img);
points = [ x y];
[d,idx] = pdist2( points, points, 'euclidean', 'Largest', 1);
idx1 = idx( d==max(d));
[~,idx2] = find(d==max( d));

p={};
for i=1:length(idx1)
   p{end+1} = [ points(idx1(i),1), points(idx1(i),2), points(idx2(i),1), points(idx2(i),2)];
end

首先,您需要知道这些白色像素的位置,以便您使用find函数启动以获取坐标。然后使用pdist2,它(在这种情况下)返回行矩阵d中的最大距离和行矩阵i中的相应索引。然后,您只需要检查最大距离中最大值的位置,以获得具有最大距离的点的索引(这些点位于点p的结构中)。
如果您需要显示结果,请使用以下部分:

figure; 
imshow( img);
hold on;
for i=1:numel(p)
    line( [ p{i}(1), p{i}(3)], [p{i}(2), p{i}(4)]);
    hdl = get(gca,'Children');
    set( hdl(1),'LineWidth',2);
    set( hdl(1),'color',[1 0 0]);
end

hold off;

你会得到这个图像:
ear image with longest distance


***添加有助于仅保留唯一的点:

pp=[];
for i=1:numel(p)
    for j=i+1:numel(p)
        if prod( double( [p{i}(3:4),p{i}(1:2)] == p{j}))
            pp(end+1)=j;
        end
    end
end
j=1;
ppp={};
for i=1:numel(p)-numel(pp)
    if j<=numel(pp) && i~=pp(j)
        ppp{end+1}=p{i};
        j=j+1;
    end
end
p = ppp;