Извлечь письмо из капчи с помощью opencv

Я пытаюсь извлечь буквы из особенно раздражающей капчи.

Я пытаюсь сделать это с помощью opencv2, и пока это не дает мне потрясающих результатов. Возможно, я не выполнил правильные операции. Вот один из моих входов:

https://i.imgur.com/wr7xAQL.jpg

https://i.imgur.com/lUvYQph.jpg

https://i.imgur.com/VZHdkfv.jpg

https://i.imgur.com/nZCHxhh.jpg

Вот мой код:

   captcha_image_out = './captcha/output/'

   for filename in os.listdir(captcha_image):

       if not filename.endswith(".jpg"):
           continue

       path = os.path.join(captcha_image, filename)

       img = cv2.imread(path)

       img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

       img = cv2.medianBlur(img, 5)

       # edge detection
       edges = cv2.Canny(img, 100, 200)
       edges = ~edges

       cv2.imwrite(os.path.join(captcha_image_out, filename), edges)

И вот мои выходы:

https://i.imgur.com/sFgPtJy.jpg

https://i.imgur.com/8TaMUiU.jpg

https://i.imgur.com/rpsjI0X.jpg

https://i.imgur.com/X88fcNs.jpg

Может ли кто-нибудь объяснить, как я могу улучшить свой код?


person NeebletWorm    schedule 09.03.2020    source источник
comment
Приветствия капчам, которые действительно достигают своей цели.   -  person Yunnosch    schedule 09.03.2020
comment
Я полагаю, что эта деятельность неэтична. Попытка обойти защиту CAPTCHA показывает неуважение к владельцу сервера, независимо от того, делают ли они это для защиты своей пропускной способности или своего бизнеса.   -  person fmw42    schedule 09.03.2020


Ответы (2)


с этим кодом вы можете получить каждую букву в капче.

def inverte(imagem, name):
    imagem = (255 - imagem)
    cv2.imwrite(name, imagem)
imagem = cv2.imread(image_file)
inverte(imagem, '2.png')
image_file = '2.png'
image = cv2.imread(image_file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE)
thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
letter_image_regions = []
for contour in contours:
    (x, y, w, h) = cv2.boundingRect(contour)
    if w / h > 1.25:
        half_width = int(w / 2)
        letter_image_regions.append((x, y, half_width, h))
        letter_image_regions.append((x + half_width, y, half_width, h))
    else:
        letter_image_regions.append((x, y, w, h))

letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0])

for letter_bounding_box in letter_image_regions:
    x, y, w, h = letter_bounding_box
    letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2]
    letter_image = resize_to_fit(letter_image, 20, 20)
    letter_image = np.expand_dims(letter_image, axis=2)
    letter_image = np.expand_dims(letter_image, axis=0)




person yazdanimehdi    schedule 09.03.2020
comment
Замечательно ! К сожалению, отсутствует функция resize_to_fit. - person NeebletWorm; 09.03.2020

вот функция изменения размера, чтобы соответствовать

import cv2
import imutils


def resize_to_fit(image, width, height):

    # grab the dimensions of the image, then initialize
    # the padding values
    (h, w) = image.shape[:2]

    # if the width is greater than the height then resize along
    # the width
    if w > h:
        image = imutils.resize(image, width=width)

    # otherwise, the height is greater than the width so resize
    # along the height
    else:
        image = imutils.resize(image, height=height)

    # determine the padding values for the width and height to
    # obtain the target dimensions
    padW = int((width - image.shape[1]) / 2.0)
    padH = int((height - image.shape[0]) / 2.0)

    # pad the image then apply one more resizing to handle any
    # rounding issues
    image = cv2.copyMakeBorder(image, padH, padH, padW, padW,
                               cv2.BORDER_REPLICATE)
    image = cv2.resize(image, (width, height))

    # return the pre-processed image
    return image

person yazdanimehdi    schedule 09.03.2020
comment
У меня ошибка при изменении размера. Когда я прохожу через imutils.resize(), массив изображений пуст? error: (-215: Assertion failed) !ssize.empty() в функции 'cv::resize' РЕДАКТИРОВАТЬ: Похоже, когда программа собирает ndarray, y-2 возвращает отрицательное значение и, следовательно, недопустимый массив. - person NeebletWorm; 09.03.2020