OpenCV:在二进制图像中绘制对象的轮廓

时间:2017-06-05 21:38:52

标签: python opencv

按照http://docs.opencv.org/trunk/d4/d73/tutorial_py_contours_begin.html提供的示例 ,我在Spyder环境中使用python来绘制二进制图像中检测到的组件的轮廓。我的代码在这里:

im = cv2.imread('test.jpg') #raw RGB image
im2 = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) #gray scale image
plt.imshow(im2,cmap = 'gray')

图像显示如下:

enter image description here

然后,

thresh, im_bw = cv2.threshold(im2, 127, 255, cv2.THRESH_BINARY) #im_bw: binary image
im3, contours, hierarchy = cv2.findContours(im_bw,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(im2, contours, -1, (0,255,0), 3)
plt.imshow(im2,cmap='gray')  #without the code, only an array displayed in the console

由于某些原因,这些代码没有给出带轮廓的图形。但如果我按如下方式更改最后两行代码:

cv2.drawContours(im, contours, -1, (0,255,0), 3)
plt.imshow(im,cmap='gray')

它产生一个带轮廓的数字:

enter image description here

我对这些代码如何工作感到困惑? cv2.drawCoutours仅适用于GRB图像吗?希望不是。 此外,注意轮廓[0]给出3D阵列:

idx = contours[0]
print idx.shape

(392L, 1L, 2L)

idx应存储所有轮廓点的像素坐标。但是如何解释每个维度代表什么,并从中获取每个轮廓点的像素坐标?然后我可以使用这些坐标来绘制轮廓而无需使用cv2.drawContours

2 个答案:

答案 0 :(得分:1)

cv2.findContours和cv2.drawContours都是破坏性方法,它们修改原始输入图像,后者仅适用于绘图的RBG图像,这解释了在绘制的灰度图像中没有显示可见轮廓。

除了cv2.drawContours之外,还可以使用由cv2.findContours获得的“轮廓”(在上面的代码中)存储的边界像素的索引来轻松绘制轮廓。

答案 1 :(得分:1)

混淆是由于cv2.findContours 只能应用于 二进制图像而cv2.drawContours 用于RGB。这就是为什么要绘制轮廓,您需要将im2转换为RGB,然后绘制您的轮廓,然后再将im2转换为二进制(GRAY)。但真正令人毛骨悚然的是,结果看起来并不像您预期​​的那样:您的轮廓像素看起来是灰色而不是白色(这意味着它们的值在 150-170 之间而不是 255 之间)。它可以很容易地修复:im2[im2!=0]=255。

im_gray = cv2.imread('test.jpg',0)
im_color=cv2.imread('test.jpg',1)
im3, contours, hierarchy = 
cv2.findContours(im_gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cv2.drawContours(im_color, contours, -1, (0,255,0), 3)
im = cv2.cvtColor(im_color, cv2.COLOR_BGR2GRAY)
# if you plot im now you will see grey contours not white
im[im!=0]=255
# all contours are white now!