Python/OpenCV

OpenCV와 OCR을 활용한 번호판 인식

임베디드 친구 2025. 11. 20. 20:38
728x90
반응형

OpenCV와 OCR을 활용한 번호판 인식

개요

이번 포스팅에서는 OpenCV와 OCR(광학 문자 인식, Optical Character Recognition) 기술을 활용하여 자동차 번호판을 인식하는 방법을 다룹니다. 번호판 인식은 교통 관리 시스템, 주차 관리, 자동 출입 제어 등 다양한 분야에서 활용됩니다. Python과 OpenCV, 그리고 OCR 라이브러리인 Tesseract를 활용하여 실제 번호판 인식 시스템을 구현해보겠습니다.

사용 기술 및 라이브러리

번호판을 인식하기 위해 다음과 같은 라이브러리를 사용합니다.

  • OpenCV: 이미지 처리 및 번호판 영역 검출
  • Tesseract-OCR: 검출된 번호판에서 문자 인식
  • NumPy: 이미지 데이터 처리
  • Pytesseract: Python에서 Tesseract-OCR을 활용하기 위한 라이브러리

환경 설정

1. 필요한 패키지 설치

다음 명령어를 실행하여 필요한 라이브러리를 설치합니다.

pip install opencv-python numpy pytesseract

2. Tesseract 설치

Tesseract는 OCR 기능을 수행하는 엔진으로, 별도로 설치해야 합니다.

  • Windows: Tesseract 공식 설치 파일 다운로드 후 설치

  • Linux (Ubuntu): 다음 명령어 실행

    sudo apt install tesseract-ocr
  • Mac (Homebrew 사용):

    brew install tesseract

설치 후, Tesseract 실행 파일의 경로를 확인하고 Python에서 설정해야 합니다.

import pytesseract
pytesseract.pytesseract.tesseract_cmd = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"  # Windows의 경우

번호판 인식 단계

1. 이미지 불러오기

import cv2
import numpy as np

# 이미지 불러오기
def load_image(image_path):
    image = cv2.imread(image_path)
    cv2.imshow("Original Image", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return image

image = load_image("car_plate.jpg")

2. 번호판 영역 검출

def preprocess_image(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 그레이스케일 변환
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)  # 노이즈 제거
    edged = cv2.Canny(blurred, 50, 200)  # 엣지 검출
    return edged

processed_image = preprocess_image(image)
cv2.imshow("Processed Image", processed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 번호판 후보 영역 찾기

def find_contours(image):
    contours, _ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10]  # 큰 면적 순으로 정렬
    return contours

contours = find_contours(processed_image)

# 번호판 후보 영역 시각화
for contour in contours:
    approx = cv2.approxPolyDP(contour, 0.02 * cv2.arcLength(contour, True), True)
    if len(approx) == 4:  # 번호판은 보통 사각형 형태
        plate_contour = approx
        break

cv2.drawContours(image, [plate_contour], -1, (0, 255, 0), 3)
cv2.imshow("Detected Plate", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 번호판 영역 추출

def extract_plate(image, plate_contour):
    x, y, w, h = cv2.boundingRect(plate_contour)
    plate_image = image[y:y+h, x:x+w]
    return plate_image

plate_image = extract_plate(image, plate_contour)
cv2.imshow("Extracted Plate", plate_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. OCR을 이용한 문자 인식

import pytesseract

def recognize_text(plate_image):
    gray_plate = cv2.cvtColor(plate_image, cv2.COLOR_BGR2GRAY)
    _, threshold_plate = cv2.threshold(gray_plate, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    text = pytesseract.image_to_string(threshold_plate, config='--psm 8')
    return text.strip()

plate_text = recognize_text(plate_image)
print("인식된 번호판:", plate_text)

결과

위 과정을 실행하면 번호판 영역을 검출하고, OCR을 이용해 번호판의 문자 정보를 인식할 수 있습니다. 예제 이미지를 사용했을 때 다음과 같은 결과를 얻을 수 있습니다.

인식된 번호판: 12가 3456

최적화 방법

  1. 이미지 전처리 개선: 대비 조정, 이진화 방법 변경 (Adaptive Thresholding 등)
  2. 딥러닝 활용: Tesseract 대신 CNN 기반 OCR 모델 (예: EasyOCR, CRNN) 사용
  3. 데이터 보강: 다양한 각도 및 조명 환경에서 촬영된 번호판 이미지 학습

마무리

이번 포스팅에서는 OpenCV와 OCR을 이용해 자동차 번호판을 인식하는 방법을 알아보았습니다. 기본적인 이미지 처리 기법과 OCR을 결합하여 번호판을 인식할 수 있었으며, OCR 성능을 향상시키기 위한 몇 가지 최적화 방법도 살펴보았습니다.

반응형