• Opencv图像轮廓检测——转换灰度图像、二值图像、绘制图像轮廓、轮廓特征、轮廓外接圆


    引言

    边缘是零零散散的,轮廓是一个整体。

    一、准备工作

    1.读取图像

    2.转灰度图像

    3.转换二值图像

    1. import cv2
    2. img=cv2.imread("C:/Users/bwy/Desktop/4.jpg",cv2.IMREAD_GRAYSCALE)
    3. ret,thresh=cv2.threshold(img,127,255,cv2.THRESH_BINARY)#图像转换成二值图像

    二、图像轮廓

    函数为:cv2.findContours(img,mode,method)

    参数解读:

    img:显而易见了就是图像

    mode:轮廓检索模式

    RETR_EXTERNAL:只检索最外面的轮廓

    RETR_LIST:检索所有的轮廓,并保存到另一条链表中

    RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界

    RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次

    method:轮廓逼近方法

    CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)

    CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分

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

     返回值:

    contours:列表,保存轮廓信息。

    np.array(contours).shape

    结果:

     hierarchy:数组,分层保存轮廓信息

    三、绘制图像轮廓

    注意:cv2.drawContours(img, contours, contourIdx, color, thickness):

    参数说明:

    图像要拷贝,不然会在原图像进行操作。

    contours:轮廓信息

    -1:代表所以有轮廓

    (0,0,255):代表用红色线绘制轮廓(B,G,R),还可以进行颜色的更改

    1:代表绘制轮廓线的宽度

    1. draw_img=im.copy()
    2. res=cv2.drawContours(draw_img,contours,-1,(0,0,255),1)
    3. cv_show('res',res)

    结果如图所示:

     四、轮廓特征

    4.1、轮廓计算

    在计算时,不能将轮廓全部放进去计算,计算时需要选出其中一个。下面使用轮廓信息中的第0个轮廓计算它的面积和周长。

    1. # 获取某一个轮廓用于计算
    2. cnt = contours[0]
    3. # ==1== 面积
    4. cv2.contourArea(cnt) # 8500.5
    5. # ==2== 周长
    6. cv2.arcLength(cnt,True) # 437.948

    4.2轮廓近似

    以直线代表曲线,曲线上的两个点构成的直线,曲线上任意找一点到直线的距离最远并且小于阈值就满足以曲代直,否则继续划分。

    1. img1 = cv2.imread("C:/Users/bwy/Desktop/5.png") # 获取一张图像
    2. gray = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) # 灰度图
    3. ret,thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 二值化
    4. cv_show('thresh',thresh)

    结果:

    1. contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) # 轮廓提取
    2. cnt=contours[0]
    3. draw = img1.copy() # 绘制轮廓
    4. res = cv2.drawContours(draw, [cnt], -1, (0,0,255), 4) # 在draw图像中绘制cnt轮廓
    5. cv_show('res',res) # 绘图
    6. epsilon = 0.01*cv2.arcLength(cnt,True) # 以周长的百分比作为阈值,指定的越小,得到的轮廓和原来的区别较小
    7. approx = cv2.approxPolyDP(cnt, epsilon, True) # 近似函数,cnt为轮廓,epsilon阈值。返回近似后的轮廓
    8. draw_image = img1.copy()
    9. res = cv2.drawContours(draw_image,[approx] , -1, (0,255,0),6) # 将近似后的轮廓approx画在原图上,用蓝色表示,线条粗2
    10. cv_show('res',res)

    结果如图所示:

    五、轮廓外接圆

    1. # 轮廓外接圆
    2. # 返回圆心坐标和半径
    3. (x,y),radius = cv2.minEnclosingCircle(cnt)
    4. # 圆心坐标
    5. center = (int(x),int(y))
    6. # 半径
    7. radius = int(radius)
    8. # 绘制外接圆,输入整型
    9. circle = cv2.circle(img1,center,radius,(255,0,0),2)
    10. cv_show('circle',circle)

     结果如图所示:

  • 相关阅读:
    【尚硅谷】IDEA2022快速上手开发利器
    Web Component -- 即将爆发的原生的 UI 组件化标准
    腾讯云应用服务器新增用户名密码
    Linux - MongoDB部署
    Vue项目使用SVG矢量图型基础步骤
    嵌入式设备时间同步(校时)
    CVPR2023 RIFormer, 无需TokenMixer也能达成SOTA性能的极简ViT架构
    前端需要去了解的nodejs知识(fs文件处理)
    黑马点评项目遇到的部分问题
    达梦数据库相关SQL及适配Mysql配置总结
  • 原文地址:https://blog.csdn.net/m0_72662900/article/details/126802330