在OpenCV 2.4中处理轮廓和边界矩形-python 2.7
image-processing
opencv
python-2.7
5
0

我正在使用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()
参考资料:
Stack Overflow
收藏
评论
共 1 个回答
高赞 时间 活跃

由于您的原始图像噪声很大,一个简单的解决方法是使用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)

但是,此方法不是最可靠的方法,因为您必须手动指定内核大小,并且代码中的cnt=contours[0]行假定感兴趣的轮廓是轮廓列表中的firs,只有当只有一个轮廓。一种更可靠的方法是假设您对最大轮廓感兴趣,这将使您甚至补偿中等的噪声。

为此,添加以下行:

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

行后:

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

产生此代码:

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()

这两种方法都给出带有正确边界框的结果:

边界框结果

NB
由于OpenCV 3.x中findContours()方法返回3个结果(可以看出这里 ),因此额外的返回值应该抓住这样的:

_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPL‌​E)
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号