OpenCV(图像处理)-基于Python-特征检测-特征点匹配

简介: 1.图像特征图像特征就是指有意义的图像区域,具有独特性,易于识别性,比如角点、斑点以及高密度区。而为什么角点具有重要的特征呢?看下图:

59e7237481d6460bbc5b9a8281a0c546.png1.图像特征

图像特征就是指有意义的图像区域,具有独特性,易于识别性,比如角点、斑点以及高密度区。而为什么角点具有重要的特征呢?

看下图:


14a267effa4d4cd4a301ef23b330936e.png

观察ABD三张图片,我们不容易得知图像的位置,而CEF三张图我们特别容易找到它们在原图中对应的位置,这是因为ABD比较平滑,我们不易找出他们的特点,而CEF三张图有很明显的轮廓特征,有很多边缘特征即角点,因此一幅图像中的角点非常重要。

想让计算机具有识别图片的功能,首先要让他们学会提取图片的特征,提取图像的角点。


角点的特征

在特征中最重要的是角点

是灰度梯度最大值所对应的像素

两条线的交点

极值点(一阶导数最大值但是二阶导数为0)

2. 哈里斯检测

原理:

844a97be82c84373ad70780c1b8ed3ab.png

图1方块上下左右移动都没有变化,说明图1不是角点;图2上下没有变化,左右移动有变化,说明图2是边缘;图3上下左右移动都有变化,说明图3是角点。


42439ba1747743f6a53af6db597fb51a.png

cornerHarris()

dst = cv2.cornerHarris(img, blockSize, ksize, k)

img :需要检测的图像,最好为灰度图

blockSize:检测窗口的大小,一般取2

ksiez:Sobel卷积核,一般取3

k:权重系数,经验值,一般取0.02~0.04之间

返回值:dst不是图像,是点的集合

缺点:k是个经验值需要自己调节

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Harris角点检测
dst = cv2.cornerHarris(gray, 2, 3, 0.02)
# 表示img中dst值大于0.01*dst.max()的像素点索引出来,然后将这些像素点的值赋为 [0,0,255]。
img[dst > 0.01*dst.max()] = [0, 0, 255]
cv2.imshow('img', img)
cv2.waitKey(0)


c20014f7a5a34658a186eedf9b64296b.png

3.Shi-Tomasi角点检测

Shi-Tomasi是Harris角点检测的改进,因为Harris角点检测的稳定性与k有关,而k是个经验值,与人的主观因素有关。Shi-Tomasi避免了这个问题。

goodFeaturesToTrack()

dst = cv2.goodFeaturesToTrack(img, maxCorners, qualityLevel, minDistance)

img:需要检测的图像,最好为灰度图

maxCorners:角点的最大数量,值为0表示无限制

qualityLevel:小于1.0的正数,一般在0.01-1.0之间

minDistance:角之间最小欧式距离,忽略小于此距离的点

mask:感兴趣的区域,不填默认全部图像

blockSize:检测窗口大小

useHarrisDetector:是否使用Harris算法,True/False

k:默认是0.04

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Harris角点检测
# dst = cv2.cornerHarris(gray, 2, 3, 0.02)
maxCorners = 100
ql = 0.01
minDistance = 10
# ShiTomasi角点检测
corners = cv2.goodFeaturesToTrack(gray, maxCorners, ql, minDistance)
# corners为float32类型,需要转化为整型
corners = np.int0(corners)
# 表示img中dst值大于0.01*dst.max()的像素点索引出来,然后将这些像素点的值赋为 [0,0,255]。
# img[dst > 0.01*dst.max()] = [0, 0, 255]
for i in corners:
    x, y = i.ravel() # 将迭代的数组,转化成一维的
    cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
cv2.imshow('img', img)
cv2.waitKey(0)


ac586659110e43b99eeb5062f7440f88.png

4.Scale-Invariant Feature Transform(SIFT)

该算法是与缩放无关的特征检测,比如说,以前是角点,但是在图放大或缩小后,由于图片比例的变化,原来是角,放大之后,可能就不是角;原来是角,缩小之后可能就是角。而该算法正好解决了这个问题。


7b9e6f0fd5e44325816da2b4023cbbef.png

SIFT能够计算关键点和描述子,关键点:位置、大小和方向;关键点描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换、光照变换的影响。

SIFT语法

首先创建SIFT对象

进行检测,kp =sift.detect(img,…)

绘制关键点,drawKeypoints(gray, kp, img)

从灰度图gray中检测的,关键点kp,在原图img中画

创建SIFT对象

sift = cv2.xfeatures2d.SIFT_create(什么也不写)

kp = sift.detect(img, mask)

img:是检测图片,尽量用灰度图

mask:掩码,指明对图中哪部分进行检测,一般填None(全图)

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建sift对象
sift = cv2.xfeatures2d.SIFT_create()
# 关键点检测
kp = sift.detect(gray, None)
# 使用关键点画图
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)


bd749ca90e444bb49b2e317b76fb9eea.png

此接口一下能算出关键点和描述子

kp, des = sift.detectAndCompute(img, mask)

img:是检测图片,尽量用灰度图

mask:掩码,指明对图中哪部分进行检测,一般填None(全图)

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建sift对象
sift = cv2.xfeatures2d.SIFT_create()
# kp = sift.detect(gray, None)
kp, des = sift.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)


59e7237481d6460bbc5b9a8281a0c546.png

SIFT缺点:速度慢

5.SURF

由于SIFT速度较慢,因此又产生了SURF算法,该算法速度优于SIFT。

  • 首先创建SURF对象

进行检测,kp, des =surf.detectAndCompute(img, mask)

绘制关键点,drawKeypoints(gray, kp, img)

从灰度图gray中检测的,关键点kp,在原图img中画

创建surf对象

surf = cv2. xfeatures2d.SURF_create()

kp, des = surf.detectAndCompute(img, mask)

img:是检测图片,尽量用灰度图

mask:掩码,指明对图中哪部分进行检测,一般填None(全图)

kp:检测出的关键字

des:是描述子,用来特征匹配使用的

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# # 创建sift对象
# sift = cv2.xfeatures2d.SIFT_create()
# 创建surf对象
surf = cv2.xfeatures2d.SURF_create()
# 计算关键点和描述子
kp, des = surf.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)

注意:此算法由于付费的缘由,需要使用3.4.2.17版本的opencv库

6.ORB(Oriented FAST and Rotated BRIEF)

其中FAST用于特征检测,BRIEF是对已检测到的特征点进行描述,它加快了特征描述符的建立速度,同时也极大降低了特征匹配的时间。

ORB的优势在于:速度快,可用于实时监测;免费。


先建立ORB对象

orb = cv2.ORB_create()

计算特征点与描述子

kp, des = orb.detectAndCompute(img, mask)

使用kp画出特征点

cv2.drawKeypoints(gray, kp, img)


img:是检测图片,尽量用灰度图

mask:掩码,指明对图中哪部分进行检测,一般填None(全图)

import cv2
import numpy as np
# 读取图片,并转为灰度图
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建orb对象
orb = cv2.ORB_create()
# 对ORB进行检测
kp, des = orb.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)

ab2164f0c66b4c6b99f4b8fccdc74403.png

检测出的特征点越来越少,因此在提升检测速度的同时,精度也在丢失。


7.特征匹配

根据特征点的描述子进行匹配,特征匹配方法有:


BF(Brute-Force),暴力特征匹配方法

FLANN 最快临近区特征匹配方法

7.1 暴力特征匹配

它使用第一组中的每个特征点的描述子与第二组中的所有特征点的描述子进行匹配,计算他们之间的差距,然后将最接近的一个匹配返回


创建匹配器,bf = cv2.BFMatcher(normType, crossCheck)

进行特征匹配,match = bf. match(des1, des2)

绘制匹配点, cv2.drawMatches(img1, kp1, img2, kp2,…)

创建匹配器

bf = cv2.BFMatcher(normType, crossCheck)

normType:NORM_L1(SIFT),NORM_L2(SURF), HAMMING1(ORB)

crossCheck:是否进行交叉匹配,默认为false

描述子进行匹配

match = bf.match(dst1, dst2)

dst1:要搜索的图的描述子

dst2:从库里能匹配的描述子

画相同的地方

img3 = cv2.drawMatchers(img1, kp1, img2, kp2, match, None)

img1, kp1:要搜索的图,和特征点

img2, kp2:从库里匹配的图和特征点

match:匹配好的描述子

import cv2
import numpy as np
# 读取图片,并转为灰度图
img1 = cv2.imread('./image/opencv_search.png')
img2 = cv2.imread('./image/opencv_orig.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 创建orb对象
orb = cv2.ORB_create()
# 对ORB进行检测
kp1, dst1 = orb.detectAndCompute(gray1, None)
kp2, dst2 = orb.detectAndCompute(gray2, None)
# 创建匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
# 描述子进行匹配
match = bf.match(dst1, dst2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, match, None)
cv2.imshow('img3', img3)

6d677a85ffc14468b05a3a154eadf927.png

7.2 FLANN

  • 进行批量特征匹配时,FLANN速度更快
  • 由于它使用的是临近近似值,所以精度较差

创建匹配器

flann = cv2.FlannBasedMatcher()

进行特征匹配

match = flann.match()

绘制匹配点img3 = cv2.drawMatches()

import cv2
import numpy as np
# 读取图片,并转为灰度图
img1 = cv2.imread('./image/opencv_search.png')
img2 = cv2.imread('./image/opencv_orig.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 创建orb对象
orb = cv2.ORB_create()
# 对ORB进行检测
kp1, dst1 = orb.detectAndCompute(gray1, None)
kp2, dst2 = orb.detectAndCompute(gray2, None)
# 判断描述子的数据类型,若不符合,则进行数据替换
if dst1.dtype != 'float32':
    dst1 = dst1.astype('float32')
if dst2.dtype != 'float32':
    dst2 = dst2.astype('float32')
# 创建匹配器(FLANN)
flann = cv2.FlannBasedMatcher()
# 描述子进行匹配计算
matches = flann.match(dst1, dst2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, None)
cv2.imshow('img3', img3)


cf359fdd4d3f45efaa546c0d21bf0089.png 

目录
相关文章
|
19天前
|
机器学习/深度学习 人工智能 算法
图像处理与分析:Python中的计算机视觉应用
【4月更文挑战第12天】Python在计算机视觉领域广泛应用,得益于其丰富的库(如OpenCV、Pillow、Scikit-image)和跨平台特性。图像处理基本流程包括获取、预处理、特征提取、分类识别及重建生成。示例代码展示了面部和物体检测,以及使用GAN进行图像生成。
|
6天前
|
机器学习/深度学习 存储 监控
数据分享|Python卷积神经网络CNN身份识别图像处理在疫情防控下口罩识别、人脸识别
数据分享|Python卷积神经网络CNN身份识别图像处理在疫情防控下口罩识别、人脸识别
18 0
|
1天前
|
机器学习/深度学习 算法 数据可视化
Python用KNN(K-近邻)回归、分类、异常值检测预测房价、最优K值选取、误差评估可视化
Python用KNN(K-近邻)回归、分类、异常值检测预测房价、最优K值选取、误差评估可视化
|
2天前
|
算法 安全 机器人
最新版opencv4.9安装介绍,基本图像处理详解
最新版opencv4.9安装介绍,基本图像处理详解
|
3天前
|
数据采集 关系型数据库 BI
Python路面平整度检测车辆数据——速度修正
Python路面平整度检测车辆数据——速度修正
10 0
|
13天前
|
数据采集 存储 安全
python检测代理ip是否可用的方法
python检测代理ip是否可用的方法
|
13天前
|
机器学习/深度学习 算法 自动驾驶
opencv python 图片叠加
【4月更文挑战第17天】
|
14天前
|
数据挖掘 计算机视觉 Python
SciPy图像处理技巧:图像增强与特征提取
【4月更文挑战第17天】本文介绍了如何使用SciPy进行图像增强和特征提取。通过调整亮度、对比度和伽马校正实现图像增强,示例代码展示了相关操作。同时,利用Sobel算子进行边缘检测和Laplacian of Gaussian (LoG) 进行角点检测,以提取图像特征。虽然SciPy不是专业的图像处理库,但其数值计算能力在图像分析中仍有一定价值,可与其他图像处理库结合使用。
|
14天前
|
机器学习/深度学习 存储 算法
OpenCV与NumPy:图像处理中的黄金组合
【4月更文挑战第17天】OpenCV和NumPy是Python图像处理的两大利器,互补协作形成黄金组合。OpenCV专注计算机视觉,提供丰富算法,而NumPy擅长数值计算和数组操作。两者无缝对接,共同实现高效、灵活的图像处理任务。通过灰度化、二值化、边缘检测等案例,展示了它们的协同作用。未来,这一组合将在计算机视觉和机器学习领域发挥更大作用,解锁更多图像处理潜力。
|
14天前
|
数据可视化 Python
python对网络图networkx进行社区检测和彩色绘图
python对网络图networkx进行社区检测和彩色绘图