python cv2.findContours参数测试

findContours是连通域处理中最常用的函数之一,顾名思义,是实现图像中连通域的查找定位。结合cv2.drawContours/cv2.contourArea/cv2.boundingRect/cv2.minAreaRect等函数可以实现连通域轮廓的描绘,面积计算,外接四边形和最小外接四边形的求取。
opencv4中函数原型:

contours,hierarchy=cv2.findContours(img, mode, method[, contours[, hierarchy[, offset ]]])  

输出参数:

contours:查找到的轮廓的列表
hierarchy:保存每个连通域对应的属性

输入参数:

img: 输入的图像,可以为灰度图和二值图,常用的为二值图,背景为黑色,前景为白色
mode:表示轮廓的检索模式.常用的有cv2.RETR_EXTERNAL和cv2.RETR_TREE
    cv2.RETR_EXTERNAL  只检测外轮廓
    cv2.RETR_TREE 内外轮廓都检测
	此外还有,具体功能待探索:
    cv2.RETR_LIST
    cv2.RETR_CCOMP
method:轮廓的近似办法
    cv2.CHAIN_APPROX_NONE 存储所有的轮廓点
    cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

函数测试如下:

def imshow(img, height, width, title, flagbatch):
    cv2.namedWindow(title, 0)  # 参数必须为0
    cv2.resizeWindow(title, width, height)
    cv2.moveWindow(title, 600, 300) # 窗口出现的位置
    cv2.imshow(title, img)
    if flagbatch:
        cv2.waitKey(0)
def TestContour():
    font = cv2.FONT_HERSHEY_SIMPLEX
    img = cv2.imread('./datasets/logo1.jpg')
    gray = 255 - cv2.imread('./datasets/logo1.jpg',0) # 保证前景为白色

    _,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)

    H,W = binary.shape

    mode = [cv2.RETR_EXTERNAL,cv2.RETR_TREE]
    method = [cv2.CHAIN_APPROX_NONE,cv2.CHAIN_APPROX_SIMPLE]
    plt.figure()
    for mode_id in range(2):
        for met_id in range(2):
            pltimg = img.copy()
            title = str(mode_id) + '_' + str(met_id)
            contours, hierarchy = cv2.findContours(binary,mode[mode_id],method[met_id])

            contours = sorted(contours, key=lambda contour: cv2.contourArea(contour),reverse=True) # 按连通域面积从大到小排序

            Num = len(contours)

            for i in range(Num):
                area = cv2.contourArea(contours[i])
                (x, y, w, h) = cv2.boundingRect(contours[i])
                cv2.rectangle(pltimg, (x, y), (x + w, y + h), (0, 0, 255), 2, cv2.LINE_AA)
                cv2.putText(pltimg, "No.{},area:{}".format(i+1,area), (x-5, y - 5), font, 0.8, (255, 0, 0), 2)

            # imshow(img,H,W,'img',True)

            plt.subplot(2,2,2*mode_id + met_id + 1)
            plt.imshow(pltimg[:,:,[2,1,0]])  # plt 和 opencv的通道顺序相反,前者为rgb, 后者为bgr
            plt.title(title)

    plt.show()



  1. 无内轮廓图像
    在这里插入图片描述
    测试效果如下:
    在这里插入图片描述
    可以看到对于只有外轮廓的连通域,四种组合参数的效果一致。
  2. 有内外轮廓图像
    在这里插入图片描述
    测试效果如下:
    在这里插入图片描述
    可以看到对于有内外轮廓的连通域,external只检测外轮廓,tree则同时检测了内外轮廓。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值