86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
# -*- 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()
|