Python OpenCV 图片滑块验证码 滑块图片验证码 快速自动识别方案 代码简单 模板匹配识别 识别成功率达90%+

本文介绍了一种使用Python OpenCV的模板匹配方法来自动化识别图片滑块验证码的方案,详细阐述了OpenCV模板匹配的原理和实现过程,以及通过测试表明该方法的成功识别率可达85%以上。
摘要由CSDN通过智能技术生成

前言

通过上一篇的文章大家已经对图片滑块验证码已经有了初步的了解,图片滑块验证码的核心关键在于图片识别接下来接入讲解。因为初版滑块图片识别虽然能识别验证码,通过一些策略调整也相对提高了一些图片识别率,总的来说26%的识别率还是低。本文主要讲解通用滑块图片解决方案,通过Python OpenCV 图片滑块验证码 滑块验证码 自动识别方案 模板比对识别 识别成功率达85%+。

一、图片滑块验证功能分析

1、图片滑块验证功能概述

创建验证码接口请求后,返回主图和滑块图片地址

2、Web前端 显示 滑块和验证码背景图

3、滑块验证码 验证接口 传参

滑动滑块停止后获得x坐标,并以x坐标向服务端发起校验,下图为校验通过截图。

PS:其他内容不在累述,详细内容请看第一篇文章,接下来上上关键核心点。

二、图片滑块验证码 自动化识别方案 模板比对识别 分析与实现

2.1、OpenCV 模板匹配

2.1.1 OpenCV 模板匹配 简述

模板匹配就是在给定的图片中,查找和模板最相似的区域,算法的输入包括模板和图片,通过不断移动模板图片,计算其与图片对应区域匹配度,将匹配度最高区域选择为最终结果,详细内容请阅读下一篇博客。

2.1.2 OpenCV 模板匹配 实现

result=cv.matchTemplate( img,template,method)

参数:
1 > template :模板
2 > method: 实现模板匹配的算法,主要有:

1.平方差匹配(CV_TM_SQDIFF):利用模板与图像之间的平方差进行匹配,最好的匹配是0,匹配越差,匹配的值越大。
2.相关匹配(CV_TM_CCORR):利用模板与图像间的乘法进行匹配,数值越大表示匹配程度较高,越小表示匹配效果差。
3.利用相关系数匹配(CV_TM_CCOEFF):利用模板与图像间的相关系数匹配,1表示完美的匹配,-1表示最差的匹配。

注意:完成匹配后使用cv.minMaxLoc()方法查找最大值所在的位置即可,如果使用平方差作为比较方法,则最小值位置是最佳匹配位置。

2.2、OpenCV 模板匹配 示例代码

2.2.1 OpenCV 模板匹配 示例代码

import cv2

def getImageXindex(getBigImg,getSmallImg):
    # 获取验证码背景图
    bj_rgb = cv2.imread("./data/getBigImg.png")
    # 背景图片灰度处理
    bj_gray = cv2.cvtColor(bj_rgb,cv2.COLOR_BGR2GRAY)
    
    # 滑块验证码图片
    hk_rgb = cv2.imread("./data/getSmallImg.png",0)    # 以灰度模式加载图片

    # 模板匹配 TM_CCOEFF_NORMED  归一化相关匹配法
    res = cv2.matchTemplate(bj_gray,hk_rgb,cv2.TM_CCOEFF_NORMED)

    # 获取模板匹配值
    lo = cv2.minMaxLoc(res)
    print(lo)
    print(lo[3][0])


if __name__ == "__main__":
    # 滑块验证码 背景图
    getBigImg = "./data/getBigImg1.png"
    # 滑块验证码 滑块图
    getSmallImg = "./data/getSmallImg1.png"

    getImageXindex()

2.2.2 OpenCV 模板匹配 示例结果解析

> ython test.py
(-0.5933699011802673, 0.9847355484962463, (238, 143), (168, 110))
168

三、图片滑块验证码 自动化识别方案 模板比对识别 测试

3.1、滑块图片验证 自动识别率 部分测试代码示例

#!/usr/bin/env python
# -*- coding=utf-8 -*-
__author__ = 'Benjamin'
__CreateAt__ = '2022/8/2-14:06'

import threading
import requests
import random
import time
import test
import datetime

# 格式化Header头
def CheckStr(Header):
    Headers = {}
    for i in Header.split("\n"):
        if i != None or i != "" or i != '':
            data = i.split("\n")
            if data[0] != None or data[0] != '' or data[0] != '\n':
                twodata = data[0].split(": ")
                try:
                    Headers[twodata[0]] = twodata[1]
                except:
                    pass
    return Headers

GetHeaderP = CheckStr(open("headersMain", "r+").read())


# 多线程启动 下载 验证码背景图 和 滑块验证图片
def downloadImgThread():
    thread_list = []
    imgUrl = ["xxxx/imageCode/getBigImg","xxxxx/imageCode/getSmallImg"]
    imgName = ['getBigImg.png','getSmallImg.png']

    for iter in range(len(imgUrl)):
        thread_list.append(threading.Thread(target=downloadImg, args=(imgUrl[iter],imgName[iter])))

    for task in thread_list:
        task.start()
        task.join()


def downloadImg(imgUrl,imgName):
    url = "{}?0.{}".format(imgUrl,random.randint(1040385533093276,99210935326926565))
    getBigImg = requests.get(url=url, headers=GetHeaderP).content
    with open(imgName, 'wb') as f:
        f.write(getBigImg)


def RefreshImage():
    url = "xxx/imageCode/createImage"
    requests.post(url=url, headers=GetHeaderP).text

    downloadImgThread()


def setCode(getBigImg,getSmallImg):

    start = time.time()

    RefreshImage()

    x = test.getImageXindex(getBigImg,getSmallImg)

    rsp = checkCode(x)

    if "success" in rsp:
        end = time.time() - start
        print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),"第{}次校验成功,x坐标为:{},校验结果为:{},校验耗时:{}秒".format(str(i+1),str(x),str(rsp),str(round(end,2))))
        return True
    elif "fail" in rsp:
        end = time.time() - start
        print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),"第{}次校验失败,x坐标为:{},校验结果为:{},校验耗时:{}秒".format(str(i + 1), str(x), str(rsp), str(round(end, 2))))
        return False

    return False



def checkCode(xIndex):
    url = "/imageCode/checkCode"
    data = {"xIndex": xIndex}
    rsp = requests.post(url=url, headers=GetHeaderP, data=data).text
    return rsp


if __name__ == "__main__":

    # 滑块验证码 背景图
    getBigImg = "getBigImg.png"
    # 滑块验证码 滑块图
    getSmallImg = "getSmallImg.png"

    sucessList = []
    errorList = []
    forLen = 10
    for i in range(forLen):
        result = setCode(getBigImg,getSmallImg)
        if result:
            sucessList.append(result)
        else:
            errorList.append(result)
    print("len(sucessList):{},len(errorList):{},result:{}%".format(len(sucessList), len(errorList), round(len(sucessList)/forLen,2)*100))

3.2、OpenCV 图片模板匹配 测试结果展示

由于测试样本和次数单次采样结果不作为最终的评判标准,可能存在不匹配的情况。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BenjaminQA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值