4

考虑下图:

交通图

这是交通视频片段中的一帧。

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

我正在研究 OpenCV 和 Python。

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

4

3 回答 3

5

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

您的方法应如下所示:

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

示例代码:

#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()
于 2013-03-16T15:29:23.990 回答
1

好吧,我建议您执行以下操作:

  1. 将图像分成不同的区域,根据各种事物主要是照明。
  2. 然后对于每个区域,应用阈值将重要区域(交通)与不重要区域(树木等)分开。( cv2.threshold)
  3. 使用轮廓,您可以将车辆与其他东西区分开来。(cv2.findContours以及更多)

如果你有视频流或类似的东西,你也可以使用运动检测之类的东西。

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

于 2013-03-14T15:18:55.090 回答
1

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

  1. 首先丢弃图像中您不感兴趣的部分。如果是静态相机,您可以手动计算该区域。在其他情况下尝试使用线检测算法
  2. 然后用 cvThreshold 提取背景(使用背景提取的好例子)。
  3. 提取后,您可以找到轮廓并分析其形状以区分物体(汽车、人等)。

希望这会有所帮助。

于 2013-03-14T08:51:08.697 回答