1.边界矩形
旋转边角矩形:这个边界矩形是面积最小的,他考虑了对象的旋转。用函数cv2.minAreRect(),返回的是一个Box2D结构,其中包含矩形左上角点的坐标(x,y),以及矩形的宽和高(w,h),以及旋转角度。但是要绘制这个矩形需要矩形的4个交点。可以通过cv2.boxPoints()获得。
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('bianjie.jpg')
imgray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.转化为二值图
ret,thresh=cv.threshold(imgray,127,255,0)
#3.轮廓提取
contours,hierarchy=cv.findContours(thresh,1,2)
#4.将轮廓绘制在图像上
#img=cv.drawContours(img,contours,1,(0,255,0),3)
cnt=contours[1]
#5.边界矩形
#5.1直边界矩形
x,y,w,h=cv.boundingRect(cnt)
img=cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3)
#5.2旋转边界矩形结果
s=cv.minAreaRect(cnt)
a=cv.boxPoints(s)
a=np.int0(a) #转换a的类型为int型
cv.polylines(img,[a],True,(0,0,255),3)
#6图像显示
#图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('矩形结果')
plt.xticks([]),plt.yticks([])
plt.show()
2.最小外接圆
使用函数cv2.minEnclosingCircle()获取最小外接圆
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('bianjie.jpg')
imgray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.转化为二值图
ret,thresh=cv.threshold(imgray,127,255,0)
#3.轮廓提取
contours,hierarchy=cv.findContours(thresh,1,2)
#4.将轮廓绘制在图像上
#img=cv.drawContours(img,contours,1,(0,255,0),3)
cnt=contours[0]
(x,y),r=cv.minEnclosingCircle(cnt)
center=(int(x),int(y))
r=int(r)
imgcircle=cv.circle(img,center,r,(0,255,0),3)
plt.imshow(imgcircle[:,:,::-1])
plt.show()
3.椭圆拟合
椭圆拟合的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中一组数据以椭圆方程为模型进行拟合,使某一椭圆方程尽量满足这些数据,并求出该椭圆方程的各个参数。
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('bianjie.jpg')
imgray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.转化为二值图
ret,thresh=cv.threshold(imgray,127,255,0)
#3.轮廓提取
contours,hierarchy=cv.findContours(thresh,1,2)
#4.将轮廓绘制在图像上
#img=cv.drawContours(img,contours,1,(0,255,0),3)
cnt=contours[0]
ellipse=cv.fitEllipse(cnt)
imgellipse=cv.ellipse(img,ellipse,(0,255,255),3)
plt.imshow(imgellipse[:,:,::-1])
plt.show()
4.直线拟合
直线拟合就是将图像中的对象拟合一条直线过程,在opencv中拟合直线的API是;
output=cv2.fitLine(points,distType,param,reps,aeps)
参数;
-points:待拟合直线的点的集合,可以是检测处理轮廓结果
-distype:距离公式,在进行拟合时,要使输入点到拟合直线的距离之和最小,常用的以下几种:
cv2.DIST_L1:曼哈顿距离
cv2.DIST_L2:欧式距离
cv2.DIST_C:切比雪夫距离
-param:距离参数,可以设为0
-Reps,aeps:用于表示拟合曲线所需要的径向和角度精度,通常设为0.01
返回:
-output:[vx,vy,x,y]的1*4的数组,前两个表示直线的方向,及vy/vx表示斜率,后两位表示直线上的一个点。
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('bianjie.jpg')
imgray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.转化为二值图
ret,thresh=cv.threshold(imgray,127,255,0)
#3.轮廓提取
contours,hierarchy=cv.findContours(thresh,1,2)
#4.将轮廓绘制在图像上
#img=cv.drawContours(img,contours,1,(0,255,0),3)
cnt=contours[0]
[vx,vy,x,y]=cv.fitLine(cnt,cv.DIST_L2,0,0.01,0.01)
rows,cols=img.shape[:2]
lefty=int((-x*vy/vx)+y)
righty=int(((cols-x)*vy/vx)+y)
imgline=cv.line(img,(0,lefty),(cols-1,righty),(0,0,255),3)
plt.imshow(imgline[:,:,::-1])
plt.show()
5.图像的矩特征
在opencv中有直接计算图像矩的API,分为两个函数:moments()函数用于计算中心矩,HuMoments函数用于中心距计算Hu矩
moments(array,binaryImage=false)
参数:
-array:输入数组,也可以是灰度图像,也可以是二维数组,例如提取的轮廓结果
-BinaryImage:默认是false,若为True,则所有非零的像素都会按值1对待,也就是说相当于对图像进行了二值化处理,阈值为1,此参数仅对图像有效。
返回:
-moment:返回数组的中心矩
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('bianjie.jpg')
imgray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.计算图像的Hu矩
imgmn=cv.moments(imgray)
imghu=cv.HuMoments(imgmn)
#3.计算轮廓的Hu矩
#3.1转换为二值图
ret,thresh=cv.threshold(imgray,127,255,0)
#3.2轮廓提取
image,contours,hierarchy=cv.findContours(thresh,1,2)
#3.3计算轮廓的Hu矩
cnt=contours[1]
mn=cv.moments(cnt)
hu=cv.HuMoments(mn)
print('Hu矩结果\n',hu)
总结
1.图像的轮廓
轮廓是图像目标的外部特征,是具有相同的颜色或者灰度的连续点连成的曲线
查找轮廓:cv.findContours()
注意:轮廓的检索方式,近似方式以及轮廓的层次
绘制轮廓:cv.drawContours()
2.轮廓的特征
面积:ContourArea()
周长:ArcLength()
轮廓近似:approxPolyDP()逼近图像的多边曲线
凸包:ConvexHull()
边界矩形:BoundingRect()和MinAreaRect()
最小外接圆:MinEnclosingCircle()
椭圆拟合:fitEllipse()
直线拟合:fitline()
3.图像的矩特征
矩是统计与概率中的概念
在图像中的应用:空间矩,中心矩,Hu矩
API:moments()
6.角点特征
总结
1.图像特征
图像特征要有区分性,容易被比较。一般认为角点,斑点等是较好的图像特征
特征检测:找到图像中的特征
特征描述:对特征及其周围的区域进行描述
7.Harris角点检测
7.1原理
Harris角点检测的思想是通过图像的局部的小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化,如下图所示:
7.2实现
在opencv中实现Hariis检测使用的API是:
dst=cv.cornerHarris(src,blockSize,ksize,k)
参数:
-img:数据类型为float32的输入图像
-blockSize:角点检测中要考虑的领域大小
-ksize:sobel求导使用的核大小
-k:角点检测方程中的自由参数,取值参数为[0.04,0.06]
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.读取图像,并转换为灰度图像
img=cv.imread('harris.jpg')
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.角点检测
#2.1输入图像必须是float32
gray=np.float32(gray)
#2.2最后一个参数在0.04到0.05之间
dst=cv.cornerHarris(gray,2,3,0.04)
#3.设置阈值,将角点绘制出来,阈值根据图像进行选择
img[dst>0.001*dst.max()]=[0,255,0]
#图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('Harris角点检测')
plt.xticks([]),plt.yticks([])
plt.show()
Harris角点检测的优缺点:
优点:
-旋转不变性,椭圆转过一定角度但是其形状保持不变(特征值保持不变)
-对于图像灰度的仿射变化具有部分的不变性,由于仅仅使用了图像的一介导数,对于图像灰度平移变化不变;对于图像灰度尺度变化不变
缺点:
-对尺度很敏感,不具备几何尺度不变性
-提取的角点是像素级的
8.Shi-Tomasi角点检测算法
8.1原理
Shi-Tomasi算法是对Harris角点检测算法的改进,一般会比Harris算法得到更好的角点。Harris算法的角点响应函数是将矩阵M的行列式值与M的迹相减,利用差值判断是否为角点。后来Shi和Tomasi提出改进的方法是,若矩阵M的两个特征值中较小的一个大于阈值,则认为它是角点。
8.2实现
在opencv中实现Shi-Tomasi角点检测使用的API:
corners=cv2.goodFeaturesToTrack(image,maxcorners,qualityLevel,minDistance)
参数:
-image:输入灰度图像
-maxCorners:获取角点数的数目
-qualityLevel:该参数指出最低可接收的角点质量水平,在0-1之间
-minDistance:角点之间最小的欧式距离,避免得到相邻特征点
返回:
-Corners:搜索到的角点,在这里所有低于质量水平的角点被排除掉,然后把合格的角点按质量排序,然后将质量较好的角点附近(小于欧式距离)的角点删掉,最后找到maxCorners个角点返回
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.读取图像
img=cv.imread('shi-tomas.jpg')
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.角点检测
corners=cv.goodFeaturesToTrack(gray,1000,0.01,10)
#3.绘制角点
for i in corners:
x,y=i.ravel()
x = int(x)
y = int(y)
cv.circle(img, (x, y), 2, (0, 0, 255), -1)
#图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('shi-tomasi角点检测')
plt.xticks([]),plt.yticks([])
plt.show()
总结
1.Harris算法
思想:通过图像的局部的小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化。
API:cv.cornerHarris()
2.Shi-Tomasi算法
对Harris算法的改进,能够更好地检测角点
API:cv2.goodFeatureToTrack()