1.ORB算法
1.1原理
SIFT和SURF算法是受专利保护非,在使用他们时我们是要付费的,但是ORB不需要,它可以用来对图像中的关键点快速创建特征向量,并用这些特征向量来识别图像中的对象。
1.2ORB算法流程
ORB算法结合了Fast和Brief算法,提出了构造金字塔,为Fast特征点添加了方向,从而使得关键点具有了尺度不变性和旋转不变性。具体流程描述如下:
-构造尺度金字塔,金字塔共有n层,与SIFT不同的是,每一层仅有一幅图像,第s层的尺度为:
在不同的尺度上利用Fast算法检测特征点,采用Harris角点响应函数,根据角点的响应值排序,选取前N个特征点,作为本尺度的特征点。
计算特征点的主方向,计算以特征点为圆心半径为r的圆形领域内的灰度质心位置,将从特征点到质心位置的方向做特征点的主方向
为了解决选择不变性,将特征点的领域旋转到主方向上利用Brief算法构建特征描述符,至此就得到了ORB的特征描述向量
1.3BRIEF算法
BRIEF是一种特征描述子提取算法,并非特征点的提取算法,一种生成二值化描述子的算法,不提取代价低,匹配只需要使用简单的汉明距离利用比特之间的异或操作就可以完成。因此,时间代价低,空间代价低,效果还挺好是最大的优点。
算法的步骤介绍如下:
1.图像滤波:对关键点周围区域进行滤波
2.选取点对:一般N=128,256,512
3.构建描述符:假设x,y是某个点对的两个端点,p(x),p(y)是两点对应的像素值,则有:
4.对每一个点对都进行上述的二进制赋值,形成BRIEF的关键点的描述特征向量,该向量一般
为128-512位的字符串,其中仅包含1和0
2.实现
在opencv中实现ORB算法,使用的是:
1.实例化ORB
orb=cv.xfeatures2d.orb_create(nfeatures)
参数:
-nfeatures:特征点的最大数量
2.利用orb.detectAndCompute()检测关键点并计算
kp,des=orb.detectAndCompute(gray,None)
参数:
-gray:进行关键点检测的图像,注意是灰度图像
返回:
-kp:关键点信息,包括位置,尺度,方向信息
-des:关键点描述符,每个关键点BRIEF特征向量,二进制字符串
3.将关键点检测结果绘制在图像上
cv.drawKeyponts(image,keypoints,outputimage,color,flags)
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.图像读取
img=cv.imread('hanfeng.png')
#2.ORB角点检测
#2.1实例化ORB对象
orb=cv.ORB_create(nfeatures=5)
#2.2检测关键点,并计算特征描述符
kp,des=orb.detectAndCompute(img,None)
print(des.shape)
#3将关键点绘制在图像上
img2=cv.drawKeypoints(img,kp,None,color=(0,255,0),flags=0)
#绘制图像
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img2[:,:,::-1])
plt.xticks([]),plt.yticks([])
plt.show()
总结
1.Fast算法
原理:若一个像素周围有一定数量的像素与该点像素值不同,则认为其为角点
API:cv.FastFeatureDetector_create()
2.ORB算法
原理:是Fast算法和BRIEF算法的结合
API:cv.ORB_create()
3.LBP算法
LBP是指局部二值模式,是一种用来描述图像局部特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点,它是由T.Ojala,M.Pietikainen和D.Harwood在1994年提出,由于LBP特征计算简单,效果较好,因此LBP特征在计算机视觉的许多领域都得到了广泛的应用。
3.1LBP特征描述
原始的LBP算子定义为在$33$的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,$33$领域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。如图所示:
4.实现
在opencv中实现了LBP特征的计算,但没有提供一个单独的计算LBP特征的接口。所以我们使用skimage给大家演示该算法。
skimage即是Scikit-Image。基于python脚本语言开发的数字图片处理包,scikit-image是基于scipy的一款图像处理包,它将图片作为numpy数组进行处理。安装方法:
pip install scikit-image
skimage包的全称是scikit-image SciKit,它对scipy.ndimage进行了扩展,提供了更多的图片处理功能。它是由python语言编写的。由scipy社区开发和维护。skimage包由许多的子模块组成,各个子模块提供不同的功能。其中feature模块进行特征检测与提取。使用的API是:
skimage.feature.local_binary_pattern(image,P,R,method='default')
参数:
-image:输入的灰度图像
-P,R:进行LBP算子计算时的半径和像素点数
-method:算法类型:{'default','ror','nri-uniform','var'}
default:‘默认’,原始的LBP特征
ror:圆形LBP算子
nri-uniform:等价LBP算子
var:旋转不变LBP算子
from skimage.feature import local_binary_pattern
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.读取图像
img=cv.imread('hanfeng.png')
face=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2.特征提取
#2.1需要的参数
#LBP算法中范围半径的取值
radius=1
#领域像素点数
n_points=8*radius
#2.1原始LBP特征
lbp=local_binary_pattern(face,8,1)
#2.2圆形LBP特征
clbp=local_binary_pattern(face,n_points,radius,method='ror')
#2.3 旋转不变LBP特征
varlbp=local_binary_pattern(face,n_points,radius,method='var')
#2.4等价特征
uniformlbp=local_binary_pattern(face,n_points,radius,method='uniform')
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(lbp,'gray')
axes[0,0].set_title('原始的LBP特征')
axes[0,0].set_xticks([])
axes[0,0].set_yticks([])
axes[0,1].imshow(clbp,'gray')
axes[0,1].set_title('圆形LBP特征')
axes[0,1].set_xticks([])
axes[0,1].set_yticks([])
axes[1,0].imshow(varlbp,'gray')
axes[1,0].set_title('旋转不变LBP特征')
axes[1,0].set_xticks([])
axes[1,0].set_yticks([])
axes[1,1].imshow(uniformlbp,'gray')
axes[1,1].set_title('等价特征')
axes[1,1].set_xticks([])
axes[1,1].set_yticks([])
plt.show()
5.HOG算法
5.1特征提取流程
HOG的主要思想是:在一幅图像中,局部目标的表象和形状能够被梯度或边缘的方向密度分布(即梯度的统计信息,而梯度主要位于边缘的地方)很好地描述
HOG特征检测算法的几个步骤:颜色空间归一化——>梯度方向直方图——》重叠块直方图归一化——》HOG特征。如图所示:
整体流程简单描述如下:
1.将输入图像(你要检测的目标或者扫描端口)灰度化,即将彩色图像转化为灰度图
2.颜色空间归一化:采用Gamma校正法对输入图像进行颜色空间的标准化(归一化),目的是调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰
3.梯度计算:计算每个像素的梯度(包括大小和方向);主要为了捕获轮廓信息,同时进一步弱化光照的干扰
4.梯度方向直方图:将图像分成小cells(例如8*8像素/cell),统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的描述符
5.重叠直方图归一化:将每几个cell组成一个block(例如3*3个cell/block),一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征描述符。
6.HOG特征:将图像image内所有block的HOG特征描述符串联起来就可以得到image(你要检测的目标)的HOG特征描述符,就得到最终的可供分类使用的特征向量了
5.2HOG特征的优缺点
优点:
-HOG表示的是边缘的结构特征,因此可以描述局部的形状信息
-位置和方向的量化在一定程度上可以一直平移和旋转带来的影响
-采取局部区域归一化直方图,可以部分抵消光照变换带来的影响
缺点:
-描述子生成冗长、维数较高,导致速度慢,实时性差
-很难处理遮挡问题
-由于梯度的性质,对噪声非常敏感
6.实现
opencv提供了计算HOG特征的API,实现HOG特征提取的流程是:
1.实例化HOG特征提取算子,使用的API是:
hog=cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins)
参数;
-winSize:检测窗口的大小
-blockSize:block块的大小
-blockStride:block块的滑动步长
-cellSize:cell单元的大小
-Nbins:统计梯度的方向的数目,一般取为9,即在一个cell单元中计算9个方向的梯度直方图
返回:
-hog:实例化后的Hog特征检测对象
-搜索整个图像,计算图像的HOG特征,调用:
hogDes=hog.compute(img,winStride,padding)
参数:
-img:输入图像
-winStride:检测窗口的滑动步长
-padding:填充,在图像的周围填充点对边界进行处理
返回:
-hogDes:整幅图像的HOG特征描述符,当padding为默认的(0,0)时,特征向量的维数:[(img_size-window_size)/winddow_size+1)]*(每个检测窗口中的特征维数)。
import numpy as np
import cv2 as cv
import matplotlib
matplotlib.use('TkAgg') # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
#1.读取图像
img=cv.imread('hanfeng.png')
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
print(img.shape)
#2.HOG特征提取
#2.1参数设置
winSize=(64,128)
blockSize=(16,16)
blockStride=(8,8)
cellSize=(8,8)
nbins=9
#2.2实例化hog对象
hog=cv.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins)
#2.3计算hog特征描述符
hogDes=hog.compute(img,winStride=(8,8))
#2.4输出描述符的大小
print(hogDes.size)
总结:
1.LBP算法:
原始LBP特征:在3*3的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0.这样,3*3领域内的8个点经比较可产生8位二进制数,即LBP值。
圆心LBP算子:计算不同半径领域大小和不同像素点数的特征值
旋转不变LBP算子:不断旋转圆形邻域得到一系列初始定义的LBP值,取其最小值作为该邻域的LBP值
Uniform Pattern LBP特征:当某个LBP所对应的循环二进制数从0到1或从1到0最多有两次跳变时,该LBP所对应的二进制就称为一个等价模式类。除等价模式类以外的模式都归为另一类,称为混合模式类。
API:
Skiimage.feature.Local_binary_pattern()
2.HOG算法:
思想:在一幅图像中,局部目标的表象和形状能够利用梯度或边缘的方向密度分布来描述。
HOG特征检测算法的步骤:颜色空间归一化——>梯度方向直方图——》重叠块直方图归一化——》HOG特征
API:
(1)实例化HOG对象:
hog=cv.HOGDescriptor()
(2)计算HOG特征描述符
hogdes=hog.Compute()