处理OpenCV 2.4中的轮廓和边界矩形 - python 2.7 [英] Dealing with contours and bounding rectangle in OpenCV 2.4 - python 2.7

查看:849
本文介绍了处理OpenCV 2.4中的轮廓和边界矩形 - python 2.7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用openCv和python,我正在处理结构分析和形状描述符。
我找到了这个博客:),因此应该捕获额外的返回值,如:

  _,等高线,等级= cv2.findContou rs(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPL E)


I am working with openCv and python and I am dealing with Structural Analysis and Shape Descriptors. I have found this blog: http://opencvpython.blogspot.it/2012/06/contours-2-brotherhood.html that's very helpful and I have tried with a black and white image to drawing a bounding rectangle and it works. But now from an image i extract, for example, the yellow color and on that i would like to draw a bounding rectangle. The problem is that the black and white image is not uniform it has some noise and like that the code doesn't recognize the whole shape.

And this is the code:

import numpy as np
import cv2

im = cv2.imread('shot.bmp')
hsv_img = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
COLOR_MIN = np.array([20, 80, 80],np.uint8)
COLOR_MAX = np.array([40, 255, 255],np.uint8)
frame_threshed = cv2.inRange(hsv_img, COLOR_MIN, COLOR_MAX)
imgray = frame_threshed
ret,thresh = cv2.threshold(frame_threshed,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt=contours[0]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Show",im)
cv2.waitKey()
cv2.destroyAllWindows()

解决方案

Since your original image is fairly noisy, a simple fix is to remove some of the noise using cv2.medianBlur() This will remove small noise areas in your original image, and leave you with only one contour. The first few lines of your code would look like this:

im = cv2.imread('shot.bmp')
im = cv2.medianBlur(im,5)    # 5 is a fairly small kernel size
hsv_img = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

However, this method is not the most robust because you must manually specify a kernel size, and the line cnt=contours[0] in your code assumes that the contour of interest is the firs in the list of contours, which is only true if there is only one contour. A more robust method is to assume that you are interested in the largest contour, which will allow you to compensate for even moderate noise.

To do this, add the lines:

# Find the index of the largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]

after the line:

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

Resulting in this code:

import numpy as np
import cv2

im = cv2.imread('shot.bmp')
hsv_img = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
COLOR_MIN = np.array([20, 80, 80],np.uint8)
COLOR_MAX = np.array([40, 255, 255],np.uint8)
frame_threshed = cv2.inRange(hsv_img, COLOR_MIN, COLOR_MAX)
imgray = frame_threshed
ret,thresh = cv2.threshold(frame_threshed,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

# Find the index of the largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]

x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Show",im)
cv2.waitKey()
cv2.destroyAllWindows()

Both of these methods give a result with a correct bounding box:

N.B.
As of OpenCV 3.x the findContours() method returns 3 results (as can be seen here), so the additional return value should be caught like:

_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPL‌​E)

这篇关于处理OpenCV 2.4中的轮廓和边界矩形 - python 2.7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆