python - 在没有 scipy 的情况下计算二值化图像中的对象
问题描述
我正在尝试计算图像中对象的数量,我已经对其进行了二值化,但是,我不允许使用 scipy 或 numpy 包,因此我不能使用scipy.ndimage.label
,有什么想法吗?我的尝试计算了 80 多个对象,但只有 13 个(用 scipy 计算)
def label(img):
n=1
for i in range(h):
for j in range(c):
if img[i][j]==255:
if img[i-1][j]!=0 and img[i-1][j]!=255:
img[i][j]=img[i-1][j]
elif img[i+1][j]!=0 and img[i+1][j]!=255:
img[i][j]=img[i-1][j]
elif img[i][j+1]!=0 and img[i][j+1]!=255:
img[i][j]=img[i][j+1]
elif img[i][j-1]!=0 and img[i][j-1]!=255:
img[i][j]=img[i][j-1]
else:
img[i][j]=n
if img[i-1][j]!=0:
img[i-1][j]=img[i][j]
if img[i+1][j]!=0:
img[i+1][j]=img[i][j]
if img[i][j+1]!=0:
img[i][j+1]=img[i][j]
if img[i][j-1]!=0:
img[i][j-1]=img[i][j]
n+=1
elif img[i][j]!=0:
if img[i-1][j]!=0:
img[i-1][j]=img[i][j]
if img[i+1][j]!=0:
img[i+1][j]=img[i][j]
if img[i][j+1]!=0:
img[i][j+1]=img[i][j]
if img[i][j-1]!=0:
img[i][j-1]=img[i][j]
return img,n
解决方案
你会想要像https://codereview.stackexchange.com/questions/148897/floodfill-algorithm这样的东西,它实现了https://en.wikipedia.org/wiki/Flood_fill。如果这对您可行,它非常适合numba或 cython。
或许您可以使用已经提供 Floodfill 的 OpenCV:https ://docs.opencv.org/3.4/d7/d1b/group__imgproc__misc.html#gaf1f55a048f8a45bc3383586e80b1f0d0 。
假设您已经二值化,所以背景是颜色一,对象是颜色零。设置c = 2
,扫描一个零像素,并用颜色填充它c
。现在递增c
,扫描为零,填充,起泡,冲洗,重复。您最终会看到每个对象都带有不同的颜色,因此您可以将其用作隔离蒙版。不同的颜色在调试过程中非常有帮助,但如果您只想计数,当然三种颜色就足够了(甚至两种颜色)。最终的位图将统一为双色情况下的背景颜色。
使用 4 元素Von Neumann 邻域与8 元素邻域将对最终结果产生很大影响。通过 8 元素设置中的对角连接,油漆更容易“泄漏”。进行边缘检测和加厚可以帮助减少不必要的颜色泄漏。
推荐阅读
- swift - 如何在 Swift 中使用相同类型在另一个泛型中初始化一个泛型?
- html - 从高度 0 到 100 的过渡元素,从底部开始
- vb.net - 带变量的数据列表达式
- c - 禁用 clang-tidy 诊断
- webgl - WebGL 德罗斯特效果
- javascript - 未找到模块:导入模块以做出反应时无法解析“axios”
- iccube - icCube 中是否可以有没有层次结构的维度?
- html - 如何包装 SVG
里面的元素 ? - excel - 投资公式
- amazon-cloudformation - 在不使用 Jenkins cloudformation 插件启动创建/更新堆栈后,如何从 Jenkins Job 跟踪 Cloudformation 事件?