在灰度图像中获得类似彩色轮廓的斑点

时间:2015-06-04 04:23:25

标签: opencv image-processing computer-vision aforge scikit-image

我想在这些图像中选择人员行作为单独的blob:

这可能吗?

修改:我想要选择的区域显示在此图片中(粗略地说,我是手动选择的):

如果其他blob也被选中,那也没关系(之后我可以按照它们的区域过滤它们)。

1 个答案:

答案 0 :(得分:3)

这是让你入门的东西。我正在制作您展示的第一张图片。我看到你将scikit-image作为标记包含在内,所以我假设你是用Python开发的。因此,我将使用Python包装器来帮助我们执行此操作。请注意,我选择的此算法的每个步骤的参数特别适用于第一个图像。您必须使用这些参数来使其他图像生效。

这是我做的:

  1. 读入图片并通过cv2.cvtColor
  2. 转换为灰度
  3. 通过cv2.adaptiveThreshold执行自适应阈值,以便从背景中最佳地分割出形状。它们看起来像火车,因此我将从这里称这些形状的火车。
  4. 执行形态二元关闭以关闭通过cv2.morphologyEx进行阈值处理所产生的任何间隙,并使用椭圆结构元素
  5. 填写所有洞。基本上,您可以将孔视为被白色包围的黑色像素区域。执行此操作的常见方法是执行填充操作,种子像素从图像的左上角开始,然后反转结果以获得这些孔。一旦我们有这些洞,我们将使用这个掩码索引步骤#3中的图像并将这些像素设置为白色。我使用cv2.floodFill。请注意,输入图像是这样的,您可以删除上下行以及最左侧和最右侧的列,并且必须在调用函数之前初始化存储泛洪结果的输出图像。
  6. 通过cv2.findContours找到图像中的轮廓。
  7. 浏览每个轮廓并过滤掉面积小于一定量的轮廓。我使用cv2.contourArea来帮助我做到这一点。
  8. 对于剩余的轮廓,请使用cv2.drawContours
  9. 填充白色轮廓

    假设第一个图像被称为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)
    

    这是我得到的图像。它并不完美,但它足以让你开始。

    enter image description here