某金采购平台滑块验证码识别

前言

遇到滑块验证码,使用ddddocrcv2一般都能快速搞定,它们处理滑块验证码的原理无外乎是:

  • 读取背景图片和缺口图片
  • 识别图片边缘
  • 转换图片格式
  • 缺口匹配

这篇博客提供了cv2处理滑块验证码的几个案例:不想用selenium处理滑块验证码?教你用cv2解决

不过某金采购平台滑块的验证码使用上面两个方式识别成功率太低了,干扰点太多导致匹配不对。

下图所示,灰色方块就是我们要定位到的缺口位置:

在这里插入图片描述

解决方案

如果从该站点来说,其实它已经有提供缺口位置了,它的反爬主要还是在参数加密上。

本着学习的态度假设下在未知的情况下自己要怎么解决:

  1. 使用yolo训练图片拿到缺口检测模型,这种实现起来不难,只要标记好数据集,百来张样本训练快成功率高,只是还要安装yolo环境,使用时还得加载模型。
  2. 前面opencv和ddddocr用缺口拼接的方式效果不好,那如果我们通过找到灰色区域面积最大的方式确定

缺口位置呢?这种方式有可行性。

方案实现

这里我就演示下方案2的实现方式,这里肯定没法使用ddddocr来实现,需要用opencv自定义开发实现。

将图片非灰色区域全部置为白色

这里要将图片转换为HSV色彩空间,这样就能使用掩码了,掩码能保留想要保存的像素区域

def gery_grap(image_path, lower_sat=0, upper_sat=50, lower_val=50, upper_val=200):
    # 读取图片
    img = cv2.imread(image_path)
    # 转换为HSV色彩空间
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)
    # 创建掩码:低饱和度(灰色)且中等亮度
    mask = (s >= lower_sat) & (s <= upper_sat) & (v >= lower_val) & (v <= upper_val)
    result = np.full_like(img, 255)
    result[mask] = img[mask]
    cv_show(result)

效果:

在这里插入图片描述

找到所有灰色区域轮廓

前面我们拿到的是灰色与白色区域图,由于灰色区域像素不一,这里我们要把所有灰色区域转成黑色,这样差异性更大,便于查找

灰度转换
gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)

在这里插入图片描述

图像二值化
ret, binary = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)

在这里插入图片描述

反转阈值
_, binary = cv2.threshold(binary, 180, 255, cv2.THRESH_BINARY_INV)

在这里插入图片描述

查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

这一步就能拿到所有白色区域的轮廓了,接下来就是遍历所有轮廓区域,计算得到最大面积的轮廓就是了。

最终结果

在这里插入图片描述

完整代码

def gery_grap(image_path, lower_sat=0, upper_sat=50, lower_val=50, upper_val=200):
    # 读取图片
    img = cv2.imread(image_path)
    # 转换为HSV色彩空间
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)
    # 创建掩码:低饱和度(灰色)且中等亮度
    mask = (s >= lower_sat) & (s <= upper_sat) & (v >= lower_val) & (v <= upper_val)
    result = np.full_like(img, 255)
    result[mask] = img[mask]

    gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)  # 图像转为灰度图
    ret, binary = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)  # 图像二值化
    _, binary = cv2.threshold(binary, 180, 255, cv2.THRESH_BINARY_INV)  # 反转阈值
    contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 查找轮廓

    # 初始化最大面积和对应轮廓
    max_area = 0
    max_contour = None

    # 遍历轮廓并计算面积
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > max_area:
            max_area = area
            max_contour = contour

    M = cv2.moments(max_contour)
    cx = int(M['m10'] / M['m00'])
    cy = int(M['m01'] / M['m00'])
    cv2.circle(img, (cx, cy), 5, (0, 255, 0), -1)
    return [cx, cy]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

九月镇灵将

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

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

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

打赏作者

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

抵扣说明:

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

余额充值