首页IT科技python获取图像轮廓(【OpenCV-Python】:查找物体轮廓+计算轮廓面积、长度、重心)

python获取图像轮廓(【OpenCV-Python】:查找物体轮廓+计算轮廓面积、长度、重心)

时间2025-08-01 08:50:07分类IT科技浏览4883
导读:✨博客主页:米开朗琪罗~🎈...

✨博客主页:米开朗琪罗~🎈

✨博主爱好:羽毛球🏸

✨年轻人要:Living for the moment(活在当下)!💪

🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】

😺一              、查找并绘制物体轮廓

🐶1.1 查找轮廓

🦄1.1.1 函数API

函数:img, contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])

参数介绍:

参数image:寻找轮廓的图像; 参数mode:表示轮廓的检索模式 cv2.RETR_EXTERNAL:只检测外轮廓 cv2.RETR_LIST:检测的轮廓不建立等级关系 cv2.RETR_CCOMP:建立两个等级的轮廓              ,上面的一层为外边界                     ,里面的一层为内孔的边界信息              。如果内孔内还有一个连通物体        ,这个物体的边界也在顶层                      。 cv2.RETR_TREE:建立一个等级树结构的轮廓       。 参数method:表示轮廓的近似方法: cv2.CHAIN_APPROX_NONE:存储所有的轮廓点, 相邻的两个点的像素位置差不超过1, 即max(abs(x1-x2), abs(y2-y1)) == 1 cv2.CHAIN_APPROX_SIMPLE:压缩水平方向       ,垂直方向                     ,对角线方向的元素               ,只保留该方向的终点坐标       ,例如一个矩形轮廓只需4个点来保存轮廓信息              。 cv2.CHAIN_APPROX_TC89_L1                     ,CV_CHAIN_APPROX_TC89_KCOS:用teh-Chinl chain 近似算法 返回值img:返回原图的灰度图; 返回值contour:返回一个列表               ,列表中包含了检测到的所有轮廓,每个轮廓用ndarray表示; 返回值hierarchy:这是一个ndarray                     ,其中的元素个数和轮廓个数相同                      ,每个轮廓contours[i]对应4个hierarchy元素,分别为hierarchy[i][0] ~hierarchy[i][3]              ,分别表示后一个轮廓                     、前一个轮廓        、父轮廓       、内嵌轮廓的索引编号                      ,如果没有对应项        ,则该值为负数                      。

https://blog.csdn.net/hjxu2016/article/details/77833336

🦄1.1.2 程序设计

注意:在查找物体轮廓之前要先对图像进行灰度化与二值化操作!

实验使用图像:

import cv2 import numpy as np original = cv2.imread(rC:\Users\Lenovo\Desktop\contour.jpg) print(original.shape) # 查找物体轮廓 def findcontour(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 图像灰度化 ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 图像二值化 image, contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 查找物体轮廓 return image, contours, hierarchy image, contours, hierarchy = findcontour(original)

我们打印轮廓数量:

print(轮廓数:, len(contours))

得到:轮廓数: 3

注意:findcontours函数会“原地              ”修改输入的图像!!!

🐶1.2 绘制轮廓

🦄1.2.1 函数API

函数:img = cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)

参数介绍:

参数image:要绘制轮廓的图像              ,必须是三通道; 参数contours:表示轮廓本身                     ,存储方式为list; 参数contourIdx:轮廓索引        ,表示要绘制哪条轮廓       ,若为-1                     ,则绘制所有轮廓; 返回值img:绘制完轮廓的图像       。

🦄1.2.2 全部轮廓绘制程序设计及结果可视化

contours = cv2.drawContours(original, contours, -1, (255, 0, 0), 5) # 绘制所有轮廓 cv2.imshow("contour", contours) cv2.waitKey()

所有轮廓绘制的结果如下:

🦄1.2.2 逐个轮廓绘制程序设计及结果可视化

nums = len(contours) color = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] contourssplit=[] for i in range(nums): temp = np.zeros(original.shape, np.uint8) contourssplit.append(temp) contourssplit[i] = cv2.drawContours(contourssplit[i], contours, i, color[i], 2) cv2.imwrite(rC:\\Users\\Lenovo\\Desktop\\%d.jpg % i, contourssplit[i]) cv2.imshow("contours" + str(i), contourssplit[i]) cv2.waitKey()

逐个轮廓绘制的结果如下:

🐶1.3 统计轮廓信息

🦄1.3.1 函数API

计算轮廓面积

函数:area= cv2.contourArea(contour               ,oriented)

参数介绍:

参数contour:轮廓信息; 参数oriented:有方向的区域标志 true:此函数依赖轮廓的方向(顺时针或逆时针)返回一个已标记区域的值       。 false:默认值                      。意味着返回不带方向的绝对值              。

该函数有个缺点:由于其计算方式是利用格林公式计算轮廓面积       ,所以如果遇到具有自交点的轮廓                     ,该函数会给出错误的结果       。

统计轮廓信息

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️重点

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

函数:moment = cv2.moments(contour)

参数介绍:

参数contour:轮廓信息; 参数moment:图像的矩                      。

函数返回一个字典               ,你可以从中得到有关轮廓的各种信息,包括面积                     、重心等!

计算轮廓周长

函数:perimeter=cv2.arcLength(contour, closed)

参数介绍:

参数contour:轮廓信息; 参数closed:用于指示轮廓是否封闭              。 True:轮廓封闭。 False:轮廓不封闭                      。

🦄1.3.2 程序设计

我们先看cv2.moments中的信息                     ,使用debug看a中的数据:

a是一个具有24个键值对的字典                      ,包含了轮廓的各个信息                      。

使用cv2.moments(contours[i])[m00]得到轮廓面积;

使用int(cv2.moments(contours[i])[m10]/cv2.moments(contours[i])[m00])和

int(cv2.moments(contours[i])[m01]/cv2.moments(contours[i])[m00])得到轮廓重心;

使用cv2.arcLength(contours[i], True)得到轮廓的长度。

nums = len(contours) color = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] contourssplit=[] for i in range(nums): temp = np.zeros(original.shape, np.uint8) contourssplit.append(temp) contourssplit[i] = cv2.drawContours(contourssplit[i], contours, i, color[i], 2) a = cv2.moments(contours[i]) print("轮廓" + str(i) + "的面积:%d" % cv2.moments(contours[i])[m00]) print("轮廓" + str(i) + "的重心:%d" % int(cv2.moments(contours[i])[m10]/cv2.moments(contours[i])[m00]), int(cv2.moments(contours[i])[m01]/cv2.moments(contours[i])[m00])) print("轮廓" + str(i) + "的长度:%d" % cv2.arcLength(contours[i], True))

结果如下:

轮廓0的面积:3214 轮廓0的重心:69 199 轮廓0的长度:403 轮廓1的面积:4752 轮廓1的重心:202 142 轮廓1的长度:336 轮廓2的面积:8019 轮廓2的重心:69 67 轮廓2的长度:336
声明:本站所有文章,如无特殊说明或标注              ,均为本站原创发布              。任何个人或组织                      ,在未征得本站同意时        ,禁止复制               、盗用       、采集                     、发布本站内容到任何网站               、书籍等各类媒体平台                      。如若本站内容侵犯了原著者的合法权益              ,可联系我们进行处理       。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
轨迹球是啥(轨迹球_百度百科) wordpress上传产品没有价格选项(WordPress发布产品——助力企业网站建设的最佳选择)