首页 > 其他分享 >某滑块验证码识别思路(附完整代码)

某滑块验证码识别思路(附完整代码)

时间:2024-12-10 10:57:28浏览次数:9  
标签:gray bg img 滑块 image cv2 验证码 识别

思路

验证码类型如下:

大概搜索了下,有两种主流思路:yolo目标检测算法和opencv模版匹配。很明显第二种成本远小于第一种,也不需要训练。

而且这种验证码有干扰(两个目标点),yolo一次还不能直接到位,还得进一步处理。我在搜索的时候还有用轮廓匹配做识别的,但是实测下来准确率很低,这里就不说了。

识别

背景预处理

先对图片做一些预处理,移除多余的干扰项, 提高准确率。比如先简单将图片切割一下,只保留包含滑块的那一部分。这么说可能不太理解,不识别之前怎么知道哪一部分包含滑块?我截图标一下大家就明白了,可以只保留中间这一块。

网页知道滑块放置的位置,说明服务器告诉了它准确的y坐标,看了下接口返回的结果里有一个tip_y应该是跟滑块放置的y坐标有关。滑块的具体位置可以在元素一栏里看到(em这个单位和px换算规则是 px = em * 字体大小,从网页上看字体大小是100px)

但tip_y的值是69,和85px对不上。这里可以打上属性修改断点,看一下属性是怎么生成的,但我找了半天没找到,最后复制多个值发给gpt让他说一下有什么规律。它说比例是固定的,也就是tip_y乘以1.23就是放置的y坐标

当然还有个简单的方法就是用浏览器获取滑块的坐标,这样就不用关心两个值有啥规律。

那就可以得到裁剪的位置了:

from PIL import Image


def crop_main_loc(background_path:Image, slide_path:Image, tip_y:int):
    background_img = Image.open(background_path)
    slide_img = Image.open(slide_path)
    top_y_212 = tip_y * (85 / 69)
    top_y_344 = int(top_y_212 * (344 / 212))
    crop_size = (0, top_y_344, background_img.width, top_y_344+slide_img.height)
    cropped_image = background_img.crop(crop_size)
    cropped_image.show()


if __name__ == '__main__':
    crop_main_loc('background.jpeg', 'slide.png', 69)

滑块预处理

先提取一下滑块的轮廓,抖音的滑块特征很明显,可以不用用cv2.Canny来提取边缘特征。

具体步骤如下:

  1. 去除外围透明像素点(滑块外层的像素点的a值都是0)
  2. 将图片转成灰度图并进行二值化操作(0和255)
  3. 只保留二值化为255的像素点
  4. 去除多余噪声

代码

读取rgba格式的滑块

import cv2
input_img = cv2.imread("slide.png", cv2.IMREAD_UNCHANGED)

将透明值为0的像素点设置为纯黑色

# 取透明维度的值
alpha_channel = input_img[:, :, 3]
# 只使用rgb三个维度的值
rgb_image = input_img[:, :, :3]
rgb_image[alpha_channel == 0] = [0, 0, 0] 

提取白色边缘并设置成黑色,将其他像素点设置为白色

gray = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2GRAY)
_, thresholded = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY)
white_img = np.ones_like(rgb_image) * 255
white_img[thresholded == 255] = [0, 0, 0]  

去除噪声(判断某个黑色像素点周围3x3范围内有多少个黑色像素点,少于阈值认为是噪声)

def count_black_neighbors_by_cv2(gray_image):
    if gray_image.ndim == 3:
        gray_image = cv2.cvtColor(gray_image, cv2.COLOR_BGR2GRAY)
    _, binary_image = cv2.threshold(gray_image, 240, 255, cv2.THRESH_BINARY_INV)
    binary_image = binary_image // 255  
    kernel = np.ones((3, 3), dtype=np.uint8)
    kernel[1, 1] = 0 
    black_neighbors = cv2.filter2D(binary_image, -1, kernel)
    # 设置边缘为0
    black_neighbors[:, 0] = 0
    black_neighbors[:, 109] = 0
    return black_neighbors

当然也可以通过遍历来实现,这样更容易理解点

def count_black_neighbors_by_range(gray_image):
    # 将图像转换为灰度图
    if len(gray_image.shape) == 3:
        gray_image = cv2.cvtColor(gray_image, cv2.COLOR_BGR2GRAY)
    # 二值化图像
    _, binary_image = cv2.threshold(gray_image, 240, 255, cv2.THRESH_BINARY_INV)
    binary_image = binary_image // 255 
    # 创建一个与输入图像大小相同的全零数组
    black_neighbors = np.zeros_like(binary_image)

    # 遍历图像中的3x3邻域,计算每个像素
    neighbor_offsets = [(-1, -1), (-1, 0), (-1, 1),
                        (0, -1),          (0, 1),
                        (1, -1), (1, 0), (1, 1)]

    # 遍历每个像素
    rows, cols = binary_image.shape
    for row in range(1, rows - 1):
        for col in range(1, cols - 1):
            # 当它本身不是黑色像素点的时候,就不计算
            if binary_image[row, col] != 1:
                continue
            count = 0
            for offset in neighbor_offsets:
                neighbor_row, neighbor_col = row + offset[0], col + offset[1]
                if binary_image[neighbor_row, neighbor_col] == 1:
                    count += 1
            black_neighbors[row, col] = count

    return black_neighbors
    
black_neighbors = count_black_neighbors_by_range(white_img)
output = np.ones_like(rgb_image) * 255
output[black_neighbors > 4] = 0

正题

好了,现在可以把上面看到的内容忘掉了,因为在实际识别的时候用不到(我发现不做处理比做处理识别的准确率要高很多),直接识别准确率甚至接近百分百了。

至于为啥还写上面的内容,主要是我花时间研究了,总要写出来,万一下次用到又忘了呢。还有就是凑个字数。

完整代码

下面是识别的完整代码

import os
import cv2


def get_slide_distance(bg_path, slide_path):
    '''
    识别滑块具体位置,返回位置比例: 位置/图片宽度
    使用的时候再乘以实际图片宽度即可
    '''
    bg_img = cv2.imread(bg_path)
    sd_img = cv2.imread(slide_path)
    bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY)
    bg_gray = cv2.GaussianBlur(bg_gray, (5, 5), 0)
    bg_edge = cv2.Canny(bg_gray, 30, 100)
    rgb_bg_gray = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    
    sd_gray = cv2.cvtColor(sd_img, cv2.COLOR_BGR2GRAY)
    sd_gray = cv2.GaussianBlur(sd_gray, (5, 5), 0)
    sd_edge = cv2.Canny(sd_gray, 30, 100)
    rgb_sd_gray = cv2.cvtColor(sd_edge, cv2.COLOR_GRAY2RGB)
    result = cv2.matchTemplate(rgb_bg_gray, rgb_sd_gray, cv2.TM_CCORR_NORMED)
    _, _, _, max_loc = cv2.minMaxLoc(result)
    cv2.rectangle(bg_img, (max_loc[0], max_loc[1]), (max_loc[0]+110, max_loc[1] + 110),
        (0, 255, 0), 2)
    result_path = os.path.join(os.path.dirname(bg_path), "result.png")
    cv2.imwrite(result_path, bg_img)
    return max_loc[0]/bg_gray.shape[1]

cv2.matchTemplate

核心函数就是cv2.matchTemplate,它是用来做模版匹配的,通俗点说是在一个图中找出另一张图,看一下gpt的参数解释:

不知道哪个参数更好,可以都测试一下。我看网上用的都是cv2.TM_CCORR_NORMED,效果如下:

TM_CCORR_NORMED

测试下来后面四个效果都不错,只有cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED效果很差:

``

流程图

为了更清晰的知道这段代码做了什么,可以将中间步骤处理过程都保存下来:

cv2.cvtColor(cv2.COLOR_BGR2GRAY是将bgr格式的图片转为灰度图):

cv2.GaussianBlur(高斯滤波做模糊处理):

cv2.Canny(边缘检测,参数可以自己调节看看,第一个是最小值,第二个是最大值,如果值给的太高保留下来的线就很少):

本文由博客一文多发平台 OpenWrite 发布!

标签:gray,bg,img,滑块,image,cv2,验证码,识别
From: https://www.cnblogs.com/kanadeblisst/p/18596859

相关文章

  • 说说你对人脸识别的理解或者对原理的理解
    人脸识别,从前端开发的角度来看,主要涉及到图像采集、预处理和与后端API的交互。核心算法和模型训练通常在后端完成。我理解的人脸识别原理,以及前端开发中需要注意的点如下:一、人脸识别原理(后端为主)人脸识别大致分为以下几个步骤:人脸检测(FaceDetection):从图像或视......
  • PbootCMS如何取消留言、自定义表单的验证码?
    在PbootCMS中,验证码可以增加系统的安全性,但在某些情况下,你可能希望取消留言表单和自定义表单中的验证码,以简化用户操作。以下是如何在PbootCMS中取消这些验证码的详细步骤和注意事项。登录PbootCMS后台:打开浏览器,访问你的PbootCMS后台登录页面(通常是 你的域名/admin)。输入......
  • 字体图片批量生成-字体识别模型数据
    众所周知,我们的文字有各种字体,字体通过字体文件方式供操作系统使用,在需要使用字体图片的场景,我们如何快速生成呢?这篇文章介绍下,如何通过操作系统自带的字体文件,利用python的pillow包快速生成字体图片。各操作系统字体文件路径windows\linux\macos:dirs=[]ifsys.platform......
  • 垃圾溢出监测识别摄像机
    垃圾溢出监测识别摄像机是一种应用于城市环境管理的智能设备,它能够帮助城市管理部门实时监测垃圾桶的填充情况,及时发现溢出情况并作出响应。该设备通常采用计算机视觉技术,结合图像识别算法,能够准确地识别垃圾桶的填充程度和溢出情况。在实际使用中,垃圾溢出监测识别摄像机首先会......
  • 河道漂浮物监测识别摄像机
    河道漂浮物监测识别摄像机利用先进的图像识别技术,通过智能算法,可以在河道和湖泊表面捕捉到漂浮的垃圾、塑料瓶、树叶等各种漂浮物,进行自动识别和提醒相关管理人员及清理,从而为环保部门提供准确的监测数据。河道漂浮物监测识别摄像机的应用具有诸多优势。首先,它能够大大减少对人......
  • 人流量监测识别摄像机
    人流量监测识别摄像机是一种基于人工智能技术的智能监控设备,其主要功能是通过摄像头捕捉实时画面,利用深度学习算法对画面中的人数进行实时识别和统计。这种摄像机可以广泛应用于各种场合,如商场、车站、学校、医院等公共场所,以及工厂、仓库等生产环境中,帮助管理者更好地了解实时人......
  • 工作服穿戴识别摄像机
    工作服穿戴识别摄像机是一种利用先进技术来识别和管理员工穿戴工作服的摄像机。这种摄像机通常包括使用RFID技术或者人脸识别技术,通过识别员工的身份和穿戴的工作服来确保员工符合安全规定和标准。工作服穿戴识别摄像机可以提高工作场所的安全性和管理效率:工作服穿戴识别摄像机是......
  • 船只监测识别摄像机
    船只识别监测摄像机是一种用于监测和识别船只的设备,它通过视频图像识别技术和智能算法来实现对船只的实时监测和识别。这种摄像机通常安装在海洋监测平台、港口码头、海岸线、湖泊、河道等位置,用于实现对船只航行情况的监测和跟踪。船只识别监测摄像机的工作原理是通过摄像头捕......
  • Burp(8)-验证码爆破插件
    声明:学习视频来自b站up主泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec团队的教学视频地址:burp(6)暴力破解与验证码识别绕过_哔哩哔哩_bilibili本文详细介绍验证码爆破插件captcha-killer-modified的使用。一、环境配置安装ddddocr和aiohttp模块安装命令:pipinstall......
  • Google PaliGemma 2 新增情绪识别能力;OpenAI 即将发布全新 Sora 视频生成器丨 RTE 开
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编......