[Python] License Plate Detection Issue - Inconsistent Results

Discussão em 'Python' iniciado por Stack, Março 1, 2025.

  1. Stack

    Stack Membro Participativo

    I am working on a license plate detection system using OpenCV in Python. My script aims to detect license plates in images, apply perspective correction, and save the detected plates. However, it does not work consistently across all images. In some cases, it fails to detect plates or detects incorrect contours. Code Implementation:

    Here is my current implementation:

    import cv2
    import os
    import numpy as np
    from datetime import datetime

    def redresser_perspective(roi, approx):
    # Function to apply perspective transformation (not included here)
    pass

    def detect_license_plate(image_path, output_dir='detected_plates'):
    """
    Detects license plates in an image and saves them.

    Enhancements:
    - Perspective correction for tilted plates.
    - More robust contour filtering based on aspect ratio and area.

    Args:
    image_path (str): Path to the input image.
    output_dir (str): Directory to save detected plates.

    Returns:
    list: List of saved plate image paths.
    """
    if not os.path.exists(output_dir):
    os.makedirs(output_dir)

    img = cv2.imread(image_path)
    if img is None:
    print(f"Error: Cannot read image {image_path}")
    return []

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

    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
    enhanced = clahe.apply(gray)

    blur = cv2.GaussianBlur(enhanced, (5, 5), 0)
    thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY_INV, 19, 9)

    rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    dilation = cv2.dilate(thresh, rect_kernel, iterations=1)

    contours, _ = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    img_display = img.copy()
    plates_saved = []
    height, width, _ = img.shape

    for contour in contours:
    area = cv2.contourArea(contour)
    peri = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.02 * peri, True)

    if len(approx) >= 4 and len(approx) <= 8:
    x, y, w, h = cv2.boundingRect(contour)

    min_width = width * 0.08
    min_height = height * 0.02
    max_height = height * 0.2
    aspect_ratio = float(w) / h
    area_ratio = area / (w * h)

    if (w > min_width and min_height < h < max_height and
    2 < aspect_ratio < 7 and 0.3 < area_ratio < 0.95):

    roi = img[y:y+h, x:x+w]

    if len(approx) == 4:
    roi_corrected = redresser_perspective(roi, approx)
    if roi_corrected is not None:
    roi = roi_corrected

    roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
    _, roi_thresh = cv2.threshold(roi_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    white_pixels = cv2.countNonZero(roi_thresh)
    total_pixels = roi_thresh.size
    white_ratio = white_pixels / total_pixels

    if 0.3 < white_ratio < 0.95:
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
    output_path = os.path.join(output_dir, f"plate_{timestamp}.jpg")

    cv2.imwrite(output_path, roi)
    plates_saved.append(output_path)

    cv2.rectangle(img_display, (x, y), (x+w, y+h), (0, 255, 0), 2)

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
    output_original = os.path.join(output_dir, f"original_with_plates_{timestamp}.jpg")
    cv2.imwrite(output_original, img_display)

    if plates_saved:
    print(f"{len(plates_saved)} plate(s) detected and saved.")
    else:
    print("No license plate detected.")

    return plates_saved


    Example Images: Here are two sample images showing incorrect detections:

    Original Image:

    [​IMG]

    Contours Detected:

    [​IMG]

    How can I improve the detection accuracy and make it more robust for different images?

    Continue reading...

Compartilhe esta Página