拼图滑块人机验证初尝试(很明显的绿色缺口类型)

1. 需要用到的库

import cv2
import numpy as np

2. 对图片进行初步的处理(不知道算不算是预处理)

# 读取图像
image = cv2.imread('./01.png')

# 定义绿色的范围(这可能需要调整)
# 注意是HSV的颜色空间
lower_green = np.array([30, 100, 100])
upper_green = np.array([90, 255, 255])

# 将图像从BGR转换为HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

        对图像进行读取操作就是: cv2.imread('图像的路径')

        然后,定义好需要针对处理的颜色,这里是给定一个颜色范围,为的是扩大颜色选取时的容差,如果定死一个颜色的数据,可能最终得到的效果是残缺的,不是自己想要的。

        在HSV中,绿色的色调范围其实是90 ~ 150(度)左右,饱和度和亮度的范围都是0 ~ 1。

        但是,OpenCV中的HSV范围与标准的HSV模型范围不同,在标准的HSV模型中,H(色相)的范围是0到360度,S(饱和度)和V(亮度)的范围是0到1。

        在计算机中,图像通常以8位无符号整数来表示每个颜色通道,为了适应这种8位表示,OpenCV将H的范围缩小到了0到179,而S和V的范围则扩大到了0到255。这样做的好处是可以直接使用8位整数来表示HSV颜色,而无需进行任何类型转换或缩放。

        如果不想用HSV,其实也可以尝试直接用RGB,我觉得理论上也是可以的,我当时就觉得HSV对颜色的描述比较直观。

        有时候滑块验证的拼图缺口不一定是纯色的,可能是做了灰度处理,缺口处做了暗黑处理,这个时候可以尝试用形状模板匹配。

3. 经过遮罩、腐蚀、膨胀,寻找外接矩形等操作得到缺口的水平坐标

# 创建遮罩,只保留绿色
    mask = cv2.inRange(hsv, lower_green, upper_green)

    # 对图像应用遮罩
    masked_image = cv2.bitwise_and(image, image, mask=mask)

    # 定义结构元素(用于腐蚀和膨胀操作)
    kernel = np.ones((5, 5), np.uint8)

    # 对遮罩后的图像进行腐蚀操作
    eroded_image = cv2.erode(masked_image, kernel, iterations=1)

    # 对腐蚀后的图像进行膨胀操作
    dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)

    # 对遮罩后的图像进行腐蚀操作
    eroded_image = cv2.erode(dilated_image, kernel, iterations=1)

    # 找到所有的轮廓
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 找到最大的轮廓
    cnt = max(contours, key=cv2.contourArea)
    # max 函数可以接受一个名为 key 的可选参数,
    # 这个参数应该是一个函数。这个函数会被应用到可迭代对象的每一个元素上,
    # 然后 max 函数会返回 key 函数结果最大的元素。
    # 这里的cv2.contourArea能够根据轮廓来计算面积
    # 最终max会返回最大面积的轮廓,即最大轮廓

    # 计算最大外接矩形
    x, y, w, h = cv2.boundingRect(cnt)

    # 计算矩形的质心
    cX = x + w // 2
    cY = y + h // 2

    # 在图像上画出质心和最大外接矩形
    cv2.circle(dilated_image, (cX, cY), 5, (255, 255, 255), -1)
    cv2.rectangle(dilated_image, (x, y), (x + w, y + h), (255, 255, 255), 2)

    # 显示结果
    cv2.imshow('result', dilated_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return cX

最终:

if __name__ == '__main__':
    distance = get_sliding_distance()
    print(distance)

        得到了水平坐标,嘿嘿嘿,咱们就知道下一步应该怎么做了。

你可能感兴趣的:(opencv)