【图像处理】——Python+opencv实现提取图像的⼏何特征
(⾯积、周长、细长度、区间。。。
转载请注明详细地址
本⽂简单介绍了图像常见⼏何特征的概念以及求解⽅法
本⽂介绍了Python和opencv求解⼏何特征的常⽤⽅法
⽬录
其他形状外接轮廓的⽅法可以参考:
⼀、获得轮廓
在进⾏轮廓⼏何特征的提取之前,⾸先要做的就是得到轮廓,得到轮廓常⽤的函数有:
cv2.findcontours()
contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offt]]] )
参数1:源图像
参数2:轮廓的检索⽅式,这篇⽂章主要讲解这个参数
参数3:⼀般⽤ cv.CHAIN_APPROX_SIMPLE,就表⽰⽤尽可能少的像素点表⽰轮廓
contours:图像轮廓坐标,是⼀个列表
hierarchy:[Next, Previous, First Child, Parent],⽂中有详细解释
具体可见:
⼆、⾯积服装防盗
⼀般指的是轮廓内所包含的所有像素的个数,但是为了⽅便计算加快计算的速度,⼀般会采样⼀种近似地⽅法去估算⾯积,常⽤的有将轮廓近似成⼀个多边形,然后进⾏求解,在Python—opencv中,有两种⽅式可以对轮廓⾯积进⾏求解
1、tedComponentsWithStats()
具体看见:》
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
time is money2、urArea()函数
ultrasonic这个函数可以针对每⼀个轮廓求得近似的⾯积,返回的是⼀个常数
contours,layer_num = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#⾯积1
area1 = urArea(contours[0])
#⾯积2
_,labels,stats,centroids = tedComponentsWithStats(binary)
area2 = stats[1][4]
三、周长
周长指的是轮廓的像素点总数,也常⽤各个像素点的中点连线的多边形长度进⾏度量,若是对⾓线⽅向则为根号2个像素格,否则为1个像素格长度
常⽤的函数为:
length = cv2.arcLength(contours[0],True)
布尔什维克主义
1、cv2.arcLength(contours[0],True)
arcLength(contour, clod)
参数解析:
contour:轮廓点集
clod:表明轮廓是否封闭与否,TRUE则表⽰封闭,FALSE则表⽰⾮封闭
#周长
length = cv2.arcLength(contours[0],True)
四、细长度
细长度表征图像中待识别区域的紧凑性,它的计算是由待识别区域的最⼩外接矩形得到,该最⼩外接矩形长轴和短轴的⽐值即为区域的细长度,表达式如下:
1、绘制外接矩形(angle()函数)
这个函数的原理就是取轮廓点集最上⾯的点、最下⾯的点、最左边的点和最右边的点作为外接矩形的四个点的坐标,这个矩形不⼀定是最⼩外接矩形,其边与坐标轴平⾏或者垂直
img = rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
img:进⾏绘制矩形的图像
pt1:矩形左上⾓⾓点坐标,是⼀个元组
pt2:矩形右下⾓⾓点坐标,是⼀个元组
color:绘制矩形的颜⾊,⼀般通过RGB的表⽰⽅式(R.G,B)
thickness:绘制矩形的线宽,如果是负数,则将轮廓区域进⾏填充
linetype:线型
rect = angle(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, isClod, color, thickness=None, lineType=None, shift=None)
参数解析:
img:绘制矩形的图像
pts:装有矩形⾓点的点阵(⼀般是由boxpoints()函数得到)
isClod:指定绘制的矩形是否为封闭的,TRUE表⽰封闭
color:绘制矩形的线条的颜⾊,⽤元组表⽰
q
thickness:线宽
linetype:线型
返回参数:返回的是绘制后的图像
min_rect_img = cv2.polylines(rgb2,[box],True,(0,255,0),2)
5、细长度的计算
直接利⽤得到的数据即可获得
federalrerve
#最⼩外接矩形
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 np
rgb1 = 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