【爬虫】滑块缺口识别

滑块示例

在这里插入图片描述
分为背景图 和 滑块图 主要目的 识别背景图滑块缺口

下载识别库

pip install opencv

code

import numpy as np
import cv2

def identify_gap(bg, tp):
    bg1 = np.asarray(bytearray(bg), dtype=np.uint8)
    tp1 = np.asarray(bytearray(tp), dtype=np.uint8)

    # 灰度
    bg_img = cv2.imdecode(bg1, cv2.IMREAD_GRAYSCALE)  # 背景图片
    tp_img = cv2.imdecode(tp1, cv2.IMREAD_GRAYSCALE)  # 缺口图片

    # 识别图片边缘
    bg_edge = cv2.Canny(bg_img, 100, 200)  # 80 255
    tp_edge = cv2.Canny(tp_img, 100, 200)

    # 识别图片边界(缺口)
    bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

    # 缺口匹配
    res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
    X = max_loc[0]  # 缺口的X轴坐标
    return X

bg为背景图 图片二进制格式
tp滑块图 图片二进制格式

实例讲解

背景图
在这里插入图片描述

滑块图
在这里插入图片描述

灰度

cv2.imdecode(bg1, cv2.IMREAD_GRAYSCALE)

执行cv2的imdecode方法 cv2.imdecode(buf, flags[, dtype])

  • buf: 图像的字节流数据,必须是一个 NumPy 数组,通常是一个 uint8 类型的数组,其内容为图像的原始字节数据。
  • flags: 指定如何读取图像。常用的值有:
    • cv2.IMREAD_COLOR: 以彩色模式加载图像。任何图像的透明度都会被忽略(这是默认标志)。
    • cv2.IMREAD_GRAYSCALE: 以灰度模式加载图像。
    • cv2.IMREAD_UNCHANGED: 包括 alpha 通道的加载图像。
  • dtype (可选): 输出的数组类型。如果省略,则根据图像的内容自动确定。

示例代码执行灰度 方便后面边界识别

未灰度的边界识别

在这里插入图片描述

执行灰度后的边界识别

在这里插入图片描述

边界识别

在这里插入图片描述
使用cv2.Canny 函数执行边界识别 如图所示成功识别出滑块的边界

edges = cv2.Canny(image, threshold1, threshold2)
  • image:待检测的灰度图像。
  • threshold1:较低的阈值,用于边缘连接。
  • threshold2:较高的阈值,用于检测强边缘。
  • edges:检测到的边缘图像,与原图大小相同,但数据类型为 uint8。

示例代码当中的cv2.Canny(bg_img, 100, 200) bg_img为传入的图片(经过灰度化之后的图片)100低阈值 200高阈值 需要根据不同的图片类型进行调整参数大小提高识别率

主要用来识别像素点的颜色变化范围,根据阈值来识别边界

缺口匹配

    # 缺口匹配
    res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
    X = max_loc[0]  # 缺口的X轴坐标

cv2.matchTemplate

cv2.matchTemplate 是 OpenCV 库中的一个函数,用于在大图像中查找与小图像(或称为模板)匹配的区域。这个函数通过比较模板图像和源图像中所有可能的位置,计算它们之间的相似度或差异度,从而找到最匹配的区域。

result = cv2.matchTemplate(image, templ, method[, result[, mask]])

  • image:源图像,即要在其中搜索模板的大图像。它可以是任意维度的灰度图像或彩色图像。
  • templ:模板图像,即要在源图像中查找的小图像。它必须与源图像具有相同的数据类型和通道数。
  • method:指定比较方法的参数,决定了如何计算源图像和模板图像之间的匹配程度。OpenCV 提供了多种匹配方法,如平方差匹配(cv2.TM_SQDIFF)、归一化平方差匹配(cv2.TM_SQDIFF_NORMED)、相关性匹配(cv2.TM_CCORR)、归一化相关性匹配(cv2.TM_CCORR_NORMED)、相关系数匹配(cv2.TM_CCOEFF)和归一化相关系数匹配(cv2.TM_CCOEFF_NORMED)。
  • result(可选):用于存储匹配结果的输出图像。如果未提供,则函数将返回一个新的矩阵作为匹配结果。
  • mask(可选):一个与模板图像同样大小的矩阵,用于指定感兴趣区域(ROI),只在该区域内进行匹配。

返回值

cv2.matchTemplate 函数返回一个与源图像大小相同的矩阵(或指定的 result 矩阵),其中每个值表示模板与源图像中相应区域的匹配程度。根据使用的匹配方法,可能需要寻找最小值或最大值来确定最佳匹配位置。

cv2.minMaxLoc

查找最佳匹配位置 使用 cv2.minMaxLoc() 函数在匹配结果矩阵中查找最小值或最大值的位置,这取决于使用的匹配方法。

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# (-0.06119127571582794, 0.5630423426628113, (66, 16), (74, 13))
  • min_val:这是结果矩阵(result)中的最小值。根据你所使用的模板匹配方法,这个最小值可能表示最差的匹配(例如,在使用平方差匹配方法时),或者在某些情况下,它可能只是表示矩阵中的最小数值,而不直接对应于最佳或最差的匹配。
  • max_val:这是结果矩阵(result)中的最大值。对于大多数模板匹配方法,这个最大值通常表示最佳匹配的位置。例如,在使用相关性匹配(cv2.TM_CCORR)或归一化相关性匹配(cv2.TM_CCORR_NORMED)时,较高的值表示较好的匹配;而在使用平方差匹配(cv2.TM_SQDIFF)或归一化平方差匹配(cv2.TM_SQDIFF_NORMED)时,较低的值(因此是结果矩阵中的较大值,因为它们是差值的负数)表示较好的匹配。但是,由于 cv2.minMaxLoc() 返回的是正值,所以你总是会在使用平方差匹配时查找最大值来找到最佳匹配。
  • min_loc:这是一个元组,表示结果矩阵中最小值的位置(即 (x, y) 坐标)。这个位置可能对于某些分析是有用的,但在模板匹配中,它通常不是关注的重点。
  • max_loc:这也是一个元组,表示结果矩阵中最大值的位置(即 (x, y) 坐标)。这个位置对应于模板在源图像中的最佳匹配位置。你可以使用这个位置来在原图上绘制一个矩形框,标记出模板匹配的区域。
    在模板匹配中,max_val 和 max_loc 是最常用的两个返回值,因为它们直接帮助你找到模板在源图像中的最佳匹配位置和该匹配的相似度度量(通过 max_val 的值来反映)。
这是一个比较复杂的问题,需要用到一些图像处理和机器学习的知识。以下是一些大致的思路和参考代码: 1. 获取滑块验证码图片和背景图片。 2. 对滑块验证码图片进行预处理,例如灰度化、二值化、去噪等。 ```python import cv2 import numpy as np def preprocess(img_path): img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1] img = cv2.medianBlur(img, 3) return img ``` 3. 对背景图片进行预处理,并将其缩小为滑块验证码图片的大小。 ```python def preprocess_bg(bg_path, size): bg = cv2.imread(bg_path, cv2.IMREAD_GRAYSCALE) bg = cv2.resize(bg, size) bg = cv2.threshold(bg, 127, 255, cv2.THRESH_BINARY)[1] bg = cv2.medianBlur(bg, 3) return bg ``` 4. 计算滑块验证码图片和背景图片的差异,并找到差异最大的位置,即滑块缺口的位置。 ```python def find_gap(img, bg): diff = cv2.absdiff(img, bg) _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh, 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 x, y, w, h = cv2.boundingRect(max_contour) return x, y ``` 5. 将滑块缺口位置作为结果返回。 ```python def recognize(img_path, bg_path, size): img = preprocess(img_path) bg = preprocess_bg(bg_path, size) x, y = find_gap(img, bg) return x ``` 注意:以上代码只是一个大致的思路和参考,实际应用中还需要根据具体情况进行优化和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值