youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)
Posted 小白YouCans
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)相关的知识,希望对你有一定的参考价值。
【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓(cv.drawContours)
1. 轮廓
轮廓是一系列相连的像素点组成的曲线,代表了物体的基本外形。轮廓常用于形状分析和物体的检测和识别。
边缘检测根据灰度的突变检测边界,但检测到的边缘通常还是零散的片段,并未构成整体。从背景中分离目标,就要将边缘像素连接构成轮廓。也就是说,轮廓是连续的,边缘不一定都连续。边缘主要是作为图像的特征使用,而轮廓主要用来分析物体的形态。
### 1.2 轮廓的绘制
OpenCV 提供函数 cv2.drawContours() 绘制轮廓。绘制轮廓并不是绘图显示,而是修改图像添加轮廓线。
函数说明:
cv.drawContours(image, contours, contourIdx, color[, thickness=1, lineType=LINE_8, hierarchy=Mat(), maxLevel=INT_MAX, offset=Point()] ) → image
cv.findContours() 对黑色背景的二值图像操作,通常会先使用阈值分割或边缘检测得到二值图像。
参数说明:
- image:输入/输出图像,必须是 BGR 格式的彩色图像
- contours: 输入的轮廓列表,每个轮廓由边界点坐标 (x,y) 向量构成
- contourIdx:所要绘制的轮廓的编号,-1 表示绘制所有轮廓
- color:绘制轮廓的颜色,RGB
- thickness:绘制轮廓的线宽,-1 (“CV_FILLED”)表示轮廓内部填充
- lineType:绘制轮廓的线型
- cv.FILLED:填充
- cv.LINE_4:4 邻接线型
- cv.LINE_8:8 邻接线型,默认值
- cv.LINE_AA:抗锯齿线型
- hierarchy: 轮廓的结构信息,可选项
- maxLevel:绘制轮廓的最大级别,存在轮廓结构信息 hierarchy 时才适用:0 表示仅绘制指定轮廓,1 表示绘制轮廓及下一级的子轮廓, 2 表示绘制轮廓及所有各级内部轮廓
- offset:每个轮廓点的偏移量,可选项
注意事项:
- 在一些 OpenCV 版本中,绘制轮廓操作会改变原始图像。为了避免不同版本带来的错误,推荐都采用原始图像的 copy 作为函数的输入图像。
例程 12.2:绘制轮廓
# 12.2 绘制轮廓
img = cv2.imread("../images/pattern1.png", flags=1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY_INV)
plt.figure(figsize=(9, 6))
plt.subplot(131), plt.axis('off'), plt.title("Origin")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 寻找二值化图中的轮廓
binary, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # OpenCV3
# contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # OpenCV4~
# 绘制最内层轮廓, hierarchy[0][i][2]=-1 表示没有子轮廓,即为最内层轮廓
contourEx = img.copy() # OpenCV3.2 之前的早期版本,查找轮廓函数会修改原始图像
for i in range(len(contours)): # 绘制第 i 个轮廓
if hierarchy[0][i][2]==-1: # 最内层轮廓
x, y, w, h = cv2.boundingRect(contours[i]) # 外接矩形
text = "(,)".format(i, x, y)
contourEx = cv2.drawContours(contourEx, contours, i, (205, 0, 0), thickness=-1) # 第 i 个轮廓,内部填充
contourEx = cv2.putText(contourEx, text, (x,y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255))
print("i=", i, ",contours[i]:", contours[i].shape, ",hierarchy[0][i] =", hierarchy[0][i], "text=", text)
# 绘制全部轮廓,contourIdx=-1 绘制全部轮廓
contourTree = img.copy()
contourTree = cv2.drawContours(contourTree, contours, -1, (0, 0, 255), 2)
plt.subplot(132), plt.axis('off'), plt.title("External contour")
plt.imshow(cv2.cvtColor(contourEx, cv2.COLOR_BGR2RGB))
plt.subplot(133), plt.axis('off'), plt.title("Tree contour")
plt.imshow(cv2.cvtColor(contourTree, cv2.COLOR_BGR2RGB))
plt.tight_layout()
plt.show()
(本节完)
版权声明:
OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124997075)
Copyright 2022 youcans, XUPT
Crated:2022-5-25
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中【youcans 的 OpenCV 例程200篇】147. 图像分割之孤立点检测
【youcans 的 OpenCV 例程200篇】148. 图像分割之线检测
【youcans 的 OpenCV 例程200篇】149. 图像分割之边缘模型
【youcans 的 OpenCV 例程200篇】150. 边缘检测梯度算子
【youcans 的 OpenCV 例程200篇】151. 边缘检测中的平滑处理
【youcans 的 OpenCV 例程200篇】152. 边缘检测之 LoG 算子
【youcans 的 OpenCV 例程200篇】153. 边缘检测之 DoG 算子
【youcans 的 OpenCV 例程200篇】154. 边缘检测之 Canny 算子
【youcans 的 OpenCV 例程200篇】155. 边缘连接的局部处理方法
【youcans 的 OpenCV 例程200篇】156. 边缘连接局部处理的简化算法
【youcans 的 OpenCV 例程200篇】157. 霍夫变换直线检测
【youcans 的 OpenCV 例程200篇】158. 阈值处理之固定阈值法
【youcans 的 OpenCV 例程200篇】159. 图像分割之全局阈值处理
【youcans 的 OpenCV 例程200篇】160. 图像处理之OTSU 方法
【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现
【youcans 的 OpenCV 例程200篇】162. 全局阈值处理改进方法
【youcans 的 OpenCV 例程200篇】163. 基于边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】164.使用 Laplace 边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】165.多阈值 OTSU 处理方法
【youcans 的 OpenCV 例程200篇】166.自适应阈值处理
【youcans 的 OpenCV 例程200篇】167.基于移动平均的可变阈值处理
【youcans 的 OpenCV 例程200篇】168.图像分割之区域生长
【youcans 的 OpenCV 例程200篇】169.图像分割之区域分离
【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类
【youcans 的 OpenCV 例程200篇】171.SLIC 超像素区域分割
【youcans 的 OpenCV 例程200篇】172.SLIC 超像素区域分割算法比较
【youcans 的 OpenCV 例程200篇】173.SEEDS 超像素区域分割
【youcans 的 OpenCV 例程200篇】174.LSC 超像素区域分割
【youcans 的 OpenCV 例程200篇】175.超像素区域分割方法比较
【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法
【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法
【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法
【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔
【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔
【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像
【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合
【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合
【youcans 的 OpenCV 例程200篇】190.基于图像分割的图像融合
【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合
【youcans 的 OpenCV 例程200篇】192.Gabor 滤波器组的形状
【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取
【youcans 的 OpenCV 例程200篇】194.寻找图像轮廓(cv.findContours)
【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓(cv.drawContours)
以上是关于youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇183.基于轮廓标记的分水岭算法
youcans 的 OpenCV 例程200篇182.基于形态学梯度的分水岭算法