在MATLAB中查找图像的边缘和拐角值 [英] Finding edge and corner values of an image in MATLAB

查看:213
本文介绍了在MATLAB中查找图像的边缘和拐角值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在追踪图像的轮廓并将其绘制到 DXF 文件中。我想使用 bwboundaries 函数来查找图像边缘的坐标,使用 cornermetric找到角坐标函数,然后删除任何不是角落的边坐标。

I am tracing the outline of an image and plotting this to a DXF file. I would like to use the bwboundaries function to find the coordinates of the edges of the image, find the corner coordinates using the cornermetric function and then remove any edge coordinates that are not a corner.

我需要做的重要事情是保持角元素的顺序从 bwboundaries ,以便该部分正确追踪。我所拥有的DXF函数,从坐标绘制,在彼此相邻的坐标之间绘制线条,因此线条必须围绕该部分而不是直接在角点之间绘制。

The important thing I need to be able to do is keep the order of the corner elements obtained from bwboundaries, so that the section traces properly. The DXF function I have, that draws from the coordinates, draws lines between coordinates that are next to each other, so the line has to be drawn "around" the section rather than straight between the corner points.

我这样做的原因是因为这种方式获得的坐标较少,因此修改DXF文件更容易(因为操作点数较少)。

The reason I am doing this is because there are less coordinates obtained this way, so it is easier to amend the DXF file (as there are less points to manipulate).

到目前为止我的代码是:

The code I have so far is:

%# Shape to be traced
bw = zeros(200);

bw(20:40,20:180) = 1;
bw(20:180,90:110) = 1;
bw(140:180,20:185) = 1;

%# Boundary finding section
[Boundary] = bwboundaries(bw); %Traces the boundary of each section.

figure, imshow(bw); hold on;
colors=['b' 'g' 'r' 'c' 'm' 'y'];

for k = 1:length(Boundary)
   perim = Boundary{k}; %Obtains perimeter coordinates (as a 2D matrix) from the cell array.
   cidx = mod(k,length(colors))+1;% Obtains colours for the plot
   plot(perim(:,2), perim(:,1),...
          colors(cidx),'LineWidth',2);
end

Coordmat = cell2mat(Boundary) %Converts the traced regions to a matrix.

X = Coordmat(:,1)
Y = Coordmat(:,2) % This gives the edge coordinates in matrix form.

%% Corner finding section (from Jonas' answer to a previous question.

%# Get corners
cornerProbability = cornermetric(bw);

cornerIdx = find(cornerProbability==max(cornerProbability(:)));

%# Label the image. bwlabel puts 1 for the first feature, 2 for the second, etc.
%# Since concave corners are placed just outside the feature, grow the features.
%# A little before labeling
bw2 = imdilate(bw,ones(3));
labeledImage = bwlabel(bw2);

%# Read the feature number associated with the corner.
cornerLabels = labeledImage(cornerIdx);

%# Find all corners that are associated with feature 1.
corners_1 = cornerIdx(cornerLabels==1)

[Xcorners, Ycorners] = ind2sub(200,corners_1) % Convert subscripts

我所拥有的代码是,给最后一个矩阵 Xfin x坐标(位于边缘和拐角处。

The code I have is, to give a matrix, Xfin, for the final x coordinates (which are on the edge AND at a corner.

Xfin = zeros(length(X),1)

for i = Xcorners
    XFin(i) = Xcorners
    if i~= Xcorners
        XFin(i) = []
    end
end

但是,这不能正常工作,因为解决方案中的值按顺序排序,并且每个值中只有一个保留。正如我所说,我希望角元素的顺序与从bwboundaries获得的顺序相同,以允许图像正确跟踪。

However, this does not work correctly, because the values in the solution are sorted into order, and only one of each value remains. As I said, I would like the corner elements to be in the same order as obtained from bwboundaries, to allow the image to trace properly.

(此问题链接到两个我在这里问过的其他问题。)

(This problem links to two other questions I've asked on here.)

推荐答案

这是一段做你想做的事情的代码。对于每个角,它找到最近的边界像素,并记住坐标的索引。

Here's a piece of code that does what you want to do. For every corner, it finds the closest boundary pixel, and remembers the index of the coordinate.

为此,你必须将边界作为4连接边界(即写 Boundary = bwboundaries(bw,4); 。如果由于某种原因不能使用4连接边界,则角点提取会变得有点复杂,因为在这种情况下,凹角不是边界的一部分(请注意,8个连接的边界,当你看到你的绿线时,内角是'圆的'。

For this to work, you have to get the boundary as 4-connected boundary (i.e. write Boundary = bwboundaries(bw,4);. If you cannot use 4-connected boundaries for some reason, the corner extraction becomes a bit more complicated, since in that case, concave corners are not part of the boundary (note that with 8-connected boundaries, the inside corners are 'round' when you look at your green line).

编辑

以下是适用于我的完整代码

Here's the full code that works for me

%# Shape to be traced
% bw = zeros(200);
% 
% bw(20:40,20:180) = 1;
% bw(20:180,90:110) = 1;
% bw(140:180,20:185) = 1;

%# alternative shape
bw = zeros(100); 
bw(40:80,40:80) = 1;


%# Boundary Finding Section
[Boundary] = bwboundaries(bw,4); %Traces the boundary of each section

figure, imshow(bw); hold on;
colors=['b' 'g' 'r' 'c' 'm' 'y'];

for k=1:length(Boundary)
 perim = Boundary{k}; %Obtains perimeter coordinates (as a 2D matrix) from the cell array
 cidx = mod(k,length(colors))+1;% Obtains colours for the plot
 plot(perim(:,2), perim(:,1),...
        colors(cidx),'LineWidth',2);

end

Coordmat = cell2mat(Boundary) %Converts the traced regions to a matrix

X = Coordmat(:,1)
Y = Coordmat(:,2) % This gives the edge coordinates in matrix form



%% Corner Finding Section (from Jonas' answer to a previous question
%# get corners
cornerProbability = cornermetric(bw);


cornerIdx = find(cornerProbability==max(cornerProbability(:)));

%# Label the image. bwlabel puts 1 for the first feature, 2 for the second, etc.
%# Since concave corners are placed just outside the feature, grow the features 
%# a little before labeling
bw2 = imdilate(bw,ones(3));
labeledImage = bwlabel(bw2);

%# read the feature number associated with the corner
cornerLabels = labeledImage(cornerIdx);

%# find all corners that are associated with feature 1
corners_1 = cornerIdx(cornerLabels==1)

[Xcorners, Ycorners] = ind2sub(size(bw),corners_1) % Convert subscripts

%% Here comes the new part

%# count corners
nCorners = length(Xcorners);
%# corner2boundaryIdx will contain the index of the boundary pixel
%# corresponding to a given corner
corner2boundaryIdx = zeros(nCorners,1);

%# remove last entry of Coordmat, because the first and the last pixel are
%# repeated
Coordmat(end,:) = [];

%# loop since we need to tread convex and concave corners differently
for i = 1:nCorners
    %# find distance of corner to boundary
    dist = sqrt((Coordmat(:,1)-Xcorners(i)).^2 + (Coordmat(:,2)-Ycorners(i)).^2);
    %# find index of closest boundary pixel. Use find
    %# instead of 2nd output of min, because we need to know how
    %# many closest indices there are in order to distinguish
    %# concave and convex corners. Convex corners are directly
    %# on the boundary, thus there is one minimum distance (0).
    %# Concave corners are just outside the boundary, thus, there
    %# are two minimum distances (1)
    minDistIdx = find(dist == min(dist));

    %# count how many minimum distances we have
    switch length(minDistIdx)
        case 1
            %# convex corners. Everything is simple
            corner2boundaryIdx(i) = minDistIdx;
        case 2
            %# concave corners. Take the index right in the middle. Note
            %# for this to work, you need to have 4-connected boundaries,
            %# otherwise, the concave corner is not part of the boundary
            %# becasue the boundary jumps along the diagonal. 
            %# If you have to use 8-connected boundaries, the 'good'
            %# difference is 1, and you need to calculate the coordinate of
            %# the concave corner from the "corner" and the two adjacent 
            %# boundary pixels.
            if diff(minDistIdx) == 2
            corner2boundaryIdx(i) = mean(minDistIdx);
            else
                error('boundary starts/stops at concave corner - case not handled yet')
            end
        otherwise
            error('%i minDist found for corner # %i',length(minDistIdx),i)
    end
end

%# All that is left to do is read the boundary pixel coordinates in the 
%# right order
corner2boundaryIdx = sort(corner2boundaryIdx);
orderedCorners = Coordmat(corner2boundaryIdx,:);

%# plot corner numbers for confirmation
hold on
for i = 1:nCorners
    text(orderedCorners(i,2),orderedCorners(i,1),num2str(i),'Color','r')
end

这篇关于在MATLAB中查找图像的边缘和拐角值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆