完整代码

import cv2

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

def verification(src, model):
    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(src, None)
    kp2, des2 = sift.detectAndCompute(model, None)

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

    ok = []
    for m, n in matches:
        if m.distance < 0.8 * n.distance:
            ok.append((m, n))

    num = len(ok)
    if num >= 500:
        result = "认证通过"
    else:
        result = "认证失败"
    return result

if __name__ == "__main__":
    src1 = cv2.imread("scr1.bmp")
    cv_show('src1', src1)
    src2 = cv2.imread("scr2.bmp")
    cv_show('src2', src2)
    model = cv2.imread("model.bmp")
    cv_show('model', model)

    result1 = verification(src1, model)
    result2 = verification(src2, model)
    print("src1验证结果为:", result1)
    print("src2验证结果为:", result2)

导入库与显示函数

定义图片显示函数cv_show

import cv2

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

认证函数 verification

这是整个程序的核心,它接收两张图像(待验证图 src 和模板图 model),返回“认证通过”或“认证失败”。

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(src, None)
kp2, des2 = sift.detectAndCompute(model, None)
  • cv2.SIFT_create():创建 SIFT检测器,它能找出图像中独特的角点、斑点等关键区域。
  • detectAndCompute:同时检测关键点(keypoints)并计算描述子(descriptors)。kp1 是 src 的关键点列表,des1 是对应的 128 维特征向量矩阵;同理 kp2 和 des2 是 model 的。

进行 kNN 匹配

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

对于 des1 中的每个特征点,在 des2 中找到距离最近的两个匹配点

筛选优秀匹配

ok = []
for m, n in matches:
    if m.distance < 0.8 * n.distance:
        ok.append((m, n))

如果最近距离 m.distance 小于次近距离 n.distance 的 0.8 倍,则认为这个匹配是“良好”的。
满足条件的匹配对存入 ok 列表,num = len(ok) 就是最终筛选出的可靠匹配点数量。

根据匹配数判定结果

if num >= 500:
    result = "认证通过"
else:
    result = "认证失败"
return result

如果可靠的匹配点数 大于等于 500,则认为两张图片内容足够相似,认证通过;否则失败。

主程序测试

if __name__ == "__main__":
    src1 = cv2.imread("scr1.bmp")
    cv_show('src1', src1)
    src2 = cv2.imread("scr2.bmp")
    cv_show('src2', src2)
    model = cv2.imread("model.bmp")
    cv_show('model', model)

    result1 = verification(src1, model)
    result2 = verification(src2, model)
    print("src1验证结果为:", result1)
    print("src2验证结果为:", result2)

调用 verification 函数,将 src1 与 model 比较,src2 与 model 比较。
运行结果:
在这里插入图片描述

src1验证结果为: 认证通过
src2验证结果为: 认证失败

如果匹配数始终达不到阈值,可以尝试降低比值阈值或减少要求数量。

补充

对于指纹库来说,我们还可以添加一个for循环语句进行匹配或者识别。
指纹库:
在这里插入图片描述

待识别指纹:

在这里插入图片描述

指纹识别代码:

import os
import cv2

def getNum(src, model):
    img1 = cv2.imread(src)
    img2 = cv2.imread(model)
    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)
    flann = cv2.FlannBasedMatcher()
    matches = flann.knnMatch(des1, des2, k=2)
    ok = []
    for m, n in matches:
        if m.distance < 0.8 * n.distance:
            ok.append(m)
    num = len(ok)
    return num

def getID(src, database):
    max = 0
    name = ""
    for file in os.listdir(database):
        model = os.path.join(database, file)
        num = getNum(src, model)
        print("文件名:", file, "匹配点个数:", num)
        if num > max:
            max = num
            name = file
    ID = name[0]
    if max < 200:
        ID = 9999
    return ID

def getName(ID):
    nameID = {0: '张三', 1: '李四', 2: '王五', 3: '赵六', 4: '朱老七', 5: '钱八',
              6: '曹九', 7: '王二麻子', 8: 'andy', 9: 'Anna', 9999: '没找到'}
    name = nameID.get(int(ID))
    return name

if __name__ == "__main__":
    src = "scr.bmp"
    database = "database"
    ID = getID(src, database)
    name = getName(ID)
    print("识别结果为:", name)

运行结果:

文件名: 0.bmp 匹配点个数: 110
文件名: 1.bmp 匹配点个数: 162
文件名: 2.bmp 匹配点个数: 159
文件名: 3.bmp 匹配点个数: 160
文件名: 4.bmp 匹配点个数: 142
文件名: 5.bmp 匹配点个数: 200
文件名: 6.bmp 匹配点个数: 149
文件名: 7.bmp 匹配点个数: 931
文件名: 8.bmp 匹配点个数: 178
文件名: 9.bmp 匹配点个数: 141
识别结果为: 王二麻子
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐