如何在二进制图像中找到一个区域周围的所有边缘像素?

发布于 2025-01-25 20:46:21 字数 1136 浏览 2 评论 0原文

该地区的孔已经填充,我想在逆时针方向找到所有边缘像素。 首先,我的解决方案是

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.

enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橪书 2025-02-01 20:46:21

如您所见,沿轴的像素对像素进行排序并不能保证一致的排序。一种更可靠的方法是乘坐像素并在适当的方向上找到与之相邻的下一个像素。

为此,我们需要按适当的顺序搜索相邻像素。对于逆时针订购,我们将把说明定义为:

    1  0  7
     \ | /
      \|/
    2--+--6
      /|\
     / | \
    3  4  5

对于当前像素,我们将开始在上一个Pixel Plus 1(Modulo 8)方向上搜索下一个像素。因此,如果先前的像素朝向6方向,我们将首先朝7个方向看,然后在0,然后是1,直到找到下一个周长像素为止。然后重复直到我们再次到达起始像素。

当我们选择启动像素时,我们没有一个“以前的”像素,因此确保我们不会错过任何像素的最简单方法是从一个极端开始(例如,最左)。然后将“上一个”像素的方向设置为您知道没有更多像素的方向,也就是说,在左侧或方向2

  1. 。代码>如上。将current_pixel添加到code> code> code> code>
  2. 重复:
  3.     从present_direction + 1(modulo 8)开始,搜索相邻的像素,直到找到另一个周边像素为止。
  4. 如果新像素等于启动像素,则break
  5.     nbsp;添加新的周边像素。如果在IS D中找到新像素的方向,则将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:

    1  0  7
     \ | /
      \|/
    2--+--6
      /|\
     / | \
    3  4  5

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,

  1. Set current_pixel and assign previous_direction as above. Add current_pixel to perimeter_list.
  2. Repeat:
  3.     Starting at previous_direction + 1 (modulo 8), search adjacent pixels in order until you find another perimeter pixel.
  4.     If the new pixel is equal to the starting pixel, break.
  5.     Add new perimeter pixel to list. If the direction the new pixel was found in is d, set previous_direction to d+4 mod 8. Set the current_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 a mod1 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 what find(bwimg, 1) is going to return.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文