您的算法允许整个图像(保存为一个像素)为“轮廓”.我不确定这究竟是你想要的;通常轮廓是两个不同区域之间的边界.您的方法的问题是您可以获得没有特别明显的遍历顺序的巨大像素块.如果您的轮廓厚度为单个像素,则遍历顺序更加明显:顺时针或逆时针.
请考虑以下图像.
........
..%%%%..
.%%%%...
...%%%%.
....%...
........
在这里,我把所有的东西都标记为“黑暗”(也许是50,可能)为%,一切都很明亮.现在你可以选择两个区域之间边界上的任何像素(我会选择黑暗的一面;你也可以在光线侧绘制轮廓,或者在光线和黑暗面之间直接绘制更多的工作.)
........
..%%%%..
.*%%%...
...%%%%.
....%...
........
现在,您尝试沿着暗区域的外边缘,一次一个像素.首先,你看一下明亮的方向(例如直接离开).然后你转动 – 逆时针旋转,让我们说 – 直到你遇到一个黑暗的像素.
........
..%%%%..
1*5%%...
234%%%%.
....%...
........
一旦你到达第5位,你会看到它是黑暗的.因此,您将其标记为轮廓的一部分,然后通过从刚刚来自的像素开始扫描来尝试找到轮廓上的下一个部分
........
..%%%%..
.0*%%...
.123%%%.
....%...
........
这里0是你来自的地方 – 你不会回到那里 – 然后你尝试像素1和2(两个光,这是不正常的),直到你点击像素3,这是黑暗的.
通过这种方式,您可以逐个像素地遍历轮廓 – 既识别轮廓又获得像素的顺序 – 直到您与开始时相同的像素发生碰撞并离开它,这样您就可以达到相同的像素你是第一次离开时做的.然后关闭轮廓.在我们的例子中,我们正在制作一个8连通的轮廓(即我们看8个邻居,而不是4个),我们得到以下(其中@表示轮廓点).
........
..@@@@..
.@@%@...
...@%@@.
....@...
........
(你必须有这个两行标准,或者如果你有一个像素宽的黑暗区域,你会向上走,但是不能沿着它向后走.)
此时,您已覆盖整个边界.但可能还有其他人.继续寻找浅色像素旁边的暗像素,直到在所有像素的顶部绘制轮廓.现在,您已将两级图像(暗和亮像素)转换为一组轮廓.
如果轮廓最终太嘈杂,请考虑先模糊图像.这将使轮廓平滑. (或者,您可以先找到轮廓,然后使用移动窗口平均坐标.)