不是最优雅的方式,但应该足够简单。
考虑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 )