Python使用Opencv实现图像特征检测与匹配的方法

论坛 期权论坛 脚本     
niminba   2021-5-23 03:16   1244   0

特征检测是计算机对一张图像中最为明显的特征进行识别检测并将其勾画出来。大多数特征检测都会涉及图像的角点、边和斑点的识别、或者是物体的对称轴。

角点检测 是由Opencv的cornerHarris函数实现,其他函数参数说明如下:

cv2.cornerHarris(src=gray, blockSize=9, ksize=23, k=0.04)
# cornerHarris参数:
# src - 数据类型为 float32 的输入图像。
# blockSize - 角点检测中要考虑的领域大小。
# ksize - Sobel 求导中使用的窗口大小
# k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06].

以国际象棋为例,这是计算机视觉最为常见的分析对象,如图所示:

这里写图片描述

角点检测代码如下:

import cv2
import numpy as np

img = cv2.imread('chess_board.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cornerHarris函数图像格式为 float32 ,因此需要将图像转换 float32 类型
gray = np.float32(gray)
# cornerHarris参数:
# src - 数据类型为 float32 的输入图像。
# blockSize - 角点检测中要考虑的领域大小。
# ksize - Sobel 求导中使用的窗口大小
# k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06].
dst = cv2.cornerHarris(src=gray, blockSize=9, ksize=23, k=0.04)
# 变量a的阈值为0.01 * dst.max(),如果dst的图像值大于阈值,那么该图像的像素点设为True,否则为False
# 将图片每个像素点根据变量a的True和False进行赋值处理,赋值处理是将图像角点勾画出来
a = dst>0.01 * dst.max()
img[a] = [0, 0, 255]
# 显示图像
while (True):
 cv2.imshow('corners', img)
 if cv2.waitKey(120) & 0xff == ord("q"):
  break
 cv2.destroyAllWindows()

运行代码,结果如图所示:

这里写图片描述

但有时候,图像的像素大小对角点存在一定的影响。比如图像越小,角点看上去趋向近似一条直线,这样很容易造成角点的丢失。如果按照上述的检测方法,会造成角点检测结果不相符,因此引入DoG和SIFT算法进行检测Opencv的SIFT类是DoG和SIFT算法组合。

DoG是对同一图像使用不同高斯滤波器所得的结果。

SIFT是通过一个特征向量来描述关键点周围区域的情况。

我们以下图为例:

这里写图片描述

import cv2
# 读取图片并灰度处理
imgpath = 'varese.jpg'
img = cv2.imread(imgpath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建SIFT对象
sift = cv2.xfeatures2d.SIFT_create()
# 将图片进行SURF计算,并找出角点keypoints,keypoints是检测关键点
# descriptor是描述符,这是图像一种表示方式,可以比较两个图像的关键点描述符,可作为特征匹配的一种方法。
keypoints, descriptor = sift.detectAndCompute(gray, None)

# cv2.drawKeypoints() 函数主要包含五个参数:
# image: 原始图片
# keypoints:从原图中获得的关键点,这也是画图时所用到的数据
# outputimage:输出
# color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
# flags:绘图功能的标识设置,标识如下:
# cv2.DRAW_MATCHES_FLAGS_DEFAULT 默认值
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
# cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
# cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
img = cv2.drawKeypoints(image=img, outImage=img, keypoints = keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT, color = (51, 163, 236))

# 显示图片
cv2.imshow('sift_keypoints', img)
while (True):
 if cv2.waitKey(120) & 0xff == ord("q"):
  break
cv2.destroyAllWindows()

运行代码,结果如图所示:

这里写图片描述

除了SIFT算法检测之外,还有SURF特征检测算法,比SIFT算法快,并吸收了SIFT算法的思想。SURF采用Hessian算法检测关键点,而SURF是提取特征,这个与SIFT很像。Opencv的SURF类是Hessian算法和SURF算法组合。我们根据SIFT的代码进行修改,代码如下:

import cv2
# 读取图片并灰度处理
imgpath = 'varese.jpg'
img = cv2.imread(imgpath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建SURF对象,对象参数float(4000)为阈值,阈值越高,识别的特征越小。
sift = cv2.xfeatures2d.SURF_create(float(4000))
# 将图片还][\BBYX]W\\\NB[\HB
\]\[Y\[[[Y\[\NB[\˙^[
[[[Y\B[[\BY	[BW\\\X]\\X]J
JCBBYW\\\[XY]X]\W]XNBb)9yfa)..y/9o#Y[XY][]
HNB]\B+anyoCB[YH[\XY
\[XY]
K
CB\\\HX]\W]X]X[\]J[YJCB+#ynml!oyl9k/f9b,y\\[HH[XY]\XHCBJ\\\[JK\\BBY[YWOIZ[B]H	[BX]W\\]
OOB]B/c9. {9if﹢`9BB[OH^X[Y\[Y[H/yfaZZ[Z[[^][KNKY
MMY
BB[OH^X[YY$y.!fanyoyl9k/f9g*y ."iy+kf.#/yl9kc9c.zac{.#9oa 9/lcyfa ykf9g*X][{B]\HHBH\H\NB][\B[\[\[\H\B[\BB]Y\HH[\XY
	]YY
CB\H	[B\\HB#nyoyl9k#CB
\]\[Y\[[[Y\[\NB[[[[Y\BY[]
HNB\\\[
CB[
\\BB/oQ99alyd9)BHX]\\X]J
CB]Y\W]Y\WH]X[\]J]Y\KJCBBb&Sc.zacyfjB[^\[\HX[]OLY\JCB\\[\HXXL
CB[H[\X]\[^\[\\\[\BB[X[[]HB[\\Bl!fY\y.#oyl9k9l9k/c9c.zacCBX]\H[X]]Y\W
\
JKCB!zfi:e&z+.zacCBHBK[X]\BYK\[	\[B\[
JCB/(9fa!a.zacyl9B[
[Y\\HX][]H\	Y
H	H
[JJCB[X[[]HH[CBB# 9i&c.zacyl9faX^]\HCB[X[\XHCB]X]\[[X[[]][\NBYX^]\OHHX]\X^]\BX^]\HX]\[X[\XH]BB[
[X[X\\	H[X[\X\XHK\\
JOOB]B. z/c9d#/9if﹢`9BB[OH^X[Y\[Y[H/yfaZZ[Z[[^][KNKNMXMMMM
YXBB[OH^X[YY.99c"#9f.#f\.c.zac{if﹢`9BB[OH^X[Y\[Y[H/yfaZZ[Z[[^][KNKNM
LLN
ML
B[OH^X[YY."l,y+j:`yk{n#9&)9ki.h9"y`9n+b{.g&i&i&+/c.
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP