1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] finding rectangles in captcha, difficult in defining edges

Discussão em 'Python' iniciado por Stack, Setembro 12, 2024.

  1. Stack

    Stack Membro Participativo

    I'm new to image processing, so kinda having hard time optmizing this algorithm. my task is to find and click on the rectangle, in random images. I've tried different approaches for edge detection and so far this is the best one I got:

    #detectSquare.py
    import cv2
    import numpy as np
    import pyautogui

    # Carregar a imagem
    arquivo = 'E:\\Documentos\\CODIGOS\\python_code-master\\BAF\\9.png'
    image = cv2.imread(arquivo) # Substitua pelo caminho da imagem

    # Converter para escala de cinza
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Aplicar um desfoque para reduzir ruídos
    blur = cv2.GaussianBlur(gray, (5, 5), 0)

    # Detectar bordas usando Canny
    edges = cv2.Canny(blur, 70, 200)

    # Aplicar uma dilatação para "fechar" os pequenos gaps nos contornos
    kernel = np.ones((5, 5), np.uint8)
    edges_dilated1 = cv2.dilate(edges, kernel, iterations=3)

    # Também pode tentar o fechamento morfológico (opcional)
    edges_dilated = cv2.morphologyEx(edges_dilated1, cv2.MORPH_GRADIENT, kernel)

    # Converting image to a binary image
    # (black and white only image).
    #_,threshold = cv2.threshold(edges_dilated, 110, 255, cv2.THRESH_BINARY)

    # Mostrar a imagem com as bordas dilatadas (opcional)
    cv2.imshow('Bordas Dilatadas', edges_dilated)
    cv2.waitKey(0)

    # Encontrar contornos na imagem
    contours, _ = cv2.findContours(edges_dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # Variável para contar os retângulos detectados
    rect_count = 0

    # Definir limites de tamanho para os retângulos (ajuste conforme necessário)
    min_area = 500 # Tamanho mínimo do retângulo
    max_area = 50000 # Tamanho máximo do retângulo

    # Lista para armazenar os centros de retângulos já detectados (para evitar duplicações)
    centers_detected = []
    # Filtrar contornos que sejam semelhantes a retângulos
    for contour in contours:
    approx = cv2.approxPolyDP(contour, 0.03 * cv2.arcLength(contour, True), True)

    # Se o contorno tiver 4 lados, é um retângulo aproximado
    if len(approx) == 4:
    # Encontrar o retângulo de menor área (inclinado)
    rect = cv2.minAreaRect(approx)

    # Obter o centro, as dimensões e o ângulo de inclinação
    (center_x, center_y), (w, h), angle = rect

    # Calcular a área do retângulo
    area = w * h

    # Checar se o tamanho do retângulo está dentro dos limites
    if area < min_area or area > max_area:
    continue # Ignorar retângulos muito pequenos ou muito grandes

    # Verificar a proporção (aspect ratio) do retângulo
    aspect_ratio = w / float(h)

    if aspect_ratio < 0.5 or aspect_ratio > 1.6:
    continue # Ignorar contornos que não tenham a proporção de um quadrado/retângulo

    # Verificar se já detectamos um retângulo muito próximo deste
    too_close = False
    for cx, cy in centers_detected:
    distance = np.sqrt((cx - center_x) ** 2 + (cy - center_y) ** 2)
    if distance < 10: # Se a distância for menor que 10 pixels, consideramos como duplicado
    too_close = True
    break

    if too_close:
    continue

    # Adicionar o centro detectado à lista para evitar duplicação
    centers_detected.append((center_x, center_y))

    # Contagem de retângulos
    rect_count += 1

    # Obter os 4 vértices do retângulo inclinado
    box = cv2.boxPoints(rect)
    box = np.int0(box) # Converter para inteiros

    # Desenhar o retângulo detectado na imagem
    cv2.drawContours(image, [box], 0, (0, 255, 0), 2)

    print(f"Centro do retângulo: ({int(center_x)}, {int(center_y)}), Área: {area}, Proporção: {aspect_ratio:.2f}, Ângulo: {angle:.2f}")

    # Mostrar o retângulo detectado (opcional)
    cv2.imshow('Retângulo Detectado', image)
    cv2.waitKey(0)

    # Usar pyautogui para mover o cursor e clicar
    # pyautogui.moveTo(center_x, center_y)
    #pyautogui.click()


    cv2.destroyAllWindows()


    The images are randomly generated in a web browser, my code will take a screenshot, analyse and get rectangle coords, click on it. In 8 samples that I tried, now using morphological gradient, 4 were rightly found. So, it seems the transformed image cleared most of noise lines, and got well formed rectangles, I've played a lot with the Canny parameters, and the values 70,200 worked best. maybe someone can tell me a better approach to get better results. I've put combined img with the original one and the green rectangle of the results, and also some original ones for testing.

    original and results
    original and results
    original and results
    original and results
    original and results
    original
    original

    Continue reading...

Compartilhe esta Página