之前想用TensorFlow + OpenCV做目标检测,但是最后因为TF2.0资料属实不多所以夭折了,不过OpenCV还是非常值得学习的。
特征检测算法
OpenCV中比较常用的特征检测和提取算法:
- Harris:用于角点检测
- SIFT:用于斑点检测
- SERF:用于斑点检测
- FAST:用于角点检测
- BRIEF:用于斑点检测
- ORB:带方向的FAST算法和具有旋转不变性的BRIEF算法(暴力匹配和基于FLANN的匹配法)
特征
上述算法中提到了角点和斑点,这是两种重要的特征。特征是有意义的图像区域。
cornerHarris角点特征
Harris算法中认为,平坦区域在所有方向上都没有明显的梯度变化,边缘区域在某个方向上有明显的梯度变化,角度边缘则在各个方向都有明显的梯度变化。
下面用一张国际象棋的图片和cornerHarris演示角点识别
import cv2import numpy as npimg = cv2.imread('chess.jpg')gray1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#灰化,可以降低维度,将三通道变为一通道gray = np.float32(gray1)dst = cv2.cornerHarris(gray, 2, 15, 0.04)#参数依次为:输入图像,角点区域大小,求导使用的窗口大小,自由参数取值[0.04, 0.06]#其中第二个参数决定检测到的角点的大小,第三个参数决定检测的灵敏度,越小越灵敏,但必须是[3, 31]之间的奇数img[dst>0.01*dst.max()] = [0, 0, 255]#给角点上色方便观察while(True): cv2.imshow('pre', gray1) cv2.imshow('result', img) if cv2.waitKey(1) & 0xff == ord('q'): breakcv2.destroyAllWindows()
结果:
Shi-Tomas角点检测
Shi-Tomas是对Harris的改进算法
import cv2 import numpy as npimg = cv2.imread("chess.jpg")print(img.shape)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)corners = cv2.goodFeaturesToTrack(gray, 100, 0.05, 10)for pt in corners: x = np.int32(pt[0][0]) y = np.int32(pt[0][1]) cv2.circle(img, (x,y), 5, (0, 0, 255), 2) cv2.imshow('result', img)while(True): if cv2.waitKey(1) & 0xff == ord('q'): breakcv2.destroyAllWindows()
基于ORB的特征检测和特征匹配
ORB将FAST关键点和基于BRIEF描述符的技术相结合,有更快的检测速度
FAST
FAST算法会在像素周围绘制一个圆,包含16个像素。然后将每个像素与加上一个阈值的圆心像素进行比较,若有连续、比加上阈值的圆心像素更亮或暗的像素,则可认为圆心是角点的。
BRIEF
BRIEF不是特征检测算法,而是描述符。角点检测算法计算的结果实际上分为两部分,一个是角点的坐标,另一个是整幅图的特征(可以看成数的累积)而特征在OpenCV里称为描述符。
暴力匹配
暴力匹配是一种基本没有优化的特征匹配方法
代码实现
import numpy as np import cv2import matplotlib.pyplot as pltimg1 = cv2.imread('football.jpg', cv2.IMREAD_GRAYSCALE)img2 = cv2.imread('shoot.jpg', cv2.IMREAD_GRAYSCALE)orb = cv2.ORB_create() #创建检测器kp1, des1 = orb.detectAndCompute(img1, None) #计算特征值kp2, des2 = orb.detectAndCompute(img2, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) #匹配特征值matches = bf.match(des1, des2) #遍历描述符,计算匹配质量(距离)matches = sorted(matches, key=lambda x:x.distance) #排序img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:40], img2, flags=2) #显示匹配质量最高的前40个点plt.imshow(img3)plt.show()
效果:
来源:CSDN
作者:weixin_43874764
链接:https://blog.csdn.net/weixin_43874764/article/details/104328727