欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MSER+SIFT 图像的特征向量提取 python

程序员文章站 2022-07-14 23:44:35
...

在做图像检索时,需要提取图像的特征向量。传统的局部特征描述子如SIFT、SURF等,如果不做别的处理,往往会得到大量的特征向量,虽然特征向量的数目越多,对图像的描述越精确,检索的准确率较高,但是这也会增加硬件成本同时也会耗费大量的计算时间。

从博主的试验结果来看,单张图384×256大小,提取出的SIFT平均有200个,如果直接和库中的数据进行相似度计算,大概要1分钟的时间。对于时间要求很高的产业,这是不能接受的。所以,在不进行压缩图像损失信息的前提下,大大减少SIFT的数目是很有必要,也是很有价值的。

在查阅了大量的资料后,博主发现在做keypoint的compute之前,用MSER 检测出的keypoint代替SIFT检测出的keypoint,可以大大减少SIFT 的数目。对MSER 有疑问的,可以在找几篇相关的博客看一看,不是很复杂。

简单的说一下MSER(最大稳定值检测),基于分水岭的概念,对图像进行二值化,阈值范围[0,255],然后不断变化阈值,变化量可以自己设置,二值图像就会经历一个从全黑0到全白255的过程,就像水位不断上升时陆地和海平面的俯瞰图。在这个过程中,有些连通区域面积随着阈值的变化量很小或基本不变,这些区域就叫MSER 。关于MSER的算法细节和具体实现就不在这说了,有兴趣的可以自己研究一下。

当用MSER检测出keypoint之后,就可以利用SIFT的方式计算这些keypoint的描述子了。

import cv2
import numpy as np
import skimage.io as io
import matplotlib.pyplot as plt
filename="/home/mysj/文档/testpicture"
str=filename+"/*.jpg"
mat=io.ImageCollection(str)
img=mat[0]
##创建一个MSER检测器,并检测图像的MSER区域
##kpkp保存检测到的keypoint
mser=cv2.MSER_create()
regions,boxes=mser.detectRegions(img)
kpkp=mser.detect(img)
print len(mser.detect(img))
##用红框框出检测到的MSER区域,boxes保存这些区域的左上角的坐标和区域的宽和高
for i in range(len(boxes)):
    x,y,w,h=boxes[i]
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
#创建一个SIFT特征提取器
siftt=cv2.xfeatures2d.SIFT_create()

print len(regions)
print len(boxes)
kp=siftt.detect(img,None)
##计算kpkp的局部描述子
des=siftt.compute(img,kpkp)
print len(des[0])
##在图像上画出这些keypoint
cv2.drawKeypoints(img,kpkp,mat[0])
plt.imshow(mat[0])    

SIFT-SIFT方式提取的特征点有243个,MSER-SIFT提取的特征点有57个,虽然精度会有些下降,但是带来的时间上的提升是很客观的。时间缩短为原来的1/4,相当于原来跑一张的时间现在可以跑4张图。红框是MSER区域。

MSER+SIFT 图像的特征向量提取 python

                                       图一 SIFT-SIFT

 

MSER+SIFT 图像的特征向量提取 python

                                    图二 MSER-SIFT