第6章 图像检索以及基于图像描述符的搜索

简介: 第6章 图像检索以及基于图像描述符的搜索

第6章 图像检索以及基于图像描述符的搜索


OpenCV可以检测图像的主要特征,然后提取这些特征,使其成为图像描述符,类似于人的眼睛和大脑。


本章介绍如何使用OpenCV检测图像特征,并通过这些特征进行图像匹配和检测。 本章选取一些图像,检测它们的主要特征,并通过单应性来检测这些图像是否存在于另一个图像中。


6.1 特征检测算法


OpenCV中最常用的特征检测和提取算法:


Harris:用于检测角点


SIFT:用于检测斑点(Blob)


SURF:用于检测斑点


FAST:检测角点


BRIEF:检测斑点


ORB:带方向的FAST算法和具有选择不变性的BRIEF算法。


匹配算法:


暴力(Brute-Force)匹配法


基于FLANN的匹配法



6.1.1 特征定义


特征是有意义的图像区域,该区域具有独特性和易于识别性。


因此,角点及高密度区域是很好的特征,而大量重复的模式和低密度区域不是好的特征。边缘可以将图像分成两个区域,因此也可以看作好的特征,


斑点(和周围差别很大的区域)也是有意义的特征。




检测角点特征:


import cv2

import numpy as np

img = cv2.imread("images/chess_board.png")

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)

dst = cv2.cornerHarris(gray,2,23,0.04)

img[dst>0.01 * dst.max()] = [0,255,0]

while(True):

   cv2.imshow('corners',img)

   if cv2.waitKey(84) & 0xff == ord('q'):

       break

cv2.destroyAllWindows()



6.1.2 使用DoG和SIFT进行特征提取与描述


通过SIFT得到充满角点和特征的图像


import cv2

import numpy as np


imgpath = r".\images\varese.jpg"

img = cv2.imread(imgpath)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()

keypoints,descriptor = sift.detectAndCompute(gray,None)

img = cv2.drawKeypoints(image=img,outImage=img,keypoints=keypoints,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,

                       color=(51,163,236))

cv2.imshow('sift_keypoints',img)

cv2.waitKey()



6.1.3 使用快速Hessian算法和SURF来提取和检测特征


SURF特征检测算法比SIFT快好几倍,它吸收了SIFT算法的思想。


SURF是OpenCV的一个类,SURF使用快速Hessian算法检测关键点,SURF会提取特征。


import cv2

import numpy as np


imgpath = r".\images\varese.jpg"

img = cv2.imread(imgpath)

alg = "SURF"

def fd(algorithm):

   if algorithm == "SIFT":

       return cv2.xfeatures2d.SIFT_create()

   if algorithm == "SURF":

       return  cv2.xfeatures2d.SURF_create(float(8000))



gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

fd_alg = fd(alg)

keypoints,descriptor = fd_alg.detectAndCompute(gray,None)

img = cv2.drawKeypoints(image=img,outImage=img,keypoints=keypoints,

                       flags=4,color=(51,163,236))

cv2.imshow('sift_keypoints',img)

cv2.waitKey()



6.1.4 基于ORB的特征检测和特征匹配


ORB是一种新的算法,用来替代SIFT和SURF算法。


ORB将基于FAST关键点检测的技术和基于BRIEF描述符的技术相结合、


1.FAST(Feature from Accelerated Segment Test)


FAST算法会在像素周围绘制一个圆,该圆包括16个像素,然后,FAST将每个像素与加上一个阈值的圆心像素值进行比较,若有连续,比此值还亮或还暗的像素,则认为圆心的角点。


2.BRIEF(Binary Robust Independent Elemetary Features)并不是特征检测算法,它只是一个描述符。


3.暴力匹配


暴力匹配是一种描述符匹配方法,该方法会比较两个描述符,并产生匹配结果的列表,称为暴力匹配的原因是该算法不涉及优化,第一个描述符的所有特征都和第二个描述符的特征进行比较。


6.1.5 ORB特征匹配


import numpy as np

import  cv2

from matplotlib import  pyplot as plt


img1 = cv2.imread('images/manowar_logo.png',cv2.IMREAD_GRAYSCALE)

img2 = cv2.imread('images/manowar_single.jpg',cv2.IMREAD_GRAYSCALE)


orb = cv2.ORB_create()

kp1,des1 =  orb.detectAndCompute(img1,None)

kp2,des2 = orb.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)

matches = bf.match(des1,des2)

matches = sorted(matches,key=lambda  x:x.distance)

img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:40],img2,flags=2)

plt.imshow(img3),plt.show()


6.1.6 K-最近邻匹配(运行出错)


只需对前面的匹配操作进行修改:



6.1.7 FLANN匹配


近似最近邻的快速库


import numpy as np

import  cv2

from matplotlib import  pyplot as plt


queryImage = cv2.imread('images/bathory_album.jpg',0)

trainingImage = cv2.imread('images/vinyls.jpg',0)


sift = cv2.xfeatures2d.SIFT_create()

kp1, des1 = sift.detectAndCompute(queryImage,None)

kp2, des2 = sift.detectAndCompute(trainingImage,None)


FLANN_INDEX_KDTREE = 0

indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees=5)

searchParams = dict(checks=50)

flann = cv2.FlannBasedMatcher(indexParams,searchParams)

matches = flann.knnMatch(des1,des2,k=2)


matchesMask = [[0,0] for i in range(len(matches))]


for i,(m,n) in enumerate(matches):

   if m.distance < 0.7 *n.distance:

       matchesMask[i]=[1,0]


drawParams = dict(matchColor=(0,255,0),singlePointColor = (255,0,0),

                 matchesMask=matchesMask, flags=0)

resultImage = cv2.drawMatchesKnn(queryImage,kp1,trainingImage,kp2,matches,None,**drawParams)

plt.imshow(resultImage,),plt.show()



6.1.8 FLANN的单应性匹配


单应性是一个条件,该条件表面当两幅图像中一副出现投影畸变时,还能匹配。


import numpy as np

import cv2

from matplotlib import  pyplot as plt


MIN_MATCH_COUNT = 10


img1 = cv2.imread('images/bb.jpg',0)

img2 = cv2.imread('images/color2_small.jpg',0)


sift = cv2.xfeatures2d.SIFT_create()

kp1,des1 = sift.detectAndCompute(img1,None)

kp2,des2 = sift.detectAndCompute(img2,None)


FLANN_INDEX_KDTREE = 0

index_params = dict(algorithm=FLANN_INDEX_KDTREE,trees=5)

search_params = dict(checks=50)


flann = cv2.FlannBasedMatcher(index_params,search_params)


matches = flann.knnMatch(des1,des2,k=2)


good = []

for m,n in matches:

   if m.distance < 0.7*n.distance:

       good.append(m)

if len(good)>MIN_MATCH_COUNT:

   scr_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)

   dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)


   M,mask = cv2.findHomography(scr_pts,dst_pts,cv2.RANSAC,5.0)

   matchesMask = mask.ravel().tolist()

   h,w = img1.shape

   pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)

   dst = cv2.perspectiveTransform(pts,M)

   img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3,cv2.LINE_AA)

else:

   print("Not enough matches are found")

   matchesMask = None


draw_params = dict(matchColor=(0,255,0),singlePointColor = None,

                  matchesMask = matchesMask,flags=2)


img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)

plt.imshow(img3,'gray'), plt.show()














6.1.9 基于文身取证的应用程序示例


#1.generate_description.py


import cv2

import numpy as np

from os import  walk

from os.path import  join

import sys


def create_descritors(folder):

   files = []

   for(dirpath,dirnames,filenames) in walk(folder):

       files.extend(filenames)

   for f in files:

       save_descriptor(folder,f,cv2.xfeatures2d.SIFT_create())


def save_descriptor(folder,image_path,feature_detector):

   img = cv2.imread(join(folder,image_path),0)

   keypoints,descriptors = feature_detector.detectAndCompute(img,None)

   descriptor_file = image_path.replace("jpg","npy")

   np.save(join(folder,descriptor_file),descriptors)


dir = 'anchors'

create_descritors(dir)


#2scan_and_match.py

from os.path import  join


from os import  walk


import  numpy as np


import  cv2


from sys import argv




folder = "anchors"


query = cv2.imread( join(folder,"tattoo_seed.jpg"),0)








files = []


images = []


descriptiors = []


for (dirpath,dirnames,filenames) in walk(folder):


   files.extend(filenames)


   for f in files:


       if f.endswith("npy") and f != "tattoo_seed.npy":


           descriptiors.append(f)


   print(descriptiors)






sift = cv2.xfeatures2d.SIFT_create()


query_kp ,query_ds = sift.detectAndCompute(query,None)




FLANN_INDEX_KDTREE = 0


index_params = dict(algorithm=FLANN_INDEX_KDTREE,trees = 5)


search_params = dict(checks = 50)


flann = cv2.FlannBasedMatcher(index_params,search_params)








MIN_MATCH_COUNT = 10




potential_culprits = {}


print(">>初始化图像扫描...")


for d in descriptiors:


   print("-----分析%s ---------"%d)


   matches=flann.knnMatch(query_ds,np.load(join(folder,d)),k=2)


   good = []


   for m,n in matches:


       if m.distance < 0.7*n.distance:


           good.append(m)


   if len(good)>MIN_MATCH_COUNT:


           print("%s 匹配!(%d)"%(d,len(good)))


   else:


           print("%s 不匹配!" % d)


   potential_culprits[d] = len(good)




max_matches = None


potential_suspect = None


for culprit, matches in potential_culprits.items():


   if max_matches == None or matches>max_matches:


       max_matches = matches


       potential_suspect = culprit




print("嫌疑人 %s" %potential_suspect.replace("npy","").upper())


相关文章
|
1月前
|
存储 自然语言处理 算法
高维向量压缩方法IVFPQ :通过创建索引加速矢量搜索
向量相似性搜索是从特定嵌入空间中的给定向量列表中找到相似的向量。它能有效地从大型数据集中检索相关信息,在各个领域和应用中发挥着至关重要的作用。
151 0
|
1月前
|
编解码 自动驾驶 测试技术
【论文速递】PETR: 用于多视图 3D 对象检测的位置嵌入变换
【论文速递】PETR: 用于多视图 3D 对象检测的位置嵌入变换
|
9月前
|
存储 算法
6.2 Sunday搜索内存特征
Sunday 算法是一种字符串搜索算法,由`Daniel M.Sunday`于1990年开发,该算法用于在较长的字符串中查找子字符串的位置。算法通过将要搜索的模式的字符与要搜索的字符串的字符进行比较,从模式的最左侧位置开始。如果发现不匹配,则算法将模式向右`滑动`一定数量的位置。这个数字是由当前文本中当前模式位置的最右侧字符确定的。相比于暴力方法,该算法被认为更加高效。
61 1
6.2 Sunday搜索内存特征
|
10月前
|
人工智能 数据挖掘 PyTorch
VLE基于预训练文本和图像编码器的图像-文本多模态理解模型:支持视觉问答、图文匹配、图片分类、常识推理等
VLE基于预训练文本和图像编码器的图像-文本多模态理解模型:支持视觉问答、图文匹配、图片分类、常识推理等
VLE基于预训练文本和图像编码器的图像-文本多模态理解模型:支持视觉问答、图文匹配、图片分类、常识推理等
|
1月前
[3D&Halcon] 三维点云匹配&无序抓取
[3D&Halcon] 三维点云匹配&无序抓取
163 0
|
10月前
|
人工智能 自然语言处理 算法
Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索
Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索
Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索
|
10月前
|
JSON 算法 数据格式
优化cv2.findContours()函数提取的目标边界点,使语义分割进行远监督辅助标注
可以看到cv2.findContours()函数可以将目标的所有边界点都进行导出来,但是他的点存在一个问题,太过密集,如果我们想将语义分割的结果重新导出成labelme格式的json文件进行修正时,这就会存在点太密集没有办法进行修改,这里展示一个示例:没有对导出的结果进行修正,在labelme中的效果图。
112 0
|
12月前
|
安全 知识图谱
三维点云的开放世界理解,分类、检索、字幕和图像生成样样行
三维点云的开放世界理解,分类、检索、字幕和图像生成样样行
211 0
|
传感器 机器学习/深度学习 存储
利用BEV辅助的立体匹配,助力3D语义场景补全
利用BEV辅助的立体匹配,助力3D语义场景补全
210 0
|
JavaScript
计算属性实现模糊搜索功能场景
我相信大家在项目中都会遇到模糊搜索这个功能要求,即我们在输入框内输入文字后显示与输入文字相关的关键字,那这个具体实现方案是什么,这是我在最近一期蓝桥杯楼赛中遇到的业务需求,大家可以来思考一下,下面我将进行实现详解
118 2
计算属性实现模糊搜索功能场景