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
: 可选的偏移量参数,用于指定轮廓点坐标的偏移。
函数无返回值,它会直接在输入的图像上绘制轮廓。
轮廓特征:
几个常用的轮廓特征:
-
轮廓面积(Contour Area): 表示轮廓所包围的区域的面积,可以通过
cv2.contourArea()
函数计算得到。 -
轮廓周长(Contour Perimeter): 表示轮廓的周长或长度,可以通过
cv2.arcLength()
函数计算得到。 -
轮廓近似多边形: 使用多边形逼近方法将轮廓曲线拟合为近似的多边形。通过调整逼近的精度参数,可以获得不同级别的近似多边形。
-
轮廓凸包(Convex Hull): 表示能够包围整个轮廓的最小凸多边形,可以使用
cv2.convexHull()
函数计算得到。 -
轮廓重心(Contour Centroid): 表示轮廓的重心位置,可以通过计算轮廓中所有点的坐标的平均值得到。
-
轮廓方向(Contour Orientation): 表示轮廓的主要方向或朝向,通常使用轮廓的拟合椭圆的角度或最小外接矩形的角度来表示。
-
轮廓边界框(Bounding Box): 表示能够完全包围轮廓的最小矩形框,可以使用
cv2.boundingRect()
函数计算得到。 -
轮廓形状特征: 包括圆度、长宽比、矩形度等特征,用于描述轮廓的形状特点。
轮廓近似:
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()