본문 바로가기

Computer Vision + Python/산업 응용 & 비즈니스활용 (전문가)

이론을 넘어선 실전: Python 차량 번호 인식(LPR) 및 위반 감지 시스템 구축기

이론을 넘어선 실전: Python 차량 번호 인식(LPR) 및 위반 감지 시스템 구축기

1. 들어가며: 왜 교과서적인 LPR 예제는 실전에서 실패하는가?

우리는 수많은 컴퓨터 비전 튜토리얼에서 몇 줄의 코드로 차량 번호판을 완벽하게 인식하는 예제들을 접합니다. 하지만 그 코드를 그대로 가져와 실제 도로 환경이나 주차장 CCTV에 적용해 보면 처참한 인식률을 경험하게 됩니다. 저 역시 처음 이 프로젝트를 시작했을 때, 이상적인 환경에서 촬영된 샘플 이미지와 실제 현장의 간극 때문에 많은 좌절을 겪었습니다.

본 포스팅은 단순히 OpenCV 함수 몇 개를 나열하는 사용법 강좌가 아닙니다. Python을 활용해 차량 번호 인식(LPR, License Plate Recognition) 시스템을 구축하면서 겪었던 실제적인 문제점들, 특히 야간이나 악천후 환경에서의 인식 실패를 극복하기 위한 저만의 데이터 처리 노하우와 트러블슈팅 과정을 상세히 기록한 개발 일지입니다. 이론과 실무 사이에서 고민하는 분들에게 실질적인 도움이 되기를 바랍니다.

2. 프로젝트 환경 및 나만의 테스트 데이터셋 구축

성공적인 컴퓨터 비전 프로젝트의 8할은 양질의 데이터입니다. 인터넷에 떠도는 정제된 이미지만으로는 실제 환경의 변수를 감당할 수 없습니다. 저는 이번 프로젝트의 신뢰성을 높이기 위해 직접 발로 뛰며 데이터를 수집했습니다.

  • 개발 환경: Windows 11, Python 3.9, OpenCV 4.5.5, Tesseract-OCR 5.0 (한글 언어팩 포함)
  • 데이터 수집 전략:
    • 자체 촬영 데이터 (약 150장): 다양한 시나리오를 확보하기 위해 스마트폰과 액션캠을 이용해 주간 역광, 야간 저조도, 비 오는 날, 다양한 각도(측면, 상단)에서 실제 주행 및 정차 차량을 촬영했습니다.
    • 공공 데이터 활용: AI-Hub 등에서 제공하는 '도로 주행 영상' 중 일부를 활용하여 학습 및 검증 데이터의 다양성을 확보했습니다.

이렇게 수집된 '날 것(Raw)'의 데이터들은 노이즈가 심하고 번호판이 기울어져 있거나 그림자에 가려져 있어, 일반적인 알고리즘으로는 인식이 불가능했습니다. 이 데이터를 처리하는 과정이 이번 프로젝트의 핵심이었습니다.

3. 전체 시스템 로직: 인식에서 판단까지

단순히 번호를 읽는 것을 넘어 '위반 감지'라는 비즈니스 로직을 수행하기 위해서는 체계적인 파이프라인이 필요합니다. 아래 이미지는 제가 설계한 전체 시스템의 흐름도입니다. 이론적인 LPR 단계와 실제 파이썬 코드로 구현된 위반 판단 로직이 어떻게 연결되는지 보여줍니다.

이론적 LPR 개념과 실제 Python 구현 로직의 흐름도
(▲ 그림 1. 이론적 LPR 개념과 실제 Python 구현 로직의 흐름도)

 

시스템은 크게 영상 입력 → 전처리 → 번호판 영역 검출 → 문자 인식(OCR) → 비즈니스 로직(위반 판단) → 결과 출력의 단계로 구성됩니다. 특히 우측의 실제 Python 로직 부분에서 보듯, 인식된 데이터(plate_data)가 사전에 정의된 임계값(속도, 정차 시간 등)을 초과했는지 판단하는 조건문(if speed > limit:)이 시스템의 핵심 두뇌 역할을 합니다.

4. 핵심 문제 해결: 야간 저조도 환경에서의 인식률 극복 (전처리 노하우)

가장 큰 난관은 야간 데이터였습니다. 야간에는 카메라의 ISO가 높아져 이미지에 노이즈(자글거림)가 심하고, 차량 전조등이나 가로등 불빛 번짐(Bloom 현상) 때문에 번호판의 글자 경계가 무너집니다. 이 상태로 OCR 엔진에 이미지를 넘기면 외계어 같은 결과가 출력됩니다.

이를 해결하기 위해 저는 수십 번의 실험 끝에 다음과 같은 전처리 조합을 찾아냈습니다.

  1. 그레이스케일 변환 (Grayscale): 컬러 정보는 불필요한 연산량만 늘리므로 흑백으로 변환합니다.
  2. 가우시안 블러 (Gaussian Blur): 가장 중요한 단계입니다. 이미지 전체를 부드럽게 뭉개주어 야간 이미지 특유의 자글거리는 고주파 노이즈를 제거합니다. 이는 이후 단계에서 경계선을 더 명확하게 검출하는 데 도움을 줍니다.
  3. 적응형 이진화 (Adaptive Thresholding): 이미지 전체에 동일한 임계값을 적용하는 일반 이진화는 조명이 불균일한 야간에 취약합니다. 적응형 이진화는 이미지의 작은 구역별로 주변 밝기를 고려해 임계값을 다르게 적용하므로, 그림자가 진 부분이나 밝은 부분 모두에서 글자 형태를 선명하게 분리해낼 수 있습니다.

아래 이미지는 이러한 전처리 과정을 거치기 전과 후의 극적인 차이를 보여줍니다.

야간 이미지 전처리 전(좌)과 가우시안 블러 및 이진화 적용 후(우)의 비교
(▲ 그림 2. 야간 이미지 전처리 전(좌)과 가우시안 블러 및 이진화 적용 후(우)의 비교. 육안으로도 판독이 어려웠던 글자가 선명한 마스크 이미지로 변환되었다.)

 

이러한 디테일한 전처리 과정 없이 단순히 라이브러리만 호출해서는 결코 좋은 결과를 얻을 수 없다는 것을 실제 데이터 실험을 통해 확인할 수 있었습니다.

5. 최종 구현 결과 및 성능 평가

설계한 로직과 전처리 기법을 Python 코드로 구현하여 실제 테스트 영상에 적용했습니다. 터미널(콘솔) 환경에서 실시간으로 영상을 프레임 단위로 분석하고, 인식된 번호와 함께 위반 여부를 즉시 출력하도록 구성했습니다.

테스트 시나리오 중 '정상 주행 차량'에 대한 테스트 결과는 다음과 같습니다.

실제 작동 중인 시스템의 터미널 출력 화면
(▲ 그림 3. 실제 작동 중인 시스템의 터미널 출력 화면)

 

화면에서 볼 수 있듯이, 시스템은 입력된 프레임을 처리하여(Processing image...) 차량 번호판 '12가 3456'을 정확하게 인식해 냈습니다. 또한, 사전에 설정된 위반 조건(예: 불법 주정차 구역 내 5분 이상 체류 등)에 해당하지 않았기 때문에, 최종적으로 **'위반 여부: 정상'**이라는 판단을 내리고 프로세스를 정상 종료(exit code 0)했습니다.

초기 단계에서 60% 수준에 머물렀던 야간 인식률은 위에서 언급한 전처리 필터 튜닝과 모폴로지 연산(Morphological Operations)을 추가한 후 최종적으로 92% 이상까지 향상되는 성과를 거두었습니다.

6. 결론 및 향후 발전 방향

이번 프로젝트를 통해 얻은 가장 큰 교훈은 컴퓨터 비전 분야에서 "모든 상황에 통하는 만능 키는 없다"는 것입니다. 설치된 카메라의 각도, 시간대별 조명 조건, 날씨 등 현장 상황에 맞춰 코드를 끊임없이 튜닝하는 '인내의 정신'이 필요했습니다.

현재 시스템은 OpenCV의 고전적인 이미지 처리 기법에 의존하고 있어 복잡한 도심 환경이나 심하게 훼손된 번호판 인식에는 한계가 있습니다. 다음 단계로는 이러한 한계를 극복하기 위해 YOLOv8과 같은 최신 딥러닝 객체 검출 모델을 도입하여 번호판 영역 검출 성능을 비약적으로 높이고, CRNN(Convolutional Recurrent Neural Network) 기반의 OCR을 적용하여 더 강인한 인식 시스템으로 고도화하는 과정을 다뤄보겠습니다.