小白学python(opencv寻找并绘制轮廓)

@TOC

凸包检测提取轮廓

原理

对二值图像进行轮廓分析之后,对获取到的每个轮廓数据,
可以构建每个轮廓的凸包,构建完成之后会返回该凸包包含
的点集。根据返回的凸包点集可以绘制该轮廓对应的凸包。
OpenCV对轮廓提取凸包的API函数如下:
convexHull(
InputArray points,
OutputArray hull,
bool clockwise = false,
bool returnPoints = true
)

points参数是输入的轮廓点集
hull凸包检测的输出结果,当参数returnPoints为ture的时候返回
凸包的顶点坐标是个点集、returnPoints为false的是返回的是一个
integer的vector里面是凸包各个顶点在轮廓点集对应的index
clockwise 表示顺时针方向或者逆时针方向
returnPoints表示是否返回点集

opencvAPI函数用来判断一个轮廓是否为凸包,该方法如下:
isContourConvex(
InputArray contour
)
复制代码

代码

def findholl(src):#凸包检测
    # 读取图片并转至灰度模式
    
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

    # 二值化,取阈值为235
    ret, thresh = cv.threshold(gray, 235, 255, cv.THRESH_BINARY)

    # 寻找图像中的轮廓
    contours, hierarchy = cv.findContours(thresh, 2, 1)

    # 寻找物体的凸包并绘制凸包的轮廓
    for cnt in contours:
        hull = cv.convexHull(cnt)
        length = len(hull)
        # 如果凸包点集中的点个数大于5
        if length > 5:
            # 绘制图像凸包的轮廓
            for i in range(length):
                cv.line(src, tuple(hull[i][0]), tuple(hull[(i + 1) % length][0]), (0, 0, 255), 2)

    cv.imshow('finger', src)


复制代码

测试:
在这里插入图片描述

轮廓检测 绘出矩形框

获取轮廓

OpenCV2获取轮廓主要是用 cv2.findContours()

cv2.findContours(img, mode, method)
复制代码

绘出轮廓

cv2.drawContours()函数
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

第一个参数是指明在哪幅图像上绘制轮廓;
第二个参数是轮廓本身,在Python中是一个list。
第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。
复制代码

代码

def Conmtours(img):
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)

    contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    draw_img0 = cv.drawContours(img.copy(), contours, 0, (0, 255, 255), 3)
    draw_img1 = cv.drawContours(img.copy(), contours, 1, (255, 0, 255), 3)
    draw_img2 = cv.drawContours(img.copy(), contours, 2, (255, 255, 0), 3)
    draw_img3 = cv.drawContours(img.copy(), contours, -1, (0, 0, 255), 3)

    cv.imshow("img", img)
    cv.imshow("draw_img0", draw_img0)
    cv.imshow("draw_img1", draw_img1)
    cv.imshow("draw_img2", draw_img2)
    cv.imshow("draw_img3", draw_img3)
复制代码

在这里插入图片描述

将图中的轮廓用圆和矩形绘制

def ConmtoursMAX(img):
    # 二值化,  黑白二值化
    ret, thresh = cv.threshold(
        cv.cvtColor(img.copy(), cv.COLOR_BGR2GRAY),  # 转换为灰度图像,
        127, 255,  # 大于127的改为255  否则改为0
        cv.THRESH_BINARY)  # 黑白二值化
   

    # 搜索轮廓
    contours, hierarchy = cv.findContours(
        thresh,
        cv.RETR_EXTERNAL,
        cv.CHAIN_APPROX_SIMPLE)
    
    for c in contours:
        x, y, w, h = cv.boundingRect(c)
        """
        传入一个轮廓图像,返回 x y 是左上角的点, w和h是矩形边框的宽度和高度
        """
        cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # 获得最小的矩形轮廓 可能带旋转角度
        rect = cv.minAreaRect(c)
        # 计算最小区域的坐标
        box = cv.boxPoints(rect)
        # 坐标规范化为整数
        box = np.int0(box)
        # 画出轮廓
        cv.drawContours(img, [box], 0, (0, 0, 255), 3)

        # 计算最小封闭圆形的中心和半径
        (x, y), radius = cv.minEnclosingCircle(c)
        # 转换成整数
        center = (int(x), int(y))
        radius = int(radius)
        # 画出圆形
        img = cv.circle(img, center, radius, (0, 255, 0), 2)

    # 画出轮廓
    cv.drawContours(img, contours, -1, (255, 0, 0), 1)
    cv.imshow("contours", img)    
复制代码

(画这个圆心累啊)
在这里插入图片描述

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享