我想在这些图像中选择人员行作为单独的blob:
这可能吗?
修改:我想要选择的区域显示在此图片中(粗略地说,我是手动选择的):
如果其他blob也被选中,那也没关系(之后我可以按照它们的区域过滤它们)。
答案 0 :(得分:3)
这是让你入门的东西。我正在制作您展示的第一张图片。我看到你将scikit-image
作为标记包含在内,所以我假设你是用Python开发的。因此,我将使用Python包装器来帮助我们执行此操作。请注意,我选择的此算法的每个步骤的参数特别适用于第一个图像。您必须使用这些参数来使其他图像生效。
这是我做的:
cv2.cvtColor
cv2.adaptiveThreshold
执行自适应阈值,以便从背景中最佳地分割出形状。它们看起来像火车,因此我将从这里称这些形状的火车。cv2.morphologyEx
进行阈值处理所产生的任何间隙,并使用椭圆结构元素cv2.floodFill
。请注意,输入图像是这样的,您可以删除上下行以及最左侧和最右侧的列,并且必须在调用函数之前初始化存储泛洪结果的输出图像。cv2.findContours
找到图像中的轮廓。cv2.contourArea
来帮助我做到这一点。cv2.drawContours
假设第一个图像被称为train1.png
,这是代码!
# Import relevant libraries
import numpy as np
import cv2
# Read in image and convert to grayscale
im1 = cv2.imread('train1.png')
im1 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
# Adaptive Threshold
thresh = cv2.adaptiveThreshold(im1, 255,
adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C,
thresholdType=cv2.THRESH_BINARY_INV,
blockSize=21,
C=2)
# Morphology to close gaps
se = cv2.getStructuringElement(cv2.MORPH_RECT, (15,15))
out = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, se)
# Find holes
mask = np.zeros_like(im1)
cv2.floodFill(out[1:-1,1:-1].copy(), mask, (0,0), 255)
mask = (1 - mask).astype('bool')
# Fill holes
out[mask] = 255
# Find contours
contours,_ = cv2.findContours(out.copy(),
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
# Filter out contours with less than certain area
area = 50000
filtered_contours = filter(lambda x: cv2.contourArea(x) > area,
contours)
# Draw final contours
final = np.zeros_like(im1)
cv2.drawContours(final, filtered_contours, -1, 255, -1)
cv2.imshow('Shapes', final)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('train1_final.png', final)
这是我得到的图像。它并不完美,但它足以让你开始。