s1lencee 发表于 2024-4-11 11:35

[验证码识别]相似度模型匹配的替代方案-特征匹配

# [验证码识别]相似度模型匹配的替代方案-特征匹配

> #### 本文章所有内容仅供学习和研究使用,本人不提供具体模型和源码。若有侵权,请联系我立即删除!维护网络安全,人人有责。

---

## 前言

在我之前图标点选验证码的识别中,参考图标和目标图标匹配一般使用的是相似度模型,但是如果遇上多个目标图标,消耗时间会成倍增加。

在我的计算机上,推理一对图片的相似度平均需要35ms(与CPU性能有关),如果有5个目标图标和3个参考图标就需要大约500ms的时间,即使使用批处理模型也只能稍微加快推理速度。

当然优化孪生神经网络主干或许可以增加速度,但是有没有其他方法能进行相似度匹配呢?

**孪生神经网络的一个重要步骤是特征提取,那么有没有其他的特征匹配算法呢?**

**通过搜索,特征匹配算法有ORB、SIFT、SURF等,本文以SIFT为主**

> 本文主要讲述特征匹配的实现和相似度模型匹配的对比,不重点讲述特征匹配的原理

## SIFT特征匹配实现

由于opencv编译较为麻烦,本文使用python的opencv-python库实现,而且SIFT是非自由算法,在一些版本的cv中是不存在的。

我的opencv版本如下,仅用于参考
```
opencv-python==4.5.5.64
opencv-contrib-python==4.5.5.64
```

匹配代码如下
```python
import cv2


icon = cv2.imread("icon.jpg")# 参考图标
target = cv2.imread("target.jpg")# 目标图标
icon = cv2.resize(icon, (160, 160))# 两张图片的长宽建议要一样
target = cv2.resize(target, (160, 160))

# 实例化SIFT
sift = cv2.SIFT_create()
# 找出关键点并计算描述符
kp1, des1 = sift.detectAndCompute(icon, None)
kp2, des2 = sift.detectAndCompute(target, None)

# 匹配对象
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)# kNN匹配
good = []
for m, n in matches:
    if m.distance <= .88 * n.distance:
      good.append()
print(len(good))
# 绘制匹配图像
draw = cv2.drawMatchesKnn(icon, kp1, target, kp2, good, None)
cv2.imshow("sift", draw)
cv2.waitKey(0)
```
运行结果如下



可以看到,SIFT在两张图片中提取了许多特征点,但是这些特征点如何关联起来呢? 这就要用到kNN匹配

**kNN算法的核心思想(抄网上的):**

**如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。**

我们可以过滤错误的匹配点,再计算匹配点的数量,就可以视为这两张图的相似度了

## 提取两张图片的匹配度

通过上面代码已经可以计算两张图片的匹配度了,然后就可以将需要比较的图片进行匹配,过程和相似度模型是一样的。

**值得注意的是,颜色会影响匹配结果。**



不仅仅是颜色,参考图标和目标图标的形状也要基本相同,如果有形变也会影响匹配结果

如果颜色相反可以使用一下函数转换

```python
def inverted(img):
    """cv2进行反色操作"""
    if len(img.shape) == 3:
      h, w, c = img.shape
      img2 = np.zeros((h, w, c), dtype='uint8')
    else:
      # 单通道图片
      h, w = img.shape
      img2 = np.zeros((h, w), dtype='uint8')
    invert_image = cv2.addWeighted(img, -1, img2, 0, 255, 0)
    return invert_image
```



中间图片是右边图片反色操作后的结果

以下是一些不同厂商图标验证码的匹配结果







> 实际上这些特征点还和图片大小有关。

## 验证码识别

与孪生一样,我们可以把所有图标两两匹配,得到一个匹配度的矩阵,然后依次获取最大匹配值即可(在我之前的文章有提到过)

本文我以某盾的图标点选为例。



可以看到,图片上的图标有黑色和白色,并且参考图标也提供了两张颜色,位置也是固定的。

**我们可以先通过目标检测获取所有目标图标,用算法判断是黑色还是白色图标,再用对应颜色的参考图标和其进行特征匹配即可。**

为了方便起见,我在目标检测模型中就区分了黑色和白色



我们有了目标的图标颜色后,可以将对应颜色的图标裁剪下来进行比较





并且通过计时可以发现,SIFT算法计算两张图片匹配度耗时在5-10ms之间,效率远大于相似度模型匹配。


## 与相似度模型匹配的比较

|    | 相似度模型匹配                           | 特征提取匹配                                             |
|:--:|:------------------------------------|:-----------------------------------------------------|
| 优点 | 1.能够匹配不同颜色、形状(关键在于数据集)<br/>2.抗干扰能力强 | 1.速度快、计算量小<br/>2.无需收集数据集                           |
| 缺点 | 1.识别速度慢,计算量大<br/>2.数据集难以收集,训练周期较长   | 1.无法匹配不同颜色、形状的图片,对于噪声和图标变形等干扰较为敏感<br/>2.抗干扰能力差,稳定性较低 |

**在实际应用中,需要根据具体场景和需求选择合适的匹配方法,权衡其优缺点,以达到最佳的识别效果。**

## 其他的特征匹配算法

如果对应速度的要求更高,可以尝试SURF算法

**SURF算法相比于SIFT算法具有更快的计算速度,特别是在特征提取和匹配方面。 与SIFT类似,SURF特征对于尺度和旋转的变化都能匹配。**

**但是SURF算法提取的特征数量较少,可能导致匹配的准确性有所降低。**

> 以上两种算法都受到专利保护,请勿用于商业用途!

## 总结

程序员圈流行一句话:“不要重复发明轮子”,当轮子的形状确定后,再发明其它形状的轮子就没有意义了,改进轮子才是重点。

所以,我们都是站在巨人的肩膀上。

**如果有更好的方案,欢迎各位大佬讨论,共同探索更优秀的解决方案。**

debug_cat 发表于 2024-4-11 17:03

大佬,可以出一些图找图模板匹配案例,和怎么改进匹配方案,我现在匹配很奇怪,很明显的特征但是匹配的点数居然是0,然后template可以找到。这情况小白应该怎么处理呢。

VnYzm 发表于 2024-4-11 12:58

SIFT专利已经过期了,可以随便用。此外SIFT这些算法好像没有GPU版本,如果有独显的话还是跑神经网络效率更高。

Pwaerm 发表于 2024-4-11 11:44

很想用,很复杂,先收藏

{:301_997:}

谢谢楼主分享

onlyclxy 发表于 2024-4-11 11:57

正好前一阵刚接触这种图像识别的... 赶巧了. 先收藏.. 感谢!

鹏路翱翔 发表于 2024-4-11 12:12

很实用,学习一下~

riluoxingchen 发表于 2024-4-11 12:35

膜拜大佬,虽然我看不懂{:301_1009:}

chrisdong919 发表于 2024-4-11 12:54

学习一下

T4DNA 发表于 2024-4-11 12:55

这个似乎可以用于字体加密

LoongKing 发表于 2024-4-11 12:55

SURFSIFT 没有后续发展吗?没有和深度学习结合起来吗?

qwq23496 发表于 2024-4-11 13:04

很详细,学习学习
页: [1] 2 3 4 5 6 7
查看完整版本: [验证码识别]相似度模型匹配的替代方案-特征匹配