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 

目录
相关文章
|
3月前
|
传感器 运维 前端开发
Python离群值检测实战:使用distfit库实现基于分布拟合的异常检测
本文解析异常(anomaly)与新颖性(novelty)检测的本质差异,结合distfit库演示基于概率密度拟合的单变量无监督异常检测方法,涵盖全局、上下文与集体离群值识别,助力构建高可解释性模型。
391 10
Python离群值检测实战:使用distfit库实现基于分布拟合的异常检测
|
10月前
|
运维 监控 算法
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
MSET-SPRT是一种结合多元状态估计技术(MSET)与序贯概率比检验(SPRT)的混合框架,专为高维度、强关联数据流的异常检测设计。MSET通过历史数据建模估计系统预期状态,SPRT基于统计推断判定偏差显著性,二者协同实现精准高效的异常识别。本文以Python为例,展示其在模拟数据中的应用,证明其在工业监控、设备健康管理及网络安全等领域的可靠性与有效性。
1128 13
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
|
6月前
|
监控 编译器 Python
如何利用Python杀进程并保持驻留后台检测
本教程介绍如何使用Python编写进程监控与杀进程脚本,结合psutil库实现后台驻留、定时检测并强制终止指定进程。内容涵盖基础杀进程、多进程处理、自动退出机制、管理员权限启动及图形界面设计,并提供将脚本打包为exe的方法,适用于需持续清理顽固进程的场景。
|
8月前
|
人工智能 算法 计算机视觉
Python 图像处理技巧
本文介绍了Python图像处理中需要掌握的15个基本技能,涵盖图像读取与保存、颜色空间转换、裁剪与调整大小、滤波与平滑、边缘检测、阈值处理、形态学操作、直方图处理、特征检测与描述、图像配准与特征匹配、轮廓检测与分析、图像分割、模板匹配、透视变换与仿射变换以及傅里叶变换等内容。通过OpenCV、Pillow和Matplotlib等库实现相关功能,为图像处理提供了全面的基础指导。
241 0
|
12月前
|
监控 网络安全 开发者
Python中的Paramiko与FTP文件夹及文件检测技巧
通过使用 Paramiko 和 FTP 库,开发者可以方便地检测远程服务器上的文件和文件夹是否存在。Paramiko 提供了通过 SSH 协议进行远程文件管理的能力,而 `ftplib` 则提供了通过 FTP 协议进行文件传输和管理的功能。通过理解和应用这些工具,您可以更加高效地管理和监控远程服务器上的文件系统。
463 20
|
11月前
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
584 1
|
XML 机器学习/深度学习 人工智能
使用 OpenCV 和 Python 轻松实现人脸检测
本文介绍如何使用OpenCV和Python实现人脸检测。首先,确保安装了OpenCV库并加载预训练的Haar特征模型。接着,通过读取图像或视频帧,将其转换为灰度图并使用`detectMultiScale`方法进行人脸检测。检测到的人脸用矩形框标出并显示。优化方法包括调整参数、多尺度检测及使用更先进模型。人脸检测是计算机视觉的基础技术,具有广泛应用前景。
581 10
|
Python
python检测网络延迟
#!/usr/bin/env python # coding: utf-8 # coding: cp950 ''' Create Date: 2012-11-06 Version: 1.
2529 0
|
4月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
343 102
|
4月前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
364 104

推荐镜像

更多