self_example/Spider/Chapter08_验证码的识别/opencv识别滑动验证码缺口/demo1缺口识别.py

86 lines
2.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/12/11 20:59
@Usage :
@Desc :
@参考https://github.com/Python3WebSpider/CrackSlideCaptcha/blob/cv/main.py
'''
import cv2
GAUSSIAN_BLUR_KERNEL_SIZE = (5, 5)
GAUSSIAN_BLUR_SIGMA_X = 0
CANNY_THRESHOLD1 = 200
CANNY_THRESHOLD2 = 450
# 得到高斯滤波之后的图
def get_gaussian_blur_image(image):
return cv2.GaussianBlur(image, GAUSSIAN_BLUR_KERNEL_SIZE, GAUSSIAN_BLUR_SIGMA_X)
# 得到边缘检测之后的图
def get_canny_image(image):
return cv2.Canny(image, CANNY_THRESHOLD1, CANNY_THRESHOLD2)
# 得到轮廓信息,会保留比较明显的边缘信息
def get_contours(image):
contours, _ = cv2.findContours(image, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
return contours
# 得到轮廓的上下限:
# 外接矩形的高度和宽度是通过实际测量得出来的高约0.25宽约0.15
# 缺口有一个最大偏移量和最小偏移量最小偏移量是验证码宽度的0.2倍最大是0.85倍
#面积阈值
def get_contour_area_threshold(image_width, image_height):
contour_area_min = (image_width * 0.15) * (image_height * 0.25) * 0.8
contour_area_max = (image_width * 0.15) * (image_height * 0.25) * 1.2
return contour_area_min, contour_area_max
# 周长阈值
def get_arc_length_threshold(image_width, image_height):
arc_length_min = ((image_width * 0.15) + (image_height * 0.25)) * 2 * 0.8
arc_length_max = ((image_width * 0.15) + (image_height * 0.25)) * 2 * 1.2
return arc_length_min, arc_length_max
# offset阈值
def get_offset_threshold(image_width):
offset_min = 0.2 * image_width
offset_max = 0.85 * image_width
return offset_min, offset_max
def main():
# 长,宽,channel
image_raw = cv2.imread('captcha.png')
image_height, image_width, _ = image_raw.shape
image_gaussian_blur = get_gaussian_blur_image(image_raw)
# 长,宽 黑白的没有channel
image_canny = get_canny_image(image_gaussian_blur)
contours = get_contours(image_canny)
cv2.imwrite('image_canny.png', image_canny)
cv2.imwrite('image_gaussian_blur.png', image_gaussian_blur)
contour_area_min, contour_area_max = get_contour_area_threshold(image_width, image_height)
arc_length_min, arc_length_max = get_arc_length_threshold(image_width, image_height)
offset_min, offset_max = get_offset_threshold(image_width)
offset = None
for contour in contours:
# 计算外接矩形的x,y起始点位置;w,h宽和高
x, y, w, h = cv2.boundingRect(contour)
if contour_area_min < cv2.contourArea(contour) < contour_area_max and \
arc_length_min < cv2.arcLength(contour, True) < arc_length_max and \
offset_min < x < offset_max:
cv2.rectangle(image_raw, (x, y), (x + w, y + h), (0, 0, 255), 2)
offset = x
cv2.imwrite('image_label.png', image_raw)
print('offset', offset)
if __name__ == '__main__':
main()