【图像处理】——Python+opencv实现提取图像的几何特征(面积、周长、细长度、区间占空比、重心、不变矩等)
- 转载请注明详细地址
- 本文简单介绍了图像常见几何特征的概念以及求解方法
- 本文介绍了Python和opencv求解几何特征的常用方法
目录
其他形状外接轮廓的方法可以参考:《OpenCV-Python——第17.3章:轮廓形状拟合(边界矩形,最小外接圆...)及性质》
一、获得轮廓
二、面积
1、cv2.connectedComponentsWithStats()
stats参数解析
2、cv2.contourArea()函数
三、周长
1、cv2.arcLength(contours[0],True)
四、细长度
1、绘制外接矩形(cv2.rectangle()函数)
2、得到矩形的角点坐标和长宽cv2.boundingRect()函数
3、求解最小外接矩形(cv2.minAreaRect()函数)
4、绘制最小外接矩形:cv2.boxPoints()函数和cv2.polylines()函数
step1 角点坐标获得cv2.boxPoints()
step2 将角点坐标全部转换为整数
step3 依次连接起来cv2.polylines()
5、细长度的计算
五、区间占空比
六、重心
七、图像上添加文字cv2.putText()函数
八、完整代码
一、获得轮廓
在进行轮廓几何特征的提取之前,首先要做的就是得到轮廓,得到轮廓常用的函数有:
cv2.findcontours()
contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] )参数1:源图像参数2:轮廓的检索方式,这篇文章主要讲解这个参数参数3:一般用 cv.CHAIN_APPROX_SIMPLE,就表示用尽可能少的像素点表示轮廓contours:图像轮廓坐标,是一个列表hierarchy:[Next, Previous, First Child, Parent],文中有详细解释
具体可见:《【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)》
二、面积
一般指的是轮廓内所包含的所有像素的个数,但是为了方便计算加快计算的速度,一般会采样一种近似地方法去估算面积,常用的有将轮廓近似成一个多边形,然后进行求解,在Python—opencv中,有两种方式可以对轮廓面积进行求解
1、cv2.connectedComponentsWithStats()
具体看见:《【图像处理】——实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(connectedComponentsWithStats()函数和connectedComponents()函数)》
retval, labels, stats, centroids =
connectedComponentsWithStats(image, labels=None, stats=None, centroids=None, connectivity=None, ltype=None)
这个函数返回值stats中的最后一个元素就是轮廓区域的面积,通过提取可以得到
stats参数解析
stats参数是一个numpy数组,每一行代表一个轮廓,每一行固定为5个参数,依次是:
CC_STAT_LEFT 组件的左上角点像素点坐标的X位置
CC_STAT_TOP 组件的左上角点像素点坐标的Y位置
CC_STAT_WIDTH 组件外接矩形的宽度,计算方式为用每一个轮廓中最右边的点的x坐标减去最左边的点的x坐标
CC_STAT_HEIGHT 组件外接矩形的高度,计算方式为用每一个轮廓中最下边的点的y坐标减去最上边的点的y坐标
CC_STAT_AREA 当前连通组件的面积(像素单位),这里统计的是轮廓所包含的像素点的个数,不是外接矩形的面积
所以stats的shape为:mx5,m是轮廓的个数,第一个轮廓是背景轮廓,前两个参数为0,0
2、cv2.contourArea()函数
这个函数可以针对每一个轮廓求得近似的面积,返回的是一个常数
contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#面积1
area1 = cv2.contourArea(contours[0])
#面积2
_,labels,stats,centroids = cv2.connectedComponentsWithStats(binary)
area2 = stats[1][4]
三、周长
周长指的是轮廓的像素点总数,也常用各个像素点的中点连线的多边形长度进行度量,若是对角线方向则为根号2个像素格,否则为1个像素格长度
常用的函数为:
length = cv2.arcLength(contours[0],True)
1、cv2.arcLength(contours[0],True)
arcLength(contour, closed)
参数解析:
contour:轮廓点集
closed:表明轮廓是否封闭与否,TRUE则表示封闭,FALSE则表示非封闭
#周长
length = cv2.arcLength(contours[0],True)
四、细长度
细长度表征图像中待识别区域的紧凑性,它的计算是由待识别区域的最小外接矩形得到,该最小外接矩形长轴和短轴的比值即为区域的细长度,表达式如下:
1、绘制外接矩形(cv2.rectangle()函数)
这个函数的原理就是取轮廓点集最上面的点、最下面的点、最左边的点和最右边的点作为外接矩形的四个点的坐标,这个矩形不一定是最小外接矩形,其边与坐标轴平行或者垂直
img = rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)img:进行绘制矩形的图像pt1:矩形左上角角点坐标,是一个元组pt2:矩形右下角角点坐标,是一个元组color:绘制矩形的颜色,一般通过RGB的表示方式(R.G,B)thickness:绘制矩形的线宽,如果是负数,则将轮廓区域进行填充linetype:线型
rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2)
2、得到矩形的角点坐标和长宽cv2.boundingRect()函数
#得到外接矩形的左上角点坐标和长宽
x,y,h,w = cv2.boundingRect(contours[0])
3、求解最小外接矩形(cv2.minAreaRect()函数)
实际上求解最小外接矩形的方法就是将图像沿逆时针或者顺时针按照一定的度数进行旋转,每旋转一次,求解一次轮廓的外接矩形的面积,记录每次旋转的度数、左上角点坐标、矩形长宽,根据三角函数可以得到旋转后的角点坐标,等旋转完成一周后,取面积最小的即为最小外接矩形
img = minAreaRect(points)
points:就是轮廓的点集
返回的是:img = ((x,y),(h,w),α)
#返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
min_rect = cv2.minAreaRect(contours[0])
4、绘制最小外接矩形:cv2.boxPoints()函数和cv2.polylines()函数
要想在原图像中绘制出最小外接矩形,则需要知道矩形的四个角点坐标,这四个角点坐标实际上就是在旋转的时候记录后进行根据记录的角度和三角函数进行转换过来的,知道后通过绘制多边形的方法将点依次连接即可
step1 角点坐标获得cv2.boxPoints()
box = cv2.boxPoints(min_rect)#返回的是一个numpy矩阵
min_rect:是一个元组
返回的是由角点组成的numpy矩阵
step2 将角点坐标全部转换为整数
box = np.int0(box)#将其转换为整数,否则会报错
step3 依次连接起来cv2.polylines()
img = polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
参数解析:
img:绘制矩形的图像
pts:装有矩形角点的点阵(一般是由boxpoints()函数得到)
isClosed:指定绘制的矩形是否为封闭的,TRUE表示封闭
color:绘制矩形的线条的颜色,用元组表示
thickness:线宽
linetype:线型
返回参数:返回的是绘制后的图像
min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)
5、细长度的计算
直接利用得到的数据即可获得
#最小外接矩形
min_rect = cv2.minAreaRect(contours[0])#返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
#细长度
min_rect_h = min_rect[1][0]
min_rect_w = min_rect[1][1]
e = min_rect_h/min_rect_w
五、区间占空比
区间占空比指的是将轮廓区域的面积除以外接矩形的面积,这里的外接矩形一般指的是最小外接矩形
#区域占空比(轮廓区域面积除以最小外接矩形面积)
ee = area1/min_rect_area
六、重心
重心描述的是待识别区域的全局特性,反映的是区域内部像素点的分布。如果待识别区域是均匀的,密度设为1则区域的重心同时也是是区域的几何中心,它可通过计算所有像素点的平均值得到
七、图像上添加文字cv2.putText()函数
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
img:需要添加文字的图像
text:添加的文字内容,一定是字符串
org:相当于一个文本框的左上角点坐标
fontface:文字大小
fontscale:文字比例
color:文字颜色,以元组的形式表达
thickness:线宽
linetype:线型
text2 = "width:" + str(int(min_rect[1][1]))
cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)
八、完整代码
import cv2
import numpy as nprgb1 = cv2.imread('roi.png')
rgb2 = cv2.imread('roi.png')
rgb3 = cv2.imread('roi.png')img = cv2.imread('roi.png',0)
ret,binary = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#面积1
area1 = cv2.contourArea(contours[0])
#面积2
_,labels,stats,centroids = cv2.connectedComponentsWithStats(binary)
area2 = stats[1][4]#周长
length = cv2.arcLength(contours[0],True)#得到外接矩形的左上角点坐标和长宽
x,y,w,h = cv2.boundingRect(contours[0])#外接矩形
rect = cv2.rectangle(rgb1,(stats[1][0],stats[1][1]),(stats[1][0]+stats[1][2],stats[1][1]+stats[1][3]),(0,0,255),2)
rect_area = w*h#最小外接矩形
min_rect = cv2.minAreaRect(contours[0])#返回的是一个元组,第一个元素是左上角点坐标组成的元组,第二个元素是矩形宽高组成的元组,第三个是旋转的角度
# print(min_rect)((530.0443725585938, 113.73445892333984), (40.497230529785156, 137.21890258789062), -86.68222045898438)#获得最小外接矩形的四个角点坐标
box = cv2.boxPoints(min_rect)#返回的是一个numpy矩阵
min_rect_area = cv2.contourArea(box)#绘制最小外接矩形,通过多边形绘制的方法进行绘制
box = np.int0(box)#将其转换为整数,否则会报错
min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)#细长度
min_rect_h = min_rect[1][0]
min_rect_w = min_rect[1][1]
e = min_rect_h/min_rect_w#区域占空比(轮廓区域面积除以最小外接矩形面积)
ee = area1/min_rect_area#质心
centroid = centroids[0]text1 = 'height:'+ str(int(min_rect[1][0]))
text2 = "width:" + str(int(min_rect[1][1]))
cv2.putText(rgb1,text1, (10, 30), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)
cv2.putText(rgb1,text2, (10, 60), 3, 0.5, (0, 255, 0), 1, cv2.LINE_AA, 0)
cv2.imshow('rect',rect)
cv2.imshow('min_rect',min_rect_img)
cv2.imshow('rgb',rgb3)
cv2.waitKey(0)print(area1)
print(area2)
print(rect_area)
print(min_rect_area)
print(e)
print(ee)
print(centroid)
【图像处理】——Python+opencv实现提取图像的几何特征(面积、周长、细长度、区间占空比、重心、不变矩等)相关推荐
- Python Opencv cv2提取图像中某种特定颜色区域(例如黑字白纸背景下的红色公章提取),并将纯色背景透明化
拜拜PHOTOSHOP- 领导突然让我帮他把公章从图片中抠出来,在确保了不是要做坏事的情况下,我打开了PHOTOSHOP,用魔棒工具一点一点抠,但由于魔棒工具的原理是对比临近区域像素差值,导致封闭字体 ...
- Python+OpenCV:交互式图像前景提取(Interactive Foreground Extraction using GrabCut Algorithm)
Python+OpenCV:交互式图像前景提取(Interactive Foreground Extraction using GrabCut Algorithm) ################# ...
- 灰度拉伸python,Python OpenCV实例:图像灰度拉伸
Python OpenCV实例:图像灰度拉伸 Python OpenCV实例:图像灰度拉伸 为什么80%的码农都做不了架构师?>>> #coding:utf-8 ''' 灰度拉伸 定 ...
- 用python怎么样实现图像二值化_使用Python+OpenCV如何实现图像二值化
使用Python+OpenCV如何实现图像二值化 发布时间:2020-10-26 14:15:52 来源:亿速云 阅读:77 作者:蛋片鸡 这篇文章运用简单易懂的例子给大家介绍使用Python+Ope ...
- Python+OpenCV:立体图像深度图(Depth Map from Stereo Images)
Python+OpenCV:立体图像深度图(Depth Map from Stereo Images) 理论 If we have two images of same scene, we can g ...
- 使用Python+opencv+k-means根据扫描图片计算叶片面积-续
一 .概述 之前写了一篇计算叶片面积的文章,后来想想其实没有那么复杂,直接二值化计算即可得到,原来的代码写了几十行,其实十余行就可以计算得到叶片面积了. 原文:使用Python+opencv+k-me ...
- 【图像处理】——实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(connectedComponentsWithStats()函数和connectedComponents()函数)
目录 一.cv2.connectedComponents() 函数原型: 输入参数解析: 返回参数解析: 二.cv2.connectedComponentsWithStats() 函数原型: 输入参数 ...
- python opencv 腐蚀_opencv 图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算
原文链接:opencv 图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算 OpenCV---开闭操作 - 山上有风景 - 博客园 腐蚀 : 腐蚀操作会把前景物体的边缘腐蚀掉.原理是卷积 ...
- [图像处理] Python+OpenCV实现车牌区域识别及Sobel算子
由于最近太忙,这篇文章只给出相关代码供大家学习,过一段时间会详细的写一些列Python图像处理的文章,包括各种算法原理.图像识别.图像增强.图像分类.深度学习等.本篇文章主要调用OpenCV库(cv2 ...
最新文章
- Python标准库:内置函数tuple([iterable])
- mega_[MEGA DEAL] 2020年完整的Java Master Class Bundle(96%)
- 学习CSS了解单位em和px的区别
- StrickyAssignor 分配策略
- multinorm r语言_与心理学数据分析相关的R工具包
- Java开发常识资料
- React开发(164):React中this.props.children续集
- 兼容各种浏览器的自动左右滚动兼左右点击滚动代码
- Linux进阶之路————用户管理
- Nodejs服务器端处理POST提交的数据_note
- PHP memcached memcache 扩展安装
- Linux开放端口、关闭防火墙操作
- Android项目目录结构中各个文件夹的作用
- python数据结构教程_python入门基础教程随笔1-python数据结构-列表
- 开关电源matlab仿真文件,基于PI控制方式的7A开关电源的MATLAB仿真.doc
- 计算机无法搜索到打印机驱动,教你一招解决电脑无法找到打印机驱动程序包要求的核心驱动的问题 - 驱动管家...
- SSL双向认证和单向认证原理
- 398高校毕业设计选题
- 微信小程序中使用Less
- 使用minikube快速部署k8s集群