如何在二进制图像中找到一个区域周围的所有边缘像素?
该地区的孔已经填充,我想在逆时针方向找到所有边缘像素。 首先,我的解决方案是
1,在边缘
2上找到所有像素,在质心和像素之间获取x方向。
3,排序。
如何改进它? 图像和代码如下,但是当我测试代码时,发现凹形和凸起使它变得毫无用处,因为在这些角度上,有很多点。
function nAngle = create_angle_array(nPosition,centroid)
a = repmat(centroid,[size(nPosition,1),1])
nAngle = mod(angle((nPosition-a)*[1;1j]),2*pi)
end
se = strel('rect',[3,3]);
erodeImage = imerode(binaryImage,se);
erodeImageLeft = binaryImage - erodeImage;
% countPixel = sum(erodeImageLeft(:)== true);
[edgeRow_a,edgeCol_a] = find(erodeImageLeft);
if isscalar(edgeRow_a)
edgeRow = [edgeRow_a];
else
edgeRow = edgeRow_a;
end
if isscalar(edgeCol_a)
edgeCol = [edgeCol_a];
else
edgeCol = edgeCol_a;
end
disp(edgeRow);
disp(edgeCol);
angleValue = create_angle_array(cat(2,edgeRow,edgeCol),centroid);
disp(angleValue);
nPixel = cat(2,angleValue,edgeRow,edgeCol);
fprintf('size(nPixelA) is [%s]\n', int2str(size(nPixel)));
disp(nPixel)
nEdgePixel = sortrows(nPixel)
The region's hole has been filled and I want to find all edge pixels in anti-clockwise direction.
At first, my solution is
1、 find all pixel at edge
2、get x-direction between centroid and the pixel.
3、sort it.
How to improve it?
Image and code as follows, but when I test code, it found that the concave and bulge make it useless because for at these angles there are possible many points.
function nAngle = create_angle_array(nPosition,centroid)
a = repmat(centroid,[size(nPosition,1),1])
nAngle = mod(angle((nPosition-a)*[1;1j]),2*pi)
end
se = strel('rect',[3,3]);
erodeImage = imerode(binaryImage,se);
erodeImageLeft = binaryImage - erodeImage;
% countPixel = sum(erodeImageLeft(:)== true);
[edgeRow_a,edgeCol_a] = find(erodeImageLeft);
if isscalar(edgeRow_a)
edgeRow = [edgeRow_a];
else
edgeRow = edgeRow_a;
end
if isscalar(edgeCol_a)
edgeCol = [edgeCol_a];
else
edgeCol = edgeCol_a;
end
disp(edgeRow);
disp(edgeCol);
angleValue = create_angle_array(cat(2,edgeRow,edgeCol),centroid);
disp(angleValue);
nPixel = cat(2,angleValue,edgeRow,edgeCol);
fprintf('size(nPixelA) is [%s]\n', int2str(size(nPixel)));
disp(nPixel)
nEdgePixel = sortrows(nPixel)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如您所见,沿轴的像素对像素进行排序并不能保证一致的排序。一种更可靠的方法是乘坐像素并在适当的方向上找到与之相邻的下一个像素。
为此,我们需要按适当的顺序搜索相邻像素。对于逆时针订购,我们将把说明定义为:
对于当前像素,我们将开始在上一个Pixel Plus 1(Modulo 8)方向上搜索下一个像素。因此,如果先前的像素朝向6方向,我们将首先朝7个方向看,然后在0,然后是1,直到找到下一个周长像素为止。然后重复直到我们再次到达起始像素。
当我们选择启动像素时,我们没有一个“以前的”像素,因此确保我们不会错过任何像素的最简单方法是从一个极端开始(例如,最左)。然后将“上一个”像素的方向设置为您知道没有更多像素的方向,也就是说,在左侧或方向2
current_pixel
添加到code> code> code> code>
。present_direction + 1
(modulo 8)开始,搜索相邻的像素,直到找到另一个周边像素为止。break
。preesit_direction
设置为d+4 mod 8
。将current_pixel
设置为新发现的像素。这将以适当的顺序找到区域的所有外围像素,而不必明确地找到周长像素。一旦沿每个方向遍历该线路,任何“尖峰”或一个从区域伸出的像素宽线将列出两次像素,因此您的最终列表可能更长的时间比周长像素的数量更长。您也可以跳过填充孔,除非您需要将它们填充以使以后的步骤填充。
需要注意的一些事情是确保您不要在图像的范围之外查看,并使MATLAB的1个基于1的数组索引与
mod
一起使用。就个人而言,我有一个mod1
来执行一个基于一个基于的Modulo。如果这样做,只需将方向数字更改为1至8而不是0到7即可。我选择从最左边的像素开始,因为那是find(bwimg,1)
将返回。As you've seen, sorting the pixels along an axis does not guarantee a consistent ordering. A more reliable way is to take a pixel and find the next pixel adjacent to it in the proper direction.
To do this, we need to search the adjacent pixels in the proper order. For a counter-clockwise ordering, we'll define the directions as:
For the current pixel, we will start searching for the next pixel in the direction of the previous pixel plus 1 (modulo 8). So if the previous pixel was in direction 6, we'll first look in direction 7, then 0, then 1, until we find the next perimeter pixel. Then repeat until we reach the starting pixel again.
When we select the starting pixel, we don't have a "previous" pixel, so the easiest way to ensure that we don't miss any pixels is to start on one of the extremes (say, leftmost). Then set the direction of the "previous" pixel to the direction you know there are no more pixels, that is, to the left or direction 2. So,
current_pixel
and assignprevious_direction
as above. Addcurrent_pixel
toperimeter_list
.previous_direction + 1
(modulo 8), search adjacent pixels in order until you find another perimeter pixel.break
.previous_direction
tod+4 mod 8
. Set thecurrent_pixel
to the newly-found pixel.This will find all of the perimeter pixels of a region in the proper order without having to explicitly find the perimeter pixels first. Any "spikes", or one pixel wide lines, protruding from the region will list the pixels twice, once traversing the line in each direction, so your final list might be longer than the number of perimeter pixels. You can also skip filling the holes, unless you need them filled for a future step.
Some things to look out for are making sure that you don't look outside the bounds of the image, and getting MATLAB's 1-based array indexing to work with
mod
. Personally, I have amod1
function to do one-based modulo. If you do this, just change the direction numbers to be 1 to 8 instead of 0 to 7. I chose to start with the leftmost pixel because that's whatfind(bwimg, 1)
is going to return.