0

I'm trying to retrieve the letters from a particularly annoying captcha.

I am trying to do it using opencv2, and so far, it doesn't give me amazing results. I might not have done the correct operations through.

NeebletWorm
  • 45
  • 1
  • 11
  • Cheers for the captchas which actually achieve their goal. – Yunnosch Mar 09 '20 at 10:32
  • I suggest that this activity is unethical. Attempting to subvert the CAPTCHA protection shows a lack of respect for the owner of the server, whether they are doing it to protect their bandwidth or their business – fmw42 Mar 09 '20 at 17:58

2 Answers2

0

with this code you can get every letter in captcha.

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)




0

here is the resize to fit function

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