OpenCv中cv2.findContours寻找轮廓错误,导致cv2.drawContours画出错误轮廓

前置知识:

①cv2.findContours用于在二值化图像中寻找轮廓

②cv2.drawContours能够根据cv2.findContours找到的轮廓在图像中画出轮廓


前情提要

笔者想要处理图像,正确的画出其轮廓,但画出的轮廓是错误的。以下为图像原图

一、错误代码及运行结果

错误代码如下:

import cv2

def show_picture(title,picture):
    """显示图像,按任意键退出"""
    cv2.imshow(f'{title}',picture)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 读入图像
img = cv2.imread('right_xia.PNG')
# 转为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 二值化【就是这里导致的问题!!!】
ret, thresh = cv2.threshold(gray_img, 200, 255, cv2.THRESH_BINARY)

# 定卷积核
element = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
# 开运算,消除黑图中小白点
open_img = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, element)

# 在二值化图像中寻找轮廓
contours, hierarchy = cv2.findContours(open_img,  cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 在原图的副本中画出轮廓
res = cv2.drawContours(img.copy(), contours, 0, ( 0, 0, 255), 2)
# 展示画完轮廓的图像
show_picture('contour_img', res)

二值化后的图像:

画完轮廓后的图像:                                                                                                                           

可以见到画出的轮廓是错误的,把整个图像窗口的白色部分都包进去了

二、原因

# 二值化【就是这里导致的问题!!!】
ret, thresh = cv2.threshold(gray_img, 200, 255, cv2.THRESH_BINARY)

此处的二值化,将像素值>200的点都变为像素值255(黑色),将其余像素点都变为像素值0(白色)

而cv2.findContours寻找的轮廓,是“白色”图像的轮廓,而在此处错误代码中,错误的将图像处理为黑色,背景处理为白色。因此,寻找到的轮廓错误。

三、解决办法

修改二值化的参数(将 cv2.THRESH_BINARY_INV 改为 cv2.THRESH_BINARY ),修改后的代码如下:

# 二值化【修改后的正确代码】
ret, thresh = cv2.threshold(gray_img, 200, 255, cv2.THRESH_BINARY_INV)

此时的二值化,是将图像处理为白色,背景处理为黑色,正确的满足了cv2.findContours的要求。

四、解决问题后的完整代码运行结果

完整代码:

import cv2

def show_picture(title,picture):
    """显示图像,按任意键退出"""
    cv2.imshow(f'{title}',picture)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 读入图像
img = cv2.imread('right_xia.PNG')
# 转为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 二值化【修改后的正确代码】
ret, thresh = cv2.threshold(gray_img, 200, 255, cv2.THRESH_BINARY_INV)

# 定卷积核
element = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
# 闭运算,消除黑图中小白点
close_img = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, element)

# 在二值化图像中寻找轮廓
contours, hierarchy = cv2.findContours(close_img,  cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 在原图的副本中画出轮廓
res = cv2.drawContours(img.copy(), contours, 0, ( 0, 0, 255), 2)
# 展示画完轮廓的图像
show_picture('contour_img', res)

二值化后图像:

画出正确轮廓的图像:

可以见到此时画出的轮廓是正确的,将所求图像全部包裹在内。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值