【教是最好的学】

19年第25周-用图像识别Opencv模板匹配搞定滑动验证码

2019-06-19  本文已影响0人  习惯研究所所长

1,先看结果

opencv图像识别-滑动验证码.gif

2,再看python图像识别代码

#!usr/bin/env python
# coding: utf-8
"""
-------------------------------------------------
   File Name:     文件名马赛克
   Description :
   Author :        Sanhuo
   date:          2019年6月19日
-------------------------------------------------
   Change Activity:
   - write your change updates in this. 
-------------------------------------------------
"""
import cv2
__author__ = 'Sanhuo'

def get_x_y(gaps_picture, big_picture, result_path="", is_show=False):
    """
    输入缺口图片和匹配的大图、图片的类型,返回缺口图片在大图的起点位置(x,y)
    :param gaps_picture: 缺口图片路径
    :param big_picture: 大图路径
    :param is_show: 默认不展示图片
    :return:
    """
    # 1, 数据输入:对图片进行预处理,灰度化分析
    gaps_temp = 'gaps_img_gray_temp.jpg'  # 用于可视化
    big_temp = 'big_img_rgb_temp.jpg'
    gaps_img_gray =  cv2.imread(gaps_picture, 0) # 0表示返回灰度图
    cv2.imwrite(gaps_temp, gaps_img_gray)  # 保存缺口图的灰度图
    w, h = gaps_img_gray.shape[::-1]

    big_img_rgb = cv2.imread(big_picture)  
    cv2.imwrite(big_temp, big_img_rgb)  # 相当于big_img的拷贝
    big_img_gray = cv2.imread(big_picture, 0)  
    
    # 2, 数据处理:图片识别匹配
    match_result = cv2.matchTemplate(gaps_img_gray, big_img_gray, cv2.TM_CCOEFF_NORMED)  # 归一化相关系数匹配
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match_result)  # 获取最佳匹配结果的坐标
    y_goal, x_goal = max_loc
    
    # 3, 数据输出:返回识别的结果,缺口图在大图的位置
    if is_show is True:
        show_result_img = cv2.imread(big_temp)
        cv2.rectangle(show_result_img, (y_goal, x_goal), (y_goal + w, x_goal + h), (0, 0, 255), 2)
        cv2.destroyAllWindows()
        cv2.imshow('Show_result', show_result_img)
        if result_path:
            # 保存结果
            cv2.imwrite(result_path, show_result_img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    return x_goal,y_goal


def main():
    for i in range(1,7):
        big_picture = "../docs/00{}.jpg".format(i)
        gaps_picture = "../docs/00{}_ans.png".format(i)
        result_path =  big_picture.replace(".jpg", "_output.jpg")
        x,y = get_x_y(gaps_picture=gaps_picture,big_picture=big_picture,result_path=result_path,is_show=True)
        print("X: {}, Y:{}".format(x,y))
    
    
if __name__ == "__main__":
    main()
    pass

3,然后分析

程序主要分为三步:
1,数据输入:这部分主要做些灰度处理的图片备份;
2,数据处理:这部分主要是调用cv2模块的模板匹配功能计算最佳匹配位置;
3,数据输出:这部分主要是数据可视化方面;

/其实每一个小程序无非就是三步,输入->处理->输出/

主要解释下第2步:数据处理方面
1,图片在计算里的本质是数组,图片的处理其实就是数组的处理。自然而言,对于python来说,Numpy是最好数组处理模块,CV2也同样的使用了numpy模块来处理。

2,图片识别包括机器学习里面的很厉害的图片识别算法CNN卷积神经网络,都离不开卷积。同样的这里采用的Opencv模板识别算法,也是依赖卷积。对于卷积不是很理解的可以看几年前写的卷积积分文章。谷歌直接搜或者百度直接搜索“卷积积分”,排在百科和知乎后面的就是啦。


卷积积分

3,Opencv的模板匹配,就一行代码。


啥?有三行,你一定看错了

这里opencv模板匹配还有其它的方法,截图如下


来源:https://zhuanlan.zhihu.com/p/62643151

数学原理啥的,我也讲不清楚,反正我是没找到通俗易懂的数学原理说明。
上面提到的,opencv模板匹配返回的是一个数组。
我输入的大图片尺寸是:600*300,缺口图:90*300,
opencv返回的是二维数组,但只有一行shape是(1,511)
511是这样来的,600-90+1,也就是模板匹配算法,要走511步,移动一步,就可以获取到与当前图片匹配程度值,然后求最可信的那个值的位置,就是缺口图应该放的位置。
所以,第二行求最大匹配的位置,求一维数组的的最大值。


求数组的最大值位置
这里如果是多维数组的话,那就用numpy的多维数组求最值索引。
求多维数据的最值位置

各位看官,如果看到,有啥想法,比如“我有一个想法”系列,可以一起交流哈!

上一篇下一篇

猜你喜欢

热点阅读