当前位置: 首页 > article >正文

旋转验证码截图识别

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路
如有侵犯,请联系作者下架

本文识别已同步上线至OCR识别网站: http://yxlocr.nat300.top/ocr/other/27

之前写过一篇文章,某东黑边旋转验证码识别,识别思路还是一样,基于梯度的计算,大家看这篇文章可以复习下这篇,链接如下:京东黑边背景旋转验证码识别,本文开始前,先声明一下,本文提供思路,不会放完整代码,有的小伙伴拿我的思路去GPT或者别的大模型那反推,你推出来没有关系,但是你推出来准确率低,来找我要源码,说什么我推出来迟早能做出来,还不如给他源码,什么恶心人的逻辑,还是为了自己卖课用,如此自傲,能推出来一时推不了一世,换个样子你就不会做了,还是老老实实打基础学思路,才能灵活应变

先来看截图验证码部分数据集
在这里插入图片描述
在这里插入图片描述
这里讲解识别思路前,需要注意一个地方,因为是截图,每个设备分辨率以及截图方式的不同,会导致算法准确度有差异,所以在ocr的demo网站中我上传了三种思路方式,识别方式各有差异,可能你的第一种方式准确率有80,他的第二种方式有80,并且整体截图识别的准确率也无法保证到很高,原因除了上述讲的一种外,还有就是整体图库是很大的

识别思路

注意:本文解决方法为ocr识别网站第一种方式,切图边缘sobel梯度

1、取出旋转缺口

取出旋转接口只要根据黑边的特征去取就可以了,从图中心开始,往外计算黑边圆,使用霍夫圆检测,下面我直接放出代码,以下图作为demo演示
在这里插入图片描述

def get_radius(image):
    center_tolerance = 10

    height, width = image.shape[:2]
    image_center = (width // 2, height // 2)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    blurred = cv2.GaussianBlur(gray, (3, 3), 2)

    circles = cv2.HoughCircles(
        blurred,  # 输入图像
        cv2.HOUGH_GRADIENT,  # 检测方法
        dp=1,  # 分辨率与图像分辨率的反比
        minDist=20,  # 圆心之间的最小距离
        param1=100,  # Canny边缘检测的高阈值
        param2=30,  # 圆心检测的阈值
        minRadius=90,  # 最小半径
        maxRadius=1100  # 最大半径
    )
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            center = (i[0], i[1])
            radius = i[2]

            # 计算圆心与图像中心点的距离
            distance = np.sqrt((center[0] - image_center[0]) ** 2 + (center[1] - image_center[1]) ** 2)

            # 如果圆心距离图像中心在允许范围内,则保留该圆
            if distance <= center_tolerance:
                return radius
    
    # 如果检测不到,则输出一个大部分通用半径
    return 173

取出圆后,效果如下
在这里插入图片描述

2、边缘降噪

边缘降噪还是和之前的方式类似,从市面上这么多验证码来看,大致常用的几种方式为(切割小圆、消除黑边、色域转换),本文采用切割小圆+消除黑边的形式,具体为切割小圆后,去除小圆周围的黑边,并等比例放大

# 切割小圆
imagearray_que = split_cicle(imagearray_que, radius - 3)
imagearray_que = large_img(imagearray_que, 1.04)
# 缩小大图,消除黑边
imagearray_bg = bg_circle(imagearray_bg, radius, renum=.93)

通过上述方法后,小圆和背景图如下:
在这里插入图片描述
在这里插入图片描述

3、计算最小梯度

最小梯度还是和以前一样,万年不变的老套路,具体步骤思路可以看下代码


def merge_img(que_result, bg_image, radius, angle):
    # 根据角度将圆放置到背景图中
    que_height, que_width = que_result.shape[:2]
    # 计算旋转矩阵
    rotation_matrix = cv2.getRotationMatrix2D((que_width / 2, que_height / 2), angle, 2)
    # 应用旋转矩阵进行旋转
    xuanzhuan_result = cv2.warpAffine(que_result, rotation_matrix, (que_width, que_height))
    center = (bg_image.shape[1] // 2, bg_image.shape[0] // 2)
    # 创建掩膜图像,尺寸与背景图像一致
    mask = np.zeros_like(bg_image[:, :, :])
    cv2.circle(mask, center, radius, 255, 0)  # 在掩膜中画圆
    # 计算旋转后的图像放置位置
    bg_height, bg_width = bg_image.shape[:2]
    circle_height, circle_width = xuanzhuan_result.shape[:2]
    # 创建掩膜区域
    mask_overlay = np.zeros_like(bg_image[:, :, 0])
    # 将掩膜区域扩展到三通道
    mask_overlay = cv2.merge([mask_overlay] * 1)
    # 创建一个与背景图像相同尺寸的全透明图像
    result_with_que = np.copy(bg_image)

    return result_with_que

def calculate_gradient_difference(result, circle_radius):
    """计算内外圆的梯度差异"""
    center_x = result.shape[1] // 2
    center_y = result.shape[0] // 2

    # 创建内外圆遮罩
    circle_inner_mask = np.zeros_like(result, dtype=np.uint8)
    cv2.circle(circle_inner_mask, (center_x, center_y), circle_radius - 10000, 255, 255)
    circle_outer_mask = np.zeros_like(result, dtype=np.uint8)
    cv2.circle(circle_outer_mask, (center_x, center_y), circle_radius + 10000, 255, 255)
    
    # 分别计算内外圆的梯度
    inner_pixels = cv2.bitwise_and(result, circle_inner_mask)
    outer_pixels = cv2.bitwise_and(result, circle_outer_mask)

    inner_sobel_x = cv2.Sobel(inner_pixels, cv2.CV_64F, 255, 255)
    inner_sobel_y = cv2.Sobel(inner_pixels, cv2.CV_64F, 255, 255)
    inner_gradient_magnitude = cv2.magnitude(inner_sobel_x, inner_sobel_y)

    gradient_diff = np.sum(inner_gradient_magnitude)
    return gradient_diff
    
for angle in range(0, 360, 5):
    # 将圆叠加到
    背景图中
    image = merge_img(imagearray_que, imagearray_bg, int(radius), angle)
    
    gradient_diff = calculate_gradient_difference(image, int(radius))
    if gradient_diff < min_diff:
        min_diff = gradient_diff
        min_l = angle
        
pred_str = min_l

通过计算后,再将正确角度覆盖到背景中展现,如下
在这里插入图片描述

4、结语

如果使用原图,准确率至少可达到90,所以能拿到原图不要死磕截图了,不过截图的识别整体过程确实更有意思,因为你不知道你的图像算法对于整体体征到底好不好用,有时候可能不是你的算法不要用,是截图截的太屎了,如果本文还有没有介绍到的地方,欢迎提出


http://www.kler.cn/a/579624.html

相关文章:

  • ⭐LeetCode(数学分类) 48. 旋转图像——优美的数学法转圈(原地修改)⭐
  • Easysearch 使用 AWS S3 进行快照备份与还原:完整指南及常见错误排查
  • 蓝桥杯[每日两题] 真题:好数 神奇闹钟 (java版)
  • 【微知】如何根据内核模块ko查看所依赖其他哪些模块?(modinfo rdma_ucm |grep depends)
  • 【Java学习】包装类
  • 基于策略模式的智能提示语生成器设计与实现——以Tkinter GUI开发为例
  • 一文了解汽车图像传感器
  • 1-002:MySQL InnoDB引擎中的聚簇索引和非聚簇索引有什么区别?
  • 逐梦DBA:Linux下MySQL字符集的处理
  • OkHttp 之任务调度模块源码分析
  • 为php添加额外的功能模块
  • 论文阅读笔记——OpenVLA: An Open-Source Vision-Language-Action Model
  • YC 孵化项目 Pinch:实时语音翻译视频会议平台;Mistral OCR:能处理多语言多模态复杂文档丨日报
  • 数据量过大的时候导出数据很慢
  • 链式多分支规则树模型结构
  • robotjs获取鼠标位置
  • c++介绍锁四
  • 快速排序(二叉树的前序递归遍历思想)
  • 【three.js】动画系统完全指南 - 从事件循环到工业级动画架构
  • MobileBERT: 一种适用于资源有限设备的紧凑型任务无关BERT