Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
回复
 
主题工具 显示模式
旧 2019-12-10, 20:30   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 在MATLAB中查找图像的边角值

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

我需要做的重要事情是保持从bwboundaries获得的corner元素的顺序,以便该部分正确跟踪。我具有的DXF函数从坐标绘制,在彼此相邻的坐标之间绘制直线,因此必须在截面“周围”绘制直线,而不是在拐角点之间笔直。

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

到目前为止,我的代码是:

%# 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坐标(在边缘AND在一个角。

Xfin = zeros(length(X),1) for i = Xcorners XFin(i) = Xcorners if i~= Xcorners XFin(i) = [] end end 但是,这不能正常工作,因为解决方案中的值是按顺序排序的,并且每个值仅保留一个。如我所说,我希望角落元素的顺序与从bwboundaries获得的顺序相同,以使图像能够正确跟踪。

(此问题与我在此处提出的另外两个问题有关。)



回答:

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

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

编辑

这是对我有用的完整代码

%# 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

更多&回答...
poster 当前离线   回复时引用此帖
回复


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 23:19


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.