小白的树莓派Tensorflow opencv 学习笔记(八)

之前想用TensorFlow + OpenCV做目标检测,但是最后因为TF2.0资料属实不多所以夭折了,不过OpenCV还是非常值得学习的。

特征检测算法

OpenCV中比较常用的特征检测和提取算法:

  1. Harris:用于角点检测
  2. SIFT:用于斑点检测
  3. SERF:用于斑点检测
  4. FAST:用于角点检测
  5. BRIEF:用于斑点检测
  6. ORB:带方向的FAST算法和具有旋转不变性的BRIEF算法(暴力匹配和基于FLANN的匹配法)

特征

上述算法中提到了角点和斑点,这是两种重要的特征。特征是有意义的图像区域。

cornerHarris角点特征

Harris算法中认为,平坦区域在所有方向上都没有明显的梯度变化,边缘区域在某个方向上有明显的梯度变化,角度边缘则在各个方向都有明显的梯度变化。

下面用一张国际象棋的图片和cornerHarris演示角点识别

import cv2
import numpy as np

img = 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'):
        break
cv2.destroyAllWindows()

结果:
在这里插入图片描述
调节灵敏度可以得到效果更好的图像,cornerharris的检测效果与图像比例有关,图像越小越可能丢失角点

Shi-Tomas角点检测

Shi-Tomas是对Harris的改进算法

import cv2 
import numpy as np

img = 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'):
        break

cv2.destroyAllWindows()

在这里插入图片描述
cv2.goodFeaturesToTrack 参数:

  1. 单通道输入图像
  2. 最多返回的角点数量
  3. 灵敏度,越低失去的点越多
  4. 相邻角点间的最短距离

基于ORB的特征检测和特征匹配

ORB将FAST关键点和基于BRIEF描述符的技术相结合,有更快的检测速度

FAST

FAST算法会在像素周围绘制一个圆,包含16个像素。然后将每个像素与加上一个阈值的圆心像素进行比较,若有连续、比加上阈值的圆心像素更亮或暗的像素,则可认为圆心是角点的。

BRIEF

BRIEF不是特征检测算法,而是描述符。角点检测算法计算的结果实际上分为两部分,一个是角点的坐标,另一个是整幅图的特征(可以看成数的累积)而特征在OpenCV里称为描述符。

暴力匹配

暴力匹配是一种基本没有优化的特征匹配方法

代码实现
import numpy as np 
import cv2
import matplotlib.pyplot as plt

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

效果:
在这里插入图片描述

发布了25 篇原创文章 · 获赞 2 · 访问量 2103

猜你喜欢

转载自blog.csdn.net/weixin_43874764/article/details/104328727
今日推荐