我有这个二进制图像,其中每个'曲线'代表一堆这些对象的帽子。它是通过对堆积的草帽的原始图像的区域进行阈值处理而获得的。
正如您所看到的,这些曲线在其形状内部有许多 间隙 和 孔 ,这些很糟糕使用像 cv.connectedcomponentes 这样的技术来获取图像中的对象数量,这是我的目标。
我认为如果有一些技术来填补这些间隙和/或主要是空洞,在原始二进制图像的较小部分,就像我正在展示的那些,可能是 连接附近的元素 或 检测和填充轮廓 ,可以将每条曲线细分为单个元素。
答案 0 :(得分: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代码(假设bw
是shape
(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 )