인공지능과 기계학습

차량 번호판 인식(3/3)-신뢰도가 낮은 결과에 대해 추가 분석을 수행하여 정확도를 높이는 방법을 적용

지콩빵 2024. 6. 30. 17:35

2편에서 실행한 코드 결과, 신뢰도가 50-60%인 경우 추가 분석을 수행하여 정확도를 높이는 방법을 적용했다.

 

-신뢰도가 낮은 영역에 대해 이미지 전처리를 강화

-다른 OCR 엔진(예: Tesseract)을 보조적으로 사용

-결과를 한국 번호판 형식과 비교하여 검증

import cv2
import numpy as np
import easyocr
import pytesseract
import re
from google.colab.patches import cv2_imshow
# 한국 번호판 패턴
license_plate_pattern = re.compile(r'^\d{2,3}[가-힣]\s?\d{4}$')

def preprocess_image(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 19, 9)
    return thresh

def validate_plate(text):
    text = re.sub(r'\s+', '', text)
    return bool(license_plate_pattern.match(text))

# 신뢰도가 0.73 미만인 데이터에 대해 추가 분석 시행
def detect_text(image_path, confidence_threshold=0.73):
    reader = easyocr.Reader(['ko', 'en'])
    image = cv2.imread(image_path)
    if image is None:
        print(f"이미지를 불러올 수 없습니다: {image_path}")
        return

    result = reader.readtext(image)
    detected_plates = []

    for (bbox, text, prob) in result:
        if len(text) >= 7 and any(char.isdigit() for char in text):
            if prob < confidence_threshold:
                # 낮은 신뢰도 결과에 대한 추가 처리
                x, y = map(int, bbox[0])
                w = int(bbox[1][0] - bbox[0][0])
                h = int(bbox[2][1] - bbox[0][1])
                roi = image[y:y+h, x:x+w]

                # 이미지 전처리 및 Tesseract OCR 적용
                preprocessed = preprocess_image(roi)
                text_tesseract = pytesseract.image_to_string(preprocessed, lang='kor', config='--psm 7')
                text_tesseract = text_tesseract.strip()

                # EasyOCR과 Tesseract 결과 비교
                if validate_plate(text_tesseract):
                    text = text_tesseract
                    prob = max(prob, 0.8)  # 신뢰도 상향 조정

            if validate_plate(text):
                tl = tuple(map(int, bbox[0]))
                br = tuple(map(int, bbox[2]))
                cv2.rectangle(image, tl, br, (0, 255, 0), 2)
                cv2.putText(image, text, (tl[0], tl[1] - 10),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
                detected_plates.append((text, prob))

    cv2_imshow(image)
    return detected_plates

# 이미지 처리
image_paths = ['00.jpg', '01.jpg', '02.jpg', '03.jpg', '04.jpg',
               '05.jpg', '06.jpg', '07.jpg', '08.jpg', '09.jpg',
               '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg']

for path in image_paths:
    print(f"Processing {path}")
    plates = detect_text(path)
    if plates:
        for text, prob in plates:
            print(f"감지된 번호판: {text} (신뢰도: {prob:.2f})")
    else:
        print("감지된 번호판이 없습니다.")
    print()