繁体   English   中英

如何使用Python / Opencv在二进制图像中分割附近的元素

[英]How to segment nearby elements in a binary image using Python/Opencv

我有这个二进制图像,其中每个“曲线”代表一堆来自这些对象的帽子。 它是通过对堆叠草帽的原始图像区域进行阈值处理而获得的。

二进制图像

如您所见,这些曲线在其形状内部有许多间隙 ,这很难使用cv.connectedcomponentes之类的技术来获取图像中的对象数量,这就是我的目标。

我认为,如果有某种技术可以填补原始二进制图像的较小部分中的这些间隙和/或主要是孔,例如我正在展示的波纹管,也许可以通过连接附近的元素检测并填充轮廓来实现 ,将每个曲线分割为一个单独的元素是可能的。

小区域1

小区域2

这不是最优雅的方法,但是应该足够简单。
考虑带w的垂直切片(与您在问题中发布的切片相同)。 如果将切片的各行上的白色像素相加,则应获得与帽子的六个边缘相对应的六个漂亮的“峰值”:

在此处输入图片说明

但是,由于轮缘是圆形的,因此对于此类估计,某些垂直切片会比其他切片好。
因此,我建议查看所有宽度为w切片,并对每个切片的峰值进行计数。
这是执行此操作的Matlab代码

img = imread('http://i.stack.imgur.com/69FfJ.jpg');  % read the image
bw = img(:,:,1)>128;  % convert to binary 

w = 75;  % width of slice
all_slices = imfilter(single(bw), ones(1,w)/w, 'symmetric')>.5;  % compute horizontal sum of all slices using filter
% a peak is a slice with more than 50% "white" pixels
peaks = diff( all_slices, 1, 1 ) > 0;  % detect the peaks using vertical diff
count_per_slice = sum( peaks, 1 );  % how many peaks each slice think it sees

查看count_per_slice的分布:

在此处输入图片说明

您会看到,尽管许多切片预测出错误的帽子数量(介于4到9之间),但大多数人投票赞成正确的帽子数量6:

num_hats = mode(count_per_slice);  % take the mode of the distribution.

一个执行相同操作的python代码(假设bwshape (h,w)和dtype bool的numpy数组):

from scipy import signal, stats
import numpy as np
w = 75;
all_slices = signal.convolve2d( bw.astype('f4'), np.ones((1,w),dtype='f4')/float(w), mode='same', boundary='symmetric')>0.5
peaks = np.diff( all_slices, n=1, axis=0 ) > 0
count_per_slice = peaks.sum( axis=0 )
num_hats = stats.mode( count_per_slice )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM