hellou

opencv学习笔记(八)

图像轮廓:
用于识别和提取图像中物体的边界或轮廓信息。轮廓是由连续的边缘像素点组成的曲线,表示了物体在图像中的外形。

常用方法:
  1、预处理:首先,对图像进行预处理,例如:灰度化、滤波、二值化,以便更好地分离物体和背景;

  2、边缘检测:使用边缘检测算法(例如canny边缘检测)在预处理后的图像中找到物体的边缘。边缘检测算法可以根据 像素之间的灰度或者梯度差异来确定边缘;

  3、轮廓提取:通过对边缘图像应用轮廓提取算法(如OpenCV中的findContours函数),从边缘图像中提取物体的轮廓。该算法会将边缘像素连接成连续的轮廓曲线。

  4、轮廓处理:根据需要,可以对提取到的轮廓进行一些后续处理,如去除小的噪声轮廓、合并相邻的轮廓等。

  5、轮廓绘制:最后,将提取到的轮廓绘制在原始图像上,以便可视化或进一步的分析。

cv2.findContours(img,mode, method)

mode:轮廓检索模式

  • RETR_EXTERNAL:只检索最外面的轮廓;
  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表中;
  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层,顶层是各部分的外部边界,第二层是空洞的边界;
  • RETR_TREE:检索所有的轮廓,并重构给嵌套轮廓的整个层次;

method:轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
  • CHAIN_APPROX_SIMPLE:仅存储水平、垂直和对角线方向的终点,将中间点进行压缩
  • CHAIN_APPROX_TC89_L1 和 CHAIN_APPROX_TC89_KCOS:  应用 Teh-Chin 链逼近算法进行轮廓压缩

函数返回值:

  • contours: 检测到的轮廓列表。每个轮廓表示为一个点集的列表,其中每个点是 (x, y) 的坐标。
#图像轮廓检测
import cv2
import numpy as np

"""cv2.findContours(img,mode,method)
mode:轮廓检测模式
>RETR_EXTEREANL:只检索最外面的轮廓;
>RETR_LIST:检索所有的轮廓,并将其保存到一条链表中;
>RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各个部分的外部边界,第二层是空洞的边界;
>RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次(常用)
method:轮廓逼近方法
>CHAIN_APPROX_NONE:以freeman链码的方式输出所有轮廓,所有其他方法输出多边形(顶点的序列);
>CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。"""

img = cv2.imread('C:/Users/hellou/Desktop/beautiful.jpg')
img = cv2.resize(img,(600,600))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转灰度图
#为了更高的准确率,使用二值图像
ret, thersh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
cv2.imshow('thersh',thersh)
cv2.waitKey(0)
cv2.destroyAllWindows()

contours, hierachy = cv2.findContours(thersh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
#contours保存的轮廓信息,hiercahy保存的层级
"""cv2.findContours()有三个参数:thresh、cv2.RETR_TREE、cv2.CHAIN_APPROX_SIMPLE。

    参数说明:

        thresh:图像数据(二值图像或经过Canny算法处理之后的图像)
        cv2.RETR_TREE:轮廓检索方式,还有cv2.RETR_LIST、cv2.RETR_EXTERNAL、cv2.RETR_CCOMP
        cv2.CHAIN_APPROX_SIMPLE:轮廓的估计方法,除此之外还有 cv2.CHAIN_APPROX_NONE"""
"""绘制轮廓
传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
注意需要copy,不然原图会变"""
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

draw_img = img.copy()
res_2 = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2)
"""cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
第一个参数是指明在哪幅图像上绘制轮廓;image为三通道才能显示轮廓
第二个参数是轮廓本身,在Python中是一个list;
第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。
-1指默认全部轮廓,指定为char值就是按照顺序依次选择(分内外)
2代表线条宽度
"""
cv2.imshow("res_2",res_2)
cv2.waitKey(0)
cv2.destroyAllWindows()

#轮廓特征
cnt = contours[0]#方括号里面的数字表示第几个轮廓
cv2.contourArea(cnt)#表示面积
cv2.arcLength(cnt,True)#周长,True表示闭合的

ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

是使用 OpenCV 中的阈值化函数对灰度图像进行二值化处理。

参数说明:

  • gray: 输入的灰度图像。
  • 127: 阈值,用于将图像中的像素分成两类:小于等于阈值的像素设为0,大于阈值的像素设为255。
  • 255: 阈值化后的像素的最大值。
  • cv2.THRESH_BINARY: 阈值化方法,表示使用二进制阈值化方法,将像素分为两类。

函数返回值:

  • ret: 所选择的阈值。
  • thresh: 阈值化后的二值图像。

cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)

  • image: 要在其上绘制轮廓的图像。
  • contours: 要绘制的轮廓列表。
  • contourIdx: 指定要绘制的轮廓在轮廓列表中的索引。如果为负值(如 -1),则绘制所有的轮廓。
  • color: 绘制轮廓的颜色,可以是单个整数值(灰度图像)或包含三个整数值的元组/列表(彩色图像)。
  • thickness: 绘制轮廓线的宽度。如果为负值,则绘制轮廓的内部区域。
  • lineType: 线条类型,指定绘制线条的样式。默认为 8 连接线条。
  • hierarchy: 轮廓的层级关系数组,与 cv2.findContours() 函数返回的层级关系数组一致。
  • maxLevel: 绘制轮廓的最大层级。如果为 0,则绘制最外层的轮廓,如果为 1,则绘制最外层和内层轮廓,以此类推。
  • offset: 可选的偏移量参数,用于指定轮廓点坐标的偏移。

函数无返回值,它会直接在输入的图像上绘制轮廓。

轮廓特征:
几个常用的轮廓特征:

  1. 轮廓面积(Contour Area): 表示轮廓所包围的区域的面积,可以通过 cv2.contourArea() 函数计算得到。

  2. 轮廓周长(Contour Perimeter): 表示轮廓的周长或长度,可以通过 cv2.arcLength() 函数计算得到。

  3. 轮廓近似多边形: 使用多边形逼近方法将轮廓曲线拟合为近似的多边形。通过调整逼近的精度参数,可以获得不同级别的近似多边形。

  4. 轮廓凸包(Convex Hull): 表示能够包围整个轮廓的最小凸多边形,可以使用 cv2.convexHull() 函数计算得到。

  5. 轮廓重心(Contour Centroid): 表示轮廓的重心位置,可以通过计算轮廓中所有点的坐标的平均值得到。

  6. 轮廓方向(Contour Orientation): 表示轮廓的主要方向或朝向,通常使用轮廓的拟合椭圆的角度或最小外接矩形的角度来表示。

  7. 轮廓边界框(Bounding Box): 表示能够完全包围轮廓的最小矩形框,可以使用 cv2.boundingRect() 函数计算得到。

  8. 轮廓形状特征: 包括圆度、长宽比、矩形度等特征,用于描述轮廓的形状特点。

轮廓近似:
approx = cv2.approxPolyDP(curve, epsilon, closed)

  • curve: 输入的轮廓曲线,通常为一个点集的列表。
  • epsilon: 近似精度,表示最大允许的拟合误差。较小的 epsilon 值会产生更接近原始轮廓的近似结果。
  • closed: 是否将近似结果作为封闭的曲线返回。如果为 True,则返回封闭的曲线;如果为 False,则返回非封闭的多边形。

函数返回近似的轮廓曲线或多边形,类型与输入的曲线类型相同(如点集列表或 Numpy 数组)。

#图像轮廓近似
import cv2
import numpy as np

#轮廓近似
img = cv2.imread('C:/Users/hellou/Desktop/zhong.jpg')
img = cv2.resize(img,(600,600))

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

epsilon =0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

draw_img = img.copy()
res_2 = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv2.imshow('res_2',res_2)
cv2.waitKey(0)
cv2.destroyAllWindows()

res_3 = np.hstack((img,res,res_2))
cv2.imshow('res_3',res_3)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

posted on 2023-06-22 11:13  云上u  阅读(114)  评论(0编辑  收藏  举报

导航