harris与Shi-Tomas检测

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()

  • 21
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值