OpenCV —— contours_matrix_()_[]
😶🌫️😶🌫️😶🌫️😶🌫️Take your time ! 😶🌫️😶🌫️😶🌫️😶🌫️
💥个人主页:🔥🔥🔥大魔王🔥🔥🔥
💥所属专栏:🔥魔王的修炼之路–Computer vision🔥
如果你觉得这篇文章对你有帮助,请在文章结尾处留下你的点赞👍和关注💖,支持一下博主。同时记得收藏✨这篇文章,方便以后重新阅读。
文章目录
- 检测轮廓
- numpy 创建矩阵与数组
- 三种图像的区别及转换
- () 与 [] 应用
检测轮廓
import cv2 import numpy as npcv2.namedWindow("win", cv2.WINDOW_NORMAL)# 自己创建图像 # # (y,x) # img = np.zeros((480, 640, 3), np.uint8)# # 绘制一个长方形(x,y) # cv2.rectangle(img, (100, 50), (500, 400), (255, 255, 255), 2) # 这需要是白色,因为在灰度图转为二值图时,阈值的影响。 # # 具体原因:彩色图转为灰度图后,灰度图对应的数字低于阈值,在转的时候就跟着黑色背景也变为了黑色,所以就检测不到轮廓了。 # # 二值化的阈值要小于灰度图里你想保留的区域的灰度值,否则就变成背景,轮廓自然找不到。# 读取图像 img = cv2.imread("../images/3.jpg")print(img.shape) # 形状# 彩色图转为灰度图(单通道) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化(只能从灰度图转过来) # 参数:灰度图(单通道);阈值;最大值(即高于阈值设置为多少);阈值处理类型 # 返回值:实际使用的阈值(一般就是你输入的阈值);二值图 # 单词意思:threshold,阈值。 ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) # + cv2.THRESH_OTSU# 查找轮廓(一般都转换成灰度图查找):普通绘制轮廓、多边形逼近、凸包,都必须在查找轮廓后进行! # 参数:二值图;怎么查找轮廓(即下标顺序以及是否查找内部轮廓);表示怎么记录轮廓,当前的是只记录关键点 # 返回值:轮廓(点的集合);层级关系 contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 打印轮廓(点集) # print(contours)# 绘制轮廓 # 参数:原图(因为轮廓已经有了,不用二值图了,也不能绘制在二值图);轮廓;绘制哪个轮廓(-1 全部绘制);颜色;粗细(-1 填充外部空间) cv2.drawContours(img, contours, -1, (0, 0, 255), 3) # 第二个参数需要是多个轮廓的列表,正好 findContours() 返回的就是# # 绘制最大轮廓,因为很乱 # # 找到最大轮廓 # max_contour = max(contours, key=cv2.contourArea) # # 绘制最大轮廓 # cv2.drawContours(img, [max_contour], -1, (0, 0, 255), 2)# 计算面积 area = cv2.contourArea(contours[0]) print(type(area)) print(f"area = {area}")# 计算周长 # 参数:计算哪个轮廓周长;是否计算首尾相连的长度 len = cv2.arcLength(contours[0], True) print(len)# 多边形逼近:一次只能处理一个轮廓 # 参数:通常取1%~5% 周长 e = 20 # 精度 approx = cv2.approxPolyDP(contours[0], e, True) # 返回的是一个轮廓逼近后的数据 # cv2.drawContours(img, [approx], -1, (0, 0, 255)) # 第二个参数需要是多个轮廓的列表# 凸包:一次只能处理一个轮廓 hull = cv2.convexHull(contours[0])# 返回的是一个轮廓逼近后的数据 cv2.drawContours(img, [approx], -1, (0, 0, 255)) # 第二个参数需要是多个轮廓的列表cv2.imshow("win", img)key = cv2.waitKey(0) if key & 0xff == ord('q'):cv2.destroyAllWindows()
numpy 创建矩阵与数组
将彩色图转换为灰度图,是为了简化通道;二值化,是为了突出目标和背景;这样才能稳定高效地提取轮廓。
目标 | 用途 | 推荐函数(不绝对,看你怎么给结构) | 示例 |
---|---|---|---|
创建图像矩阵 | 用作图像(黑、白、灰背景) | np.zeros / ones / full(np.uint8) | np.zeros((H, W, 3), np.uint8) |
创建点集数组 | 用于轮廓、多边形坐标 | np.array([...], np.int32) | np.array([(x1,y1), (x2,y2), ...]) |
返回的数据类型 | 都是 | np.ndarray (NumPy数组) | 可直接传给 OpenCV 绘图/处理函数 |
三种图像的区别及转换
步骤 | 数据形式 | 通道数 | 优点 | 用途 |
---|---|---|---|---|
彩色图像 | [B, G, R] | 3 | 色彩丰富 | 原始图、显示用 |
灰度图像 | [0~255] | 1 | 亮度信息,降维 | 边缘检测、二值化前处理 |
二值图像 | 0或255 | 1 | 背景/前景分明,适合分析形状 | 查找轮廓、区域分析 |
轮廓数据 | 一组点坐标 | N/A | 表示物体边界(如矩形、曲线) | 识别目标、标注框、形状分析等 |
操作 | OpenCV 函数 |
---|---|
彩色 → 灰度 | cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
灰度 → 二值 | cv2.threshold() |
边缘检测(可选) | cv2.Canny() |
轮廓查找 | cv2.findContours() |
绘制轮廓 | cv2.drawContours() |
() 与 [] 应用
[]
是列表:可变的、常用的点集、数组等:[1, 2, 3] # Python 列表 [(100, 100), (200, 200)] # 点集(列表嵌套元组) np.array([[1,2], [3,4]]) # 用列表构造数组(array 一般用于点集,数组即图片用 zeros\ones\full等)
()
是元组:不可变,很多坐标点(以及 shape)就是元组(100, 200) # 一个点的坐标(x, y) (200, 200, 3) # 图像的 shape
⚠️ 注意:在 Python 中
(x, y)
和[x, y]
都能表示坐标,但 元组更常见更推荐。
数组索引/切片 →
[]
数组访问用
[]
,绝不能用()
:img[0, 0] # 访问图像的第一个像素(BGR 值) gray[100:200, 50:100] # 切片区域 pts[0] # 第一个点
典型例子对比
场景 示例代码 说明 ✅ 调用函数 cv2.threshold(..., ...)
函数调用,传入参数 → 用小括号 ()
✅ 创建数组 np.zeros((200, 200, 3), np.uint8)
函数里再传个元组 (H, W, C)
→()
✅ 创建点集 pts = np.array([(x1, y1), (x2, y2)], np.int32)
列表 []
里嵌套元组()
✅ 数组索引 img[100, 50]
图像访问,用方括号 []
总结口诀:
🔹 函数要调用,用
()
🔹 列表元素,用[]
🔹 点的坐标,用()
(元组更常见)
🔹 数组取值,也用[]
- 博主长期更新,博主的目标是不断提升阅读体验和内容质量,如果你喜欢博主的文章,请点个赞或者关注博主支持一波,我会更加努力的为你呈现精彩的内容。
🌈专栏推荐
😈魔王的修炼之路–C语言
😈魔王的修炼之路–数据结构
😈魔王的修炼之路–C++
😈魔王的修炼之路–QT
😈魔王的修炼之路–算法
😈魔王的修炼之路–力扣
😈魔王的修炼之路–牛客
😈魔王的修炼之路–剑指offer
😈魔王的修炼之路–Linux
😈魔王的修炼之路–Computer vision
更新不易,希望得到友友的三连支持一波。收藏这篇文章,意味着你将永久拥有它,无论何时何地,都可以立即找到重新阅读;关注博主,意味着无论何时何地,博主将永久和你一起学习进步,为你带来有价值的内容。