# -*- 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()