文章目录
- 目录说明
- contours_begin
- 目标
- 什么是轮廓?
- 如何画等高线?
- 轮廓逼近法
- contour_features
- 目标
- 1.Moments 时刻
- 2. Contour Area 轮廓面积
- 3. Contour Perimeter 轮廓周长
- 4. Contour Approximation 轮廓近似
- 5. Convex Hull 凸包
- 6. Checking Convexity 检查凸性
- 7. Bounding Rectangle 边界矩形
- 7.a. Straight Bounding Rectangle 直边界矩形
- 7.b. Rotated Rectangle 旋转的矩形
- 8. Minimum Enclosing Circle 最小外圈
- 9. Fitting an Ellipse 拟合椭圆
- 10. Fitting a Line 拟合直线
- contour_properties
- 1. Aspect Ratio 纵横比
- 2.Extent 范围
- 3.Solidity 坚固度
- 4. Equivalent Diameter 等效直径
- 5. Orientation 方向
- 6. Mask and Pixel Points 蒙版和像素点
- 7. Maximum Value, Minimum Value and their locations 最大值,最小值和它们的位置
- 8. Mean Color or Mean Intensity 平均颜色或平均强度
- 9. Extreme Points 极端点
- contours_more_functions
- 目标
- 理论与代码
- 1.凸性缺陷
- 2.点多边形检验
- 3.匹配的形状
- contours_hierarchy
- 目标
- 理论
- 什么是层级?
- OpenCV中的层次表示
- 轮廓线检索模式
- 1. RETR_LIST
- 2. RETR_EXTERNAL
- 3. RETR_CCOMP
- 4. RETR_TREE
源码目录:opencv-4.6.0\doc\py_tutorials\py_imgproc\py_contours
目录说明
-
tutorial_py_contours_begin
Learn to find and draw Contours
学习查找和绘制轮廓 -
tutorial_py_contour_features
Learn to find different features of contours like area, perimeter, bounding rectangle etc.
学习寻找不同的轮廓特征,如面积,周长,边界矩形等。 -
tutorial_py_contour_properties
Learn to find different properties of contours like Solidity, Mean Intensity etc.
学习找到不同的属性的轮廓,如固体,平均强度等。 -
tutorial_py_contours_more_functions
Learn to find convexity defects, pointPolygonTest, match different shapes etc.
学习查找凹凸缺陷,pointPolygonTest,匹配不同形状等。 -
tutorial_py_contours_hierarchy
Learn about Contour Hierarchy
了解轮廓层次
contours_begin
目标
- 了解轮廓是什么。
- 学习寻找轮廓,绘制轮廓等
- 你会看到这些函数:cv.findContours(), cv.drawContours()
什么是轮廓?
轮廓可以简单地解释为连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度。轮廓是形状分析和目标检测与识别的有用工具。
- 为了更好的精度,使用二值图像。因此,在找到轮廓之前,应用阈值或canny边缘检测。
- 自OpenCV 3.2, findContours()不再修改源图像。
- 在OpenCV中,寻找轮廓就像从黑色背景中寻找白色物体一样。记住,要找到的对象应该是白色的,背景应该是黑色的。
让我们看看如何找到二值图像的轮廓:
import numpy as np
import cv2 as cvim = cv.imread('test.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
在 cv.findContours() 函数中有三个参数,第一个是源图像,第二个是轮廓检索方式,第三个是轮廓逼近方法。它输出轮廓和层次结构。Contours是图像中所有轮廓的Python列表。每个单独的轮廓是物体边界点的(x,y)坐标的Numpy数组。
我们将在后面详细讨论第二个和第三个参数以及层次结构。在此之前,代码示例中给出的值将适用于所有图像。
如何画等高线?
使用cv.drawContours函数绘制轮廓.它也可以用来绘制任何形状,只要你有它的边界点。它的第一个参数是源图像,第二个参数是应该作为Python列表传递的轮廓,第三个参数是轮廓的索引(在绘制单个轮廓时很有用)。要绘制所有轮廓,传递-1),剩下的参数是颜色,厚度等。
- 绘制图像中的所有轮廓:
drawContours(img, contours, -1, (0,255,0), 3) - 要画一个单独的轮廓,如第四个轮廓:
drawContours(img, contours, 3, (0,255,0), 3) - 但大多数时候,下面的方法将是有用的:
cnt = contours[4]
cv.drawContours(img, [cnt], 0, (0,255,0), 3)
最后两个方法是相同的,但当你继续,你会发现最后一个更有用。
轮廓逼近法
cv.findContours函数的第三个参数它实际上表示什么?
上面我们说过,轮廓是具有相同强度的形状的边界。它存储形状边界的(x,y)坐标。但是它能存储所有的坐标吗?这是由轮廓近似法确定的。
如果你传递了cv.CHAIN_APPROX_NONE,存储所有边界点。但实际上我们需要所有的点吗?例如,你找到了一条直线的轮廓。是否需要直线上的所有点来表示这条直线?不,我们只需要这条线的两个端点。这就是cv.CHAIN_APPROX_SIMPLE。它去除所有冗余点并压缩轮廓,从而节省内存。
下面的矩形图演示了这种技术。只需在轮廓数组中的所有坐标上画一个圆(用蓝色绘制)。第一张图片显示了我用cv.CHAIN_APPROX_NONE得到的(734点)和第二张图像显示了cv.CHAIN_APPROX_SIMPLE(只有4点)。看,它节省了多少内存!
效果图:
完整代码:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltim = cv.imread('black-white.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
contours_all, hierarchy_all = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
print(len(contours), len(contours[0]))
print(len(contours_all), len(contours_all[0]))
img1 = im.copy()
img2 = im.copy()
for pos in contours[0]:cv.circle(img1, pos[0], 3, (0,255,0), -1)
for pos in contours_all[0]:cv.circle(img2, pos[0], 3, (0,255,0), -1)plt.subplot(221),plt.imshow(im),plt.title('Original')
plt.subplot(222),plt.imshow(img1),plt.title('cv.CHAIN_APPROX_SIMPLE')
plt.subplot(223),plt.imshow(img2),plt.title('cv.CHAIN_APPROX_NONE')plt.show()
contour_features
目标
在本文中,我们将学习
- 查找轮廓的不同特征,如面积,周长,质心,边界框等
- 你会看到很多与轮廓相关的函数。
1.Moments 时刻
图像矩帮助你计算一些特征,如物体的质心,物体的面积等。查看维基百科页面Image Moments
函数 cv.moments() 给出了计算出的所有矩值的字典。见下文:
import numpy as np
import cv2 as cvimg = cv.imread('star.jpg',