资讯详情

opencv+python图像匹配——模版匹配、特征点匹配

最近在图像检测项目中,需要进行图像匹配的相关内容,查阅opencv匹配方法,整理了模板匹配和特征匹配的内容,并总结为博客。

模板匹配与特征匹配

  • 模板匹配是最原始、最基本的识别方法之一。简单地说,模板匹配目标图片上使用已知的模板图片(类似滑窗法)每次滑动计算模板和模板下方的目标子图。 但是模板匹配有一定的局限性,这是我在实际操作中发现的。局限性主要体现在。也就是说,如果模板图片的方向和大小与目标子图不一致,则无法成功匹配。

  • 特征匹配(FBM),也称为角匹配,是指通过计算匹配实体之间的相似性测量,将从图像中提取的特征作为共轭实体,并将提取的特征属性或描述参数(实际上是特征特征)作为匹配实体,实现共轭实体匹配的图像匹配方法。也就是说,,确定图像的位置关系。 该算法在匹配目标旋转或大小变化时仍然有效。

模版匹配

模板匹配是在目标图片上使用已知的模板图片(类似滑窗法)每次滑动计算模板和模板下方的目标子图

如果是单个目标的匹配,匹配位置只能通过最大相似度值获得。

若要匹配多个目标,设置合理的阈值,只要相似度大于阈值,则认为是匹配目标。

# cv2中使用matchTemplate匹配模板 result = cv2.matchTemplate(target,template,cv2.method) 

提供了六种

  • :该方法计算了模板与子图对应像素的平方差。因此,最佳匹配结果为0,相似值越小,匹配结果越差。

  • :该方法采用归一化平方差进行匹配,最佳匹配结果为0。

  • :该方法采用源图像与模板图像的卷积结果进行匹配,因此最佳匹配位置在值最大的地方,值越小,匹配结果越差。

  • :集成的相关匹配方法消除了亮度线性变化对相似度计算的影响。当图像和模板同时变量或变暗K倍时,结果可以保持不变。类似于相关匹配方法,最佳匹配位置也在值最大的地方,相似值越大。

  • :该方法采用源图像与平均值差、模板与平均值差的相关性进行匹配。最佳匹配结果等于1,最差匹配结果等于-1,值等于0直接表示两者无关。

  • :减去图像和模板的平均值,然后除以各自的方差,确保图像和模板分别改变光不影响计算结果,计算的相关系数限制在-1到1之间,1 表示完全相同,-1 两幅图像的亮度恰恰相反,0 表示没有线性关系。负值表示效果不好,正值表示匹配效果好。

#opencv模板匹配-单目标匹配 import cv2 #阅读目标图片 target = cv2.imread("target.jpg") #读取模板图片 template = cv2.imread("template.jpg") #获取模板图片的高宽尺寸 theight, twidth = template.shape[:2] #执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED result = cv2.matchTemplate(target,template,cv2.TM_SQDIFF_NORMED) #归一化处理 cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) #寻找矩阵(一维数组当做向量,用Mat定义)最大值和最小值的匹配结果及其位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
#对于cv2.TM_SQDIFF及cv2.TM_SQDIFF_NORMED方法min_val越趋近与0匹配度越好,匹配位置定点取min_loc,对于其他方法max_val越趋近于1匹配度越好,匹配位置取max_loc
strmin_val = str(min_val)
#绘制矩形边框,将匹配区域标注出来
cv2.rectangle(target,min_loc,(min_loc[0]+twidth,min_loc[1]+theight),(0,0,225),2)
#显示结果,并将匹配值显示在标题栏上
cv2.imshow("MatchResult----MatchingValue="+strmin_val,target)
cv2.waitKey()
cv2.destroyAllWindows()

FLANN特征点匹配

对图片提取SIFT特征并利用FLANN方法判别图像的相似度并可视化。

基于FLANN的匹配器(FLANN based Matcher)的特征匹配。FLANN库全称是Fast Library for Approximate Nearest Neighbors,它是目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自动选取最快算法的机制。

  • 使用SIFT特征提取关键点;
  • 计算SIFT特征描述子;
  • 使用FLANN匹配器进行描述子向量匹配。

的大概流程描述: 在图中选择出一些比较有特色的点,并把他们编码成特征向量,现在要做两个图的特征点匹配,所以要用SIFT对两个图分别做特征点选择,并且每个特征点编码成相同维度的特征向量,比如都是长度为512的向量。两个图上的特征点数量是不一样的,比如第一个图有3个特征点,第二个图有5个特征点,要做特征点匹配的话,计算第一个图中3个点跟第二个图里的5个点两两之间的距离,这个距离一般就是向量的欧式距离。特征点匹配中,就是要找两个图中比较相似的特征点,特征点的特征向量越相近,说明这两个点附近的情况就越相似。

的思想: 首先找到图一中某一个特征点在图二中的最相似点和次相似点,然后把最相近点的距离跟次相近点的距离相除,获得一个。ratio越小,就表示相近点比次相近点要更加相似很多,相反ratio越大,就表示相近点比次相近点都是一般相似。ratio test就是用ratio值去筛选,它认为:。因为ratio小的特征点对,说明最相近点比其它匹配点(次相近点在这里就代表了其它所有的特征点)都要明显很多,说明这一对匹配是非常有特色的,是可以保留的,保留了基本不会错,因为没有其它干扰因素;ratio比较大的时候,就说明这对匹配是存疑的,把最相近点换成次相近点的相似度也差不多,所以无法断定这一对特征点有没有匹配错,那么就把其筛选掉。Lowe推荐ratio的阈值为0.8。

FLANN特征匹配

我这边是有五个类的模版图,在目标图中进行特征匹配,判断属于哪一个类。我的思路则是依次进行特征匹配,比较最后特征点对点多少,从而判断更接近哪一类别。

import cv2
import os
from matplotlib import pyplot as plt

def FLANN():
    # flags=0 
    # 灰色读入目标图像
    targetPath = 'target.jpg'
    trainingImage = cv2.imread(targetPath, flags=0)
    # 灰色读所有模板图片
    templatePath = 'templatePath/'
    icons = os.listdir(templatePath)
    iconMatch= dict({ 
        'name': '未识别', 'value': 0})
    for icon in icons:
        queryImage = cv2.imread(templatePath + icon, 0)
        # 使用SIFT 检测角点
        sift = cv2.SIFT_create()
        kp1, des1 = sift.detectAndCompute(queryImage, None)
        kp2, des2 = sift.detectAndCompute(trainingImage, None)
        # 设置FLANN匹配器参数,定义FLANN匹配器,使用 KNN 算法实现匹配
        indexParams = dict(algorithm=0, trees=5)
        searchParams = dict(checks=50) 
        flann = cv2.FlannBasedMatcher(indexParams,searchParams)
        matches = flann.knnMatch(des1,des2,k=2)

        # 根据matches生成相同长度的matchesMask列表,列表元素为[0,0]
        matchesMask = [[0,0] for i in range(len(matches))]
        matchNumber = 0
        # 去除错误匹配, 此处阈值设定为0.7
        for i,(m,n) in enumerate(matches):
            if m.distance < 0.7 * n.distance:
                matchesMask[i] = [1,0]
                matchNumber = matchNumber+1
        
        # 将图像显示
        # matchColor是两图的匹配连接线,连接线与matchesMask相关
        # singlePointColor是勾画关键点
        drawParams = dict(matchColor = (0,255,0), matchesMask = matchesMask[:50], flags = 0)
        resultImage = cv2.drawMatchesKnn(queryImage,kp1,trainingImage,kp2,matches[:50],None,**drawParams)

        if matchNumber > iconMatch['value']:
            iconMatch['name'] = icon.split('_')[0]
            iconMatch['value'] = matchNumber

    return resultImage, iconMatch


if __name__ == '__main__':
    resultImage, res = FLANN()
    plt.imshow(resultImage)
    plt.show()

标签: 0871匹配哪种连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台