魏老师学生——Cecil:学习OpenCV-机器视觉之旅
原理
Harris算法:旋转不变特性,图像旋转后依然可以检测到角点。
SIFT算法:尺度不变特征变换。帮助提取图像中关键点并计算其描述符。(1.尺度空间极值检测;2.关键点-极值点定位;3.为关键点-极值点指定方向参数;4.关键点描述符;5.关键点匹配。)
尺度空间极值检测
尺度空间滤波器:完成在小角点用小窗口检测,大角点用大窗口检测。滤波器用列具有不同方差σ的高斯卷积核组成。
- 高斯拉普拉斯算子(LoG)具有不同方差值σ,可以对图像进行卷积。LoG检测大小不同的斑点,方差和斑点直径相等时可以使斑点完全平滑。方差即尺度变换因子。
- 窗口大小=高斯方差×6+1.
- LoG算子计算量巨大,SIFT算法使用高斯差分算子(DoG)对LoG做近似。
- DoG算子:通过减少采样(取奇数行)构成一组图像尺寸不同的金字塔,然后对这组图像中的每张图使用不同方差的高斯卷积核构建具有不同分辨率的图像金字塔。DoG就是这组具有不同分辨率的图像金字塔中相邻的两层之间的差值
- 在不同的尺度空间和2D平面中搜索局部最大值。对图像中的每个像素点都需要与周围8邻域、尺度空间中上下两层的相邻18(2×9)个点相比。如果该点是其中最大值就可能是关键点。
- SIFT参数经验值:octaves=4(通过降低采样来减小图像尺寸,构成尺寸减小的图像金字塔为4层),尺度空间5,即每个尺寸使用5个不同方差的高斯核卷积。初试方差1.6,k为根号2。
关键点—极值点定位
Aim:找到关键点后通过修正得出更准确结果。
way:通过尺度空间的泰勒级数展开获得极值的准确位置。极值点灰度值<阈值(0.03)就被忽略掉。
- DoG算法对边界很敏感,先去除边界。
- Harris算法:检测角点,检测边界。
- 当一个特征值远大于另一个特征值时,检测到的是边界。
去除低对比度和边界的关键点,分析剩余关键点。
为关键点-极值点指定方向参数
- 为每一个关键点赋予一个方向参数,使其有旋转不变性。
- 获取关键点邻域,计算区域的梯度级和方向。
- 根据计算结果创建含36个bins的方向直方图。
- 直方图峰值是主方向参数,高于峰值80%的柱子是辅方向。
使得在相同的尺度空间相同的位置构建有不同方向的关键点,利于匹配的稳定性。
关键点描述符
- 选取关键点周围邻域(16×16),分为16个4×4方块,为每个方块创建有8个bins的方向直方图。共128个bin。
- 关键点描述符由长128的向量构成。
关键点匹配
- 关键点特征向量的欧式距离:两幅图像中关键点的相似性判定度量。
- 取第一张图的关键点,通过遍历找出第二张图中距离最近的关键点。
- 两点距离太近可能由于噪声引起,通过计算最近距离与次近距离比值判定。比值>0.8就忽略。
- 去除90%错误匹配,5%正确匹配。
opencv中的SIFT
- sift.detect() ——解释:在图像中找到关键点。也可创建掩模图像在固定区域搜索。返回的关键点是带不同属性的特殊结构体,包含平面坐标值、邻域大小、方向角度等。
- cv2.drawKeyPoints(gray,kp,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) ——解释:在关键点部位绘制小圆圈。最后一个参数表示绘制与关键点等大的圆圈甚至绘制出关键点方向。
- kp,des=sift.compute(gray,kp) ——解释:计算关键点的描述符。
- sift.detectAndCompute() ——解释:找到关键点并计算出描述符。kp:关键点列表。des:numpy数组,大小=关键点数×128.
代码演示
#coding=utf-8
import cv2
import numpy as np
img=cv2.imread('./image2/mario.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
sift=cv2.SIFT()
kp=sift.detect(gray,None)
img=cv2.drawKeyPoints(gray,kp)
cv2.imshow('img',img)
img2=cv2.drawKeyPoints(gray,kp,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('img2',img2)