在Python中使用OpenCV和Tesseract OCR进行车牌识别中的字符检测问题

问题描述 投票:0回答:1

我正在使用 Python 开发车牌识别系统,使用 OpenCV 进行图像处理,使用 Tesseract OCR 进行字符识别。我编写了一个函数来处理车牌图像并从中提取文本,但我在一致检测大字符和小字符时遇到了问题。该功能旨在在使用 Tesseract OCR 之前锐化图像、增加对比度并应用各种预处理步骤。

@staticmethod
def process_license_plate(frame, x1, y1, x2, y2):
    """
    Extracts and processes the license plate area from the frame using enhanced OCR.

    Parameters:
    - frame (numpy.ndarray): The image or video frame containing the license plate.
    - x1, y1, x2, y2 (int): Coordinates of the license plate bounding box.

    Returns:
    - str: The recognized text of the license plate.
    """
    # Step 1: Crop the license plate area
    license_plate_area = frame[y1:y2, x1:x2]

    # Step 2: Sharpen the license plate area using a kernel
    sharpening_kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])
    sharpened_license_plate = opencv.filter2D(license_plate_area, -1, sharpening_kernel)

    # Step 3: Increase contrast using CLAHE
    lab = opencv.cvtColor(sharpened_license_plate, opencv.COLOR_BGR2LAB)
    l, a, b = opencv.split(lab)
    clahe = opencv.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
    limg = opencv.merge([clahe.apply(l), a, b])
    enhanced_license_plate = opencv.cvtColor(limg, opencv.COLOR_LAB2BGR)

    # Step 4: Preprocess for OCR - Grayscale conversion, Gaussian blur, and Adaptive thresholding
    grayscale_license_plate = opencv.cvtColor(enhanced_license_plate, opencv.COLOR_BGR2GRAY)
    blurred_license_plate = opencv.GaussianBlur(grayscale_license_plate, (3, 3), 0)
    _, thresholded_license_plate = opencv.threshold(blurred_license_plate, 0, 255, opencv.THRESH_BINARY + opencv.THRESH_OTSU)

    # Step 5: Morphological operations to clean up the image
    morph_kernel = opencv.getStructuringElement(opencv.MORPH_RECT, (3, 3))
    opened_license_plate = opencv.morphologyEx(thresholded_license_plate, opencv.MORPH_OPEN, morph_kernel, iterations=1)
    inverted_license_plate = opencv.bitwise_not(opened_license_plate)

    # Step 6: Extract text using OCR
    license_plate_text = pytesseract.image_to_string(
        inverted_license_plate, lang='eng',
        config='--psm 6 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    )

    return license_plate_text.strip()

我尝试以车牌的高度比例作为参考来隔离较大的字符。然而,正如预期的那样,这种方法并没有成功。

# Step 6: Filter out smaller elements and keep larger characters (optional)
contours, _ = opencv.findContours(inverted_license_plate, opencv.RETR_EXTERNAL, opencv.CHAIN_APPROX_SIMPLE)
filtered_license_plate = np.zeros_like(inverted_license_plate)
# Define a threshold for contour area (e.g., 90% of the license plate area)
threshold_area = 0.9 * license_plate_area.shape[0] * license_plate_area.shape[1] # Debbuging values
for contour in contours:
    if opencv.contourArea(contour) > threshold_area:
        opencv.drawContours(filtered_license_plate, [contour], -1, (255, 255, 255), thickness=opencv.FILLED)

这是使用过滤器的最终结果:

[enter image description here]

这是没有滤镜的结果

python opencv python-tesseract yolov8
1个回答
0
投票

我们看到 3 个字符,一个花园状态图标,然后是另外 3 个字符。

考虑编写一个例程,在 NJ 图标上放置一个边界框。 有了这些,您就可以更好地找到 bbox 对于 6 个感兴趣的字符。 您可能还会发现删除图标 bbox 内的像素 提高 OCR 性能。


我们在几个地方看到书写,字体大小变化很大。

Tesseract 与分辨率有一些奇怪的相互作用。 给它一些干净的 Helvetica 字符 PDF 位图, 它在较小的分辨率范围内工作得很好, 假设 1 em 是十几个到几十个像素。 炸毁东西,这样我们每个角色就有几百个像素, OCR 性能下降。

请注意,小字体文本已被充分识别。 这里有一些建议,以便 Tesseract 会忽略此类干扰性文本:

  1. 反复模糊然后锐化图像。这会破坏精美的字体,同时使巨大的字符大部分清晰可见。
  2. 缩小 400 像素高的图像,使其接近 80 像素甚至 40 像素高。这再次破坏了精美的印刷品,同时留下了大部分清晰的巨型字符。它使我们达到了 Tesseract 显示出更好的 OCR 性能的分辨率。

如果您能够使用边界框来消除干扰因素, 这也是公平的游戏。 但它对板材和汽车之间的变化更敏感。

© www.soinside.com 2019 - 2024. All rights reserved.