提取多边形形状的子图像

时间:2013-03-14 07:35:14

标签: python opencv python-2.7

考虑以下图片:

Image of traffic

这是来自流量视频片段的帧。

我想要做的是,只裁剪迎面而来的流量,并进行分析。我想要一种快速有效的方法,通过提供某些坐标,我可以提取多边形。

我正在研究OpenCV和Python。

编辑:
我看到的一个选项是将图像视为Numpy数组并使用for循环来提取某些元素,但这不会有效,我不知道它是否适合做。

3 个答案:

答案 0 :(得分:5)

我建议使用Contours提取您感兴趣的区域(您想要的任何形状)。 请参阅此文档:Drawing Contours

您的方法应如下:

  1. 通过将MouseEventListener附加到窗口,在图像本身上标记构成坐标的点。
  2. 使用创建蒙版图像。 (全零)
  3. 使用这些坐标集,使用 cv2.drawContours()方法绘制蒙版图像所需的形状,并用白色填充(255)。
  4. 使用原始灰度图像执行Bitwise_And操作。
  5. 示例代码:

    #Function
    def on_mouse(event, x, y, flags,(cPts,overlayImage,resetImage)):
        if event==cv.CV_EVENT_LBUTTONUP:
            cPts[0].append([x,y])
            cv2.circle(overlayImage,(x,y),5,(255),-1)
        elif event==cv.CV_EVENT_RBUTTONUP:
            cPts[0]=[]
            print cPts
            overlayImage[:]=resetImage[:]
    
    
    #Main Program
    cvImage=cv2.imread(inputImageFilePath)
    grayscaleImage=cv2.cvtColor(cvImage,cv.CV_BGR2GRAY)
    overlayImage=np.copy(grayscaleImage)
    
    cv2.namedWindow('preview')
    cPts=[[]]
    cv2.setMouseCallback('preview',on_mouse,(cPts,overlayImage,grayscaleImage))
    opacity=0.4
    while True:
        displayImage=cv2.addWeighted(overlayImage,opacity,grayscaleImage,1-opacity,0)
        cv2.imshow('preview',displayImage)
        keyPressed=cv2.waitKey(5)
        if keyPressed==27:
            break
        elif keyPressed==32:
            print cPts
            cv2.drawContours(overlayImage,np.array(cPts),0,255)
            maskImage=np.zeros_like(grayscaleImage)
            cv2.drawContours(maskImage,np.array(cPts),0,255,-1)
            extractedImage=np.bitwise_and(grayscaleImage,maskImage)
            cv2.imshow('extractedImage',extractedImage)
    cv2.destroyAllWindows()
    

答案 1 :(得分:1)

我可以提出一个算法版本:

  1. 首先丢弃图像中您不感兴趣的部分。如果是静态相机,您可以手动计算此区域。在其他情况下,请尝试使用Line Detection Algorithm
  2. 然后使用cvThreshold提取背景(使用background extraction的好例子)。
  3. 提取后,您可以找到轮廓并分析其形状,以区分对象(汽车,人员等)。
  4. 希望这会有所帮助。

答案 2 :(得分:1)

好吧,我建议你这样做:

  1. 根据主要照明的各种事物将图像分成不同的区域。
  2. 然后,对于每个区域,应用阈值将重要区域(交通)与不重要区域(树木等)分开。 (cv2.threshold
  3. 使用轮廓,您可以将车辆与其他车辆区分开来。(cv2.findContours及更多)
  4. 如果你有一个视频流或类似的东西,你也可以使用像运动检测这样的东西。

    您可能会发现一些有用的链接: