Gia*_*fra 19 opencv image-processing python-2.7 opencv-contour
我正在使用openCv和python,我正在处理结构分析和形状描述符.我找到了这个博客:http://opencvpython.blogspot.it/2012/06/contours-2-brotherhood.html 这是非常有帮助的,我尝试用黑白图像绘制一个边界矩形,它的工作原理.但是现在从我提取的图像,例如,黄色和我想要绘制一个边界矩形.问题是黑白图像不均匀,有一些噪音,而且代码不能识别整个形状.



这是代码:
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()
Run Code Online (Sandbox Code Playgroud)
Aur*_*ius 38
由于您的原始图像相当嘈杂,因此使用cv2.medianBlur()此功能可以消除原始图像中的小噪声区域,并且只留下一个轮廓.代码的前几行如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
但是,此方法并不是最强大的,因为您必须手动指定内核大小,并且cnt=contours[0]代码中的行假定感兴趣的轮廓是轮廓列表中的第1个,只有在只有一个轮廓时才会出现这种情况.更稳健的方法是假设您对最大轮廓感兴趣,这将允许您补偿甚至适度的噪音.
为此,请添加以下行:
# Find the index of the largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]
Run Code Online (Sandbox Code Playgroud)
行后:
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
Run Code Online (Sandbox Code Playgroud)
导致此代码:
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()
Run Code Online (Sandbox Code Playgroud)
这两种方法都给出了一个带有正确边界框的结果:

NB
作为OpenCV3.X的findContours()方法返回3个结果(可以看出这里),因此额外的返回值应该抓住这样的:
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPL??E)
Run Code Online (Sandbox Code Playgroud)