建设银行 成都 招聘网站,百度网盘app官网,网站正在建设 敬请期待,微信登录 网站开发2. 轮廓特征 轮廓特征是指由轮廓形状和结构衍生出来的一些特征参数。这些特征参数可以用于图像识别、目标检测和形状分析等应用中。常见的轮廓特征包括#xff1a;
面积#xff1a;轮廓所包围的区域的面积。周长#xff1a;轮廓的周长#xff0c;即轮廓线的长度。弧长
面积轮廓所包围的区域的面积。周长轮廓的周长即轮廓线的长度。弧长轮廓线的弧长即轮廓的长度。轮廓矩轮廓的几何矩用于描述轮廓的形状。轮廓重心轮廓所包围区域的重心坐标。外接矩形能够完全包围轮廓的矩形。最小外接矩形能够紧密包围轮廓的矩形且角度与轮廓的方向一致。外接圆能够完全包围轮廓的圆。最小外接圆能够紧密包围轮廓的圆。椭圆拟合能够最好地拟合轮廓的椭圆。凸包能够包围轮廓的最小凸多边形。轮廓层级描述轮廓的嵌套关系。
这些轮廓特征可以通过OpenCV库的cv2.contourArea()、cv2.arcLength()、cv2.moments()、cv2.boundingRect()、cv2.minAreaRect()、cv2.minEnclosingCircle()、cv2.fitEllipse()、cv2.convexHull()等函数来计算和获取下面主要介绍一些常用的特征。
2.1 目标 查找轮廓的不同特征例如面积、周长、重心、边界框等。 学习和掌握轮廓相关函数
2.2 矩特征 图像矩是一种描述图像几何特征的数学工具用于描述图像的形状、位置和分布等信息以帮助我们计算图像的质心、面积等。图像矩可以用于图像识别、目标检测、形状分析等应用中。图像矩的计算是基于图像像素的灰度值进行的常见的图像矩包括原点矩、中心矩和归一化矩。使用OpenCV库的cv2.moments()函数可以计算图像的矩。该函数接受一个二值化的图像作为输入并返回一个包含各种矩的字典。可以通过字典的键来获取不同的矩。以下是一个示例代码演示如何计算图像的矩
import cv2# 读取图像
image cv2.imread(image.jpg)# 灰度化
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 计算矩
moments cv2.moments(thresh)# 获取原点矩
m00 moments[m00]
m10 moments[m10]
m01 moments[m01]# 获取中心矩
cx int(m10 / m00)
cy int(m01 / m00)# 获取归一化矩
nu20 moments[nu20]
nu02 moments[nu02]
nu11 moments[nu11]# 打印矩的值
print(m00:, m00)
print(m10:, m10)
print(m01:, m01)
print(cx:, cx)
print(cy:, cy)
print(nu20:, nu20)
print(nu02:, nu02)
print(nu11:, nu11)上述代码中首先读取了一张图像并对其进行了灰度化和二值化处理。然后使用cv2.moments()函数计算了图像的矩。通过字典的键可以获取不同的矩的值。在示例代码中获取了原点矩的值m00、m10和m01、中心矩的值cx和cy以及归一化矩的值nu20、nu02和nu11。最后打印了这些矩的值。需要注意的是图像矩对图像的形状和位置非常敏感因此在计算图像矩之前需要对图像进行预处理如灰度化、二值化等。
注意根据这些矩的值我们可以计算出对象的重心 cx int(M[m10]/M[m00])
cy int(M[m01]/M[m00])
2.3 轮廓面积 轮廓面积是指闭合轮廓所包围的区域的面积可以用来描述对象的大小。在OpenCV中可以使用cv2.contourArea()函数计算轮廓的面积也可以使用0阶矩(M[m00])计算得到。
area cv2.contourArea(cnt)
cv2.contourArea()函数接受一个轮廓作为输入并返回轮廓的面积。该函数的语法如下
area cv2.contourArea(contour)其中contour是一个包含轮廓点的数组。可以通过cv2.findContours()函数找到图像中的轮廓并提取其中的某个轮廓来计算面积。以下是一个示例代码演示如何计算轮廓的面积
import cv2# 读取图像
image cv2.imread(image.jpg)# 灰度化
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 计算轮廓面积area cv2.contourArea(contour)# 打印轮廓面积print(Contour area:, area)在上述代码中首先读取了一张图像并对其进行了灰度化和二值化处理。然后使用cv2.findContours()函数找到图像中的轮廓。返回的contours是一个包含所有轮廓的列表。接下来遍历轮廓列表并使用cv2.contourArea()函数计算每个轮廓的面积。最后打印了每个轮廓的面积。需要注意的是cv2.contourArea()函数计算的是轮廓的面积而不是对象的实际面积。因此在使用该函数之前需要对图像进行预处理如灰度化、二值化等以确保轮廓能够正确识别。
2.4 轮廓周长 轮廓周长是指闭合轮廓的长度可以用来描述对象的形状。在OpenCV中可以使用cv2.arcLength()函数计算轮廓的周长。cv2.arcLength()函数接受一个轮廓作为输入并返回轮廓的周长。该函数的语法如下
perimeter cv2.arcLength(contour, closed)其中contour是一个包含轮廓点的数组closed是一个布尔值指示轮廓是否是闭合的。如果轮廓是闭合的则closed为True如果轮廓是开放的则closed为False。以下是一个示例代码演示如何计算轮廓的周长
import cv2# 读取图像
image cv2.imread(image.jpg)# 灰度化
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 计算轮廓周长perimeter cv2.arcLength(contour, True)# 打印轮廓周长print(Contour perimeter:, perimeter)在上述代码中首先读取了一张图像并对其进行了灰度化和二值化处理。然后使用cv2.findContours()函数找到图像中的轮廓。返回的contours是一个包含所有轮廓的列表。接下来遍历轮廓列表并使用cv2.arcLength()函数计算每个轮廓的周长。最后打印了每个轮廓的周长。需要注意的是cv2.arcLength()函数计算的是轮廓的周长而不是对象的周长。因此在使用该函数之前需要对图像进行预处理如灰度化、二值化等以确保轮廓能够正确识别。
2.5 轮廓近似 在OpenCV中可以使用cv2.approxPolyDP()函数对轮廓进行近似处理。轮廓近似可以将复杂的轮廓形状简化为更简单的几何形状如直线或曲线。cv2.approxPolyDP()函数接受一个轮廓作为输入并返回一个近似的轮廓。该函数的语法如下
approx cv2.approxPolyDP(curve, epsilon, closed)其中curve是一个包含轮廓点的数组epsilon是指定近似精度的参数closed是一个布尔值指示轮廓是否是闭合的。如果轮廓是闭合的则closed为True如果轮廓是开放的则closed为False。将轮廓形状近似到另外一种由更少点组成的轮廓形状新轮廓的点的数目由我们设定的准确度来决定。实现这一功能主要使用的是Douglas-Peucker算法(你可以到维基百科获得更多此算法的细节)。为了帮助理解假设我们需要在一幅图像中查找一个矩形但是由于图像的种种原因我们不能得到一个完美的矩形而是一个(坏形状),如下图所示: 现在就可以使用这个函数来近似这个形状了。这个函数的第二个参数叫epsilon它是从原始轮廓到近似轮廓的最大距离。它是一个准确度参数。选择一个好的epsilon 对于得到满意结果非常重要。
epsilon 0.1*cv2.arcLength(cnt,True)
approx cv2.approxPolyDP(cnt,epsilon,True)
下面第二幅图中的绿线是当epsilon 10% 时得到近似轮廓第三幅图是当epsilon 1% 时得到的近似轮廓。第三个参数设定弧线是否闭合。 以下是一个示例代码演示如何对轮廓进行近似处理
import cv2# 读取图像
image cv2.imread(image.jpg)# 灰度化
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 近似轮廓epsilon 0.01 * cv2.arcLength(contour, True)approx cv2.approxPolyDP(contour, epsilon, True)# 绘制近似轮廓cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)在上述代码中首先读取了一张图像并对其进行了灰度化和二值化处理。然后使用cv2.findContours()函数找到图像中的轮廓。返回的contours是一个包含所有轮廓的列表。接下来遍历轮廓列表并使用cv2.arcLength()函数计算每个轮廓的周长。然后根据周长计算一个近似精度epsilon并使用cv2.approxPolyDP()函数对轮廓近似处理。最后使用cv2.drawContours()函数绘制近似轮廓。需要注意的是轮廓近似处理是一种对轮廓进行简化的方法可以减少轮廓点的数量从而降低计算的复杂性。但近似精度epsilon的选择需要根据具体情况进行调整过大的epsilon会导致近似结果不准确而过小的epsilon会导致近似结果过于复杂。因此在使用cv2.approxPolyDP()函数进行轮廓近似处理时需要根据实际情况选择合适的epsilon值。
2.6 凸包 在计算机视觉中凸包Convex Hull是指一个包围一组点的最小凸多边形。凸多边形是一个所有内角均小于180度的多边形。凸包与轮廓近似相似但不同然有些情况下它们给出的结果是一样的。OpenCV中提供了cv2.convexHull()函数来计算给定点集的凸包同时检测一个曲线是否具有凸性缺陷并能纠正缺陷。一般来说凸性曲线总是凸出来的或者至少是平的。如果有地方凹下去了就叫做凸性缺陷。例如下图中的手。红色曲线显示了手的凸包凸性缺陷被双箭头标出来了。 关该cv2.convexHull()函数的语法如下
hull cv2.convexHull(points, clockwise, returnPoints)其中points是一个包含点集的数组clockwise是一个布尔值用于指定凸包的顺序如果为True则返回的凸包按顺时针方向排序如果为False则返回的凸包按逆时针方向排序returnPoints是一个布尔值用于指定返回的凸包是点的坐标还是索引默认为True表示返回点的坐标。
要获得上图的凸包下面的命令就够了
hull cv2.convexHull(cnt)
但是如果你想获得凸性缺陷需要把returnPoints 设置为False。以上面的矩形为例首先我们找到他的轮廓cnt。现在我把returnPoints 设置为True 查找凸包我得到下列值
[[[234 202]], [[ 51 202]], [[ 51 79]], [[234 79]]]其实就是矩形的四个角点。现在把returnPoints 设置为False我得到的结果是[[129],[ 67],[ 0],[142]]他们是轮廓点的索引。例如cnt[129] [[234, 202]]这与前面我们得到结果的第一个值是一样的。
以下是一个示例代码演示如何使用cv2.convexHull()函数计算凸包
import cv2
import numpy as np# 创建一组点
points np.array([[10, 10], [10, 100], [100, 10], [100, 100], [50, 50]])# 计算凸包
hull cv2.convexHull(points)# 绘制凸包
image np.zeros((200, 200, 3), dtypenp.uint8)
cv2.polylines(image, [hull], True, (0, 255, 0), 2)# 显示图像
cv2.imshow(Convex Hull, image)
cv2.waitKey(0)
cv2.destroyAllWindows()在上述代码中首先创建了一个包含5个点的数组points。然后使用cv2.convexHull()函数计算凸包并将结果保存在hull中。接下来创建一个空白图像image并使用cv2.polylines()函数绘制凸包。最后显示图像。
需要注意的是cv2.convexHull()函数返回的凸包是一个包含点的数组可以通过cv2.polylines()函数绘制凸包。另外可以使用cv2.isContourConvex()函数检查一个轮廓是否是凸的。如果返回True则表示轮廓是凸的如果返回False则表示轮廓是非凸的。凸包在计算机视觉中有广泛的应用如图像分割、形状匹配等。凸包可以帮助我们简化复杂的形状并提取出形状的关键特征。
2.7 凸性检测 函数cv2.isContourConvex() 可以可以用来检测一个曲线是不是凸的。它只能返回True 或False。没什么大不了的。
k cv2.isContourConvex(cnt)
2.8 边界矩形 通常有两类边界矩形:直边界矩形、旋转边界矩形。
直边界矩形 一个直矩形(就是没有旋转的矩形)。它不会考虑对象是否旋转。所以直边界矩形的面积不是最小的。可以使用函数cv2.boundingRect() 查找得到。(x,y)为矩形左上角的坐标w,h)是矩形的宽和高。
x,y,w,h cv2.boundingRect(cnt)
img cv2.rectangle(img,(x,y),(xw,yh),(0,255,0),2)
旋转边界矩形 这个边界矩形是积最小的因为它考虑了对象的旋转。用到的函数为cv2.minAreaRect()。返回的是一个Box2D 结构其中包含矩形左上角角点的坐标(x,y),矩形的宽和高w,h以及旋转角度。但是要绘制这个矩形需要矩形的4 个顶点可以通过函数cv2.boxPoints() 获得。
x,y,w,h cv2.boundingRect(cnt)
img cv2.rectangle(img,(x,y),(xw,yh),(0,255,0),2)
把这两中边界矩形显示在下图中其中绿色的为直矩形红的为旋转矩形。 2.9 最小外接圆 函数cv2.minEnclosingCircle() 可以帮我们找到一个对象的外接圆。它是所有能够包括对象的圆中面积最小的一个。
(x,y),radius cv2.minEnclosingCircle(cnt)
center (int(x),int(y))
radius int(radius)
img cv2.circle(img,center,radius,(0,255,0),2) 2.10 椭圆拟合 使用的函数为cv2.ellipse()返回值其实就是旋转边界矩形的内切圆。
ellipse cv2.fitEllipse(cnt)
im cv2.ellipse(im,ellipse,(0,255,0),2) 2.11 直线拟合 我们可以根据一组点拟合出一条直线同样我们也可以为图像中的白色点拟合出一条直线。
rows,cols img.shape[:2]
[vx,vy,x,y] cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty int((-x*vy/vx) y)
righty int(((cols-x)*vy/vx)y)
img cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)