차량 번호판 인식 기술은 스마트 교통 시스템의 핵심 구성 요소로, 차량 번호를 자동으로 식별하여 효율적인 교통 관리를 실현한다. 문자 템플릿은 인식 과정의 핵심 자원으로, 숫자, 알파벳 및 각 성·직할시 약칭의 표준 이미지 패턴을 포함하며 문자 매칭과 인식 단계에 폭넓게 활용된다. 본 프로젝트는 번호판 인식 흐름을 중심으로 이미지 수집, 전처리, 번호판 검출, 문자 분할, 템플릿 기반 문자 인식(OCR) 및 결과 검증 등 핵심 기술을 다루며, 특히 문자 템플릿이 SVM과 CNN 등 모델의 훈련 및 매칭에서 수행하는 역할을 강조한다. 고품질의 다양한 장면을 포괄하는 템플릿 라이브러리를 구축함으로써 복잡한 환경에서의 인식 정확도와 견고성을 향상시켜 스마트 교통 발전에 기여한다.
1. 번호판 인식 시스템 전체 아키텍처 개요
번호판 인식 기술은 스마트 교통 시스템의 핵심 구성 요소로, 최근 도시 보안, 고속도로 요금 징수, 주차장 관리 등 분야에서 광범위하게 적용되고 있다. 본 장에서는 전체적 관점에서 번호판 인식의 기술 흐름과 모듈 분할을 체계적으로 설명하며, 문자 템플릿이 전체 인식 체인에서 차지하는 핵심적인 위치를 명확히 한다.
완전한 번호판 인식 시스템은 일반적으로 이미지 수집, 전처리, 번호판 검출, 문자 분할 및 문자 인식의 다섯 가지 핵심 모듈로 구성되며, 각 모듈은 순차적인 데이터 흐름으로 연결된다. 먼저 카메라가 차량 이미지를 캡처하고, 이후 전처리 단계에서 이미지 품질을 향상시킨 다음, 에지 검출과 형태학적 분석을 통해 번호판 영역을 검출하며, 투영법 또는 딥러닝 네트워크를 활용한 문자 분할을 거쳐 최종적으로 템플릿 매칭이나 CNN을 통해 문자 인식을 완료한다.
현재 주류 아키텍처는 전통적인 이미지 처리와 딥러닝이 융합된 하이브리드 방식으로 발전하고 있다. 예를 들어 YOLOv5를 활용한 번호판 대략적 검출에 Canny+허프 변환으로 경계를 미세 조정하고, CNN으로 문자를 인식하는 방식이다. 이러한 설계는 효율성과 정확성을 동시에 고려하며, 특히 복잡한 조명과 저해상도 환경에서 더욱 견고한 성능을 보인다.
특히 주목할 점은 고품질의 문자 템플릿 라이브러리가 인식 정확도 향상의 기초적 보장이라는 것이다. NCC 기반 템플릿 매칭이든 CNN 훈련용 레이블 데이터든, 표준화되고 다양한 문자 샘플(다양한 폰트, 변형, 노이즈 포함)이 필수적이다. 후속 장에서는 이 핵심 요소를 중심으로 심층적으로 논의할 것이다.
2. 이미지 수집 및 환경 영향 요인 분석
2.1 이미지 수집 장비 선정 및 파라미터 구성
2.1.1 카메라 해상도, 프레임률 및 초점 거리 선정 기준
카메라의 핵심 성능 지표인 해상도, 프레임률(FPS), 렌즈 초점 거리는 이미지 세부 정보의 풍부함, 동적 캡처 능력, 모니터링 범위를 결정한다.
- 해상도: 번호판 영역의 픽셀 밀도에 직접적인 영향을 미친다. 경험적으로 번호판 너비는 화면 너비의 1/10 이상을 차지해야 하며, 개별 문자 너비는 30픽셀 이상이 권장된다. 중국 대륙의 일반적인 파란색 번호판을 예로 들면, 총 너비 약 440mm에 카메라와 5m 거리에서 문자 너비 30픽셀을 달성하려면 수평 해상도가 충분해야 한다. 200만 화소(1920×1080) 이상의 고화질 카메라를 권장하며, 300만~500만 화소(2560×1440 또는 2592×1944)를 우선적으로 선택하여 원거리 인식 정확도를 보장한다.
- 프레임률: 단위 시간당 캡처하는 화면 수를 결정한다. 고정형 카드뷰 장면에서 시속 60km 이하 주행 시, 30fps 이상을 권장하며 고속 도로 특수 구간에서는 60fps로 상향하여 동적 흐림을 줄인다.
- 초점 거리: 시야각(FOV)과 인식 거리에 영향을 미친다. 단초점 렌즈(예: 2.8mm)는 넓은 시야각 근거리 모니터링(≤10m)에 적합하고, 장초점 렌즈(예: 12mm 이상)는 원거리 특수 촬영(≥20m)에 적합하다.
| 파라미터 | 권장값 | 적용 장면 |
|---|---|---|
| 해상도 | ≥200만 화소(1920×1080) | 일반 카드뷰 |
| 300만~500만 화소 | 원거리/고정밀 인식 | |
| 프레임률 | 30fps | 일반 차선 |
| 60fps | 고속도로 | |
| 초점 거리 | 2.8–4mm | 주차장 출입구(근거리) |
| 8–12mm | 도시 도로 카드뷰 | |
| 16–25mm | 고속도로 요금소 |
2.1.2 주간·야간 촬영 수요에 따른 보광 전략
주간 보광 전략
- 역광 보정(BLC): 카메라가 자동으로 어두운 영역의 밝기를 증가시켜 역광으로 인한 번호판 어두움을 방지한다.
- 와이드 다이내믹(WDR/HDR) 기술: 다중 프레임 합성 또는 센서 이중 노출 메커니즘을 통해 밝은 영역과 어두운 영역의 세부 정보를 동시에 보존한다. 실측 결과 WDR 활성화 시 역광 장면에서 번호판 인식 성공률이 35% 이상 향상되었다.
- 편광 필터: 렌즈 전방에 장착하여 금속 표면 반사광을 약화시키며, 특히 비 후 젖은 노면으로 인한 거울 반사에 유효하다.
야간 보광 방안
- 적외선 보광(IR Illumination): 파장은 일반적으로 850nm(미세한 붉은빛 가시) 또는 940nm(완전 비가시)을 사용한다. 850nm은 투과력이 강하나 미세한 붉은빛 효과가 있어 무인 운영 장면에 적합하다. 색상 정보 복원이 불가능하여 노란색, 녹색 등 신에너지 번호판 구분에 불리하다는 단점이 있다.
- 백광 보광(White Light Illumination): 가시광 조명으로 실제 색상을 보존하며, 차량 유형과 번호판 색상 연합 판단에 유리하다. 차량 감지 시점에만 점등하는 스마트 트리거 메커니즘과 결합하여 주민 민원을 방지할 수 있다.
- 혼합 보광 모드: 주간 보광 해제, 야간 자동 적외선 또는 백광 전환, 지능형 제어 로직 구현.
def select_illumination_mode(light_level, vehicle_detected):
"""
환경광 강도와 차량 상태에 따른 보광 모드 선택
:param light_level: 현재 조도(lux)
:param vehicle_detected: 차량 감지 여부(bool)
:return: 보광 모드 문자열
"""
if light_level > 100:
return "NO_ILLUMINATION"
elif light_level <= 100 and vehicle_detected:
if use_color_recognition:
return "WHITE_LIGHT"
else:
return "INFRARED"
else:
return "STANDBY"
2.1.3 고정형과 이동형 수집 장면의 적응 방안
고정형 수은 고속도로 ETC 갓길, 도시 치안 카드뷰, 주차장 출입구 등에 전형적으로 적용된다. 설치 위치 고정, 시야각 제어 가능, 고성능 IPC+전문 보광등 배치, 광섬유 전송 및 집중 전력 공급(PoE 또는 고압 직류) 지원, 레이더 속도 측정·코일 트리거 등 외부 장비 연동이 가능하다.
이동형 수집은 경찰차 탑재 시스템, 순찰 로봇, 드론 장착 장비 등을 포함한다. 상대적 운동 속도가 빨라 이미지 흔들림이 심하고, 조명 변화가 빈번하며(터널 진출, 그늘 교차), 장비 공간과 전력이 제한되고 저장·전송 부담이 크다는 특징이 있다. 이를 위해 자이로스코프와 전자식 손떨림 보정(EIS) 모듈을 탑재하고, NVIDIA Jetson 시리즈 등 임베디드 플랫폼을 활용한 엣지 컴퓨팅을 구현하며, 데이터 로컬 캐싱+선택적 업로드 및 중단점 이어올리기를 지원한다.
2.2 외부 환경이 이미지 품질에 미치는 영향 메커니즘
2.2.1 조명 변화(강광, 역광, 그림자)로 인한 대비도 불균형
강한 햇빛이 렌즈를 정면으로 비출 때 렌즈 플레어(lens flare)나 센서 포화가 발생하여 이미지가 대면적으로 하얗게 변하고 번호판 문자가 "소실"될 수 있다. 역광 장면에서는 차량이 밝은 배경 앞에 위치하여 카메라가 배경 기준으로 노출되어 전경 번호판이 실루엣처럼 변한다. 국부적 그림자는 나무, 교량 또는 광고판 투영이 번호판을 덮어 문자 일부가 누락되거나 단절되게 한다.
2.2.2 우·설·안개 등 악천후로 인한 이미지 흐림 및 노이즈 증가
안개 이미지는 대기 산란 모델을 따른다: I(x) = J(x)t(x) + A(1 - t(x)), 여기서 I(x)는 관측 이미지, J(x)는 이상적인 무안개 이미지, A는 전역 대기광, t(x)는 투과율이다. 안개 제거 알고리즘은 t(x)와 A를 추정하여 J(x)를 역산하는 것을 목표로 한다.
2.2.3 차량 운행 속도에 따른 이미지 잔상 및 왜곡 문제
고속 주행 차량은 노출 시간 동안 변위가 발생하여 이미지가 운동 방향으로 늘어나는 현상인 운동 흐림(motion blur)을 초래한다. 점 확산 함수(PSF)는 h(x,y)로 표현되며, 흐림 길이 L = v·T·r(속도×노출시간×이미지 비율)로 계산된다. 대응책으로 노출 시간 단축(더 강한 보광 필요), 글로벌 셔터 카메라 사용, 후처리 블라인드 디컨볼루션 알고리즘 적용 등이 있다.
2.3 실제 장면에서의 이미지 퇴화 모델 구축
일반적인 퇴화 모델은 g(x,y) = h(x,y) * f(x,y) + n(x,y)로 표현된다. 여기서 f(x,y)는 원본 선명 이미지, h(x,y)는 점 확산 함수(PSF), *는 합성곱 연산, n(x,y)는 가법적 노이즈(가우시안, 포아송, 소금-후추 등)이다.
| 환경 조건 | 주도적 퇴화 유형 | 모델링 방식 |
|---|---|---|
| 맑은 날 정오 | 강광 과다노출 | Sigmoid 매핑 압축 |
| 황혼 역광 | 노출 부족 | 단일 스케일 Retinex 향상 |
| 안개 날 | 산란 흐림 | 어두운 채널 사전 안개 제거 |
| 야간 약광 | 고노이즈 | BM3D 노이즈 제거 |
| 비 오는 날 | 줄무늬 노이즈 | 사전 학습 기반 streak 제거 |
2.4 데이터셋 수집 규격 및 레이블링 프로세스
고품질 데이터는 모델 일반화의 초석이다. 수집은 지역(남북 기후 차이), 차종(승용차, SUV, 화물차, 오토바이), 시간(아침/점심/저녁, 사계절 변화), 번호판 종류(파란색, 노란색, 녹색, 경찰, 대사관)를 포괄해야 한다. 카테고리당 500장 이상의 유효 샘플, 총 10,000장 이상을 권장한다.
레이블링은 번호판 위치를 픽셀 단위로 정밀하게 사각형 박스로 표시하며, 3단계 품질 검사 프로세스를 수립한다: 1) 자동 검증(경계 박스 이미지 경계 초과 여부), 2) 1차 심사(초급 레이블러 교차 검토), 3) 최종 심사(전문가 10% 샘플링, 오류율 > 2% 시 전체 재작업). 버전 관리 데이터 관리 시스템을 구축하여 각 반복의 증·삭·수정 로그를 기록해 추적 가능성을 확보한다.
3. 이미지 전처리 및 번호판 검출 핵심 기술
3.1 이미지 향상 및 노이즈 제거 처리
3.1.1 그레이스케일 변환 알고리즘 및 색상 무관성의 장점
번호판 색상은 다양하나 문자 색상은 일반적으로 흰색 또는 검은색이다. RGB 3채널 데이터를 직접 사용하면冗長한 정보가 추가되고 계산 부담이 증가하므로, 컬러 이미지를 단채널 그레이스케일로 변환하는 것이 필수적이다.
import cv2
import numpy as np
def bgr_to_grayscale(input_image):
"""
BGR 이미지를 그레이스케일로 변환
:param input_image: 입력 3채널 BGR 이미지 (H, W, 3)
:return: 그레이스케일 이미지 (H, W)
"""
return cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
이 가중치 계수는 인간 눈의 색광에 대한 민감도 차이(녹색 가장 민감, 파랑 가장 둔감)에서 유래하며, 더 많은 시각 정보를 보존한다. 이 연산은 색상 간섭을 제거하여 후속 처리가 밝도 변화에만 집중하도록 하여 번호판 바탕색에 대한 알고리즘 적응력을 상시킨다.
3.1.2 중간값 필터링과 가우시안 필터링의 적용 비교
| 필터 유형 | 적용 노이즈 | 원리 | 계산 복잡도 |
|---|---|---|---|
| 중간값 필터 | 소금-후추 노이즈 | 인접 영역 중간값으로 중심 픽셀 대체 | 중간 |
| 가우시안 필터 | 가우시안 노이즈 | 가중 평균, 가중치는 정규분포 따름 | 높음 |
def apply_denoising_filters(gray_img):
"""
중간값 필터링과 가우시안 필터링 적용
:param gray_img: 입력 그레이스일 이미지
:return: 두 가지 필터링 결과
"""
median_denoised = cv2.medianBlur(gray_img, ksize=3)
gaussian_denoised = cv2.GaussianBlur(gray_img, ksize=(5, 5), sigmaX=1.0)
return median_denoised, gaussian_denoised
실무에서는 먼저 중간값 필터링으로 명확한 반점 노이즈를 처리하고, 이후 가벼운 가우시안 필터링을 추가로 적용하여 더욱 부드럽게 만드는 것을 권장한다. 특히 차량 탑재 촬영 시스템의 경우 중간값 필터링을 우선 적용하는 것이 좋다.
3.1.3 히스토그램 평활화로 저대비도 이미지 가독성 향상
역광 또는 야간 배광 장면에서 번호판 영역은 전체적으로 어두우거나 국부적으로 과다노출되어 문자와 배경 구분이 어렵다. CLAHE(제한 대비도 적응형 히스토그램 평활화)는 이미지를 8×8 블록으로 분할하여 각각 평활화하여 국부 대비도 차이가 큰 장면에 더 적합하다.
def apply_clahe_enhancement(image):
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
return clahe.apply(image)
3.2 에지 검출 연산자 성능 비교 및 선택
| 연산자 | 원리 | 장점 | 단점 | 적용 장면 |
|---|---|---|---|---|
| Sobel | 1차 미분+가중 평활화 | 항노이즈 능력 강함 | 에지가 두꺼움 | 빠른 초기 선별 |
| Canny | 다단계 최적 에지 검출 | 정밀, 연속, 항노이즈 | 계산 복잡 | 주류 선택 |
| Laplacian | 2차 미분 영교차 | 세부 정보에 민감 | 노이즈에 취약 | 보조 검출 |
def compare_edge_detectors(gray_img):
grad_x = cv2.Sobel(gray_img, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(gray_img, cv2.CV_64F, 0, 1, ksize=3)
sobel_edges = cv2.magnitude(grad_x, grad_y).astype(np.uint8)
laplacian_edges = cv2.Laplacian(gray_img, cv2.CV_64F).astype(np.uint8)
canny_edges = cv2.Canny(gray_img, threshold1=50, threshold2=150)
return sobel_edges, laplacian_edges, canny_edges
실험 결과, 대부분의 번호판 이미지에서 Canny 연산자가 가장 연속적이고 정확한 경계 에지를 얻을 수 있으며, 특히 경계가 완전할 때 우수한 성능을 보인다.
3.2.1 Canny 이중 임계값 메커니즘 최적화
적응형 Canny 에지 검출은 이미지 중간값을 기반으로 자동 임계값을 설정하여 수동 조정을 한다.
def adaptive_canny_detector(image, sigma=0.33):
median_val = np.median(image)
lower_bound = int(max(0, (1.0 - sigma) * median_val))
upper_bound = int(min(255, (1.0 + sigma) * median_val))
return cv2.Canny(image, lower_bound, upper_bound)
3.3 허프 변환 기반 직선 검출 및 번호판 대략적 검출
번호판은 일반적으로 뚜렷한 직사각형 구조를 가지며, 상하 경계는 근사 평행한 긴 직선이다. 이 선험적 지식을 활용하여 허프 변환으로 이미지의 직선 집합을 검출하고, 번호판 기하학적 특징에 부합하는 후보 영역을 선별할 수 있다.
허프 변환은 이미지 공간의 직선을 극좌표 파라미터 공간 (ρ, θ)으로 매핑하며, ρ = x cosθ + y sinθ이다. 각 에지점은 (ρ, θ) 공간에서 정현 곡선으로 표현되며, 여러 곡선의 교점이 공선점 집합에 대응한다.
def detect_hough_lines(edge_image):
lines = cv2.HoughLines(edge_image, rho=1, theta=np.pi/180, threshold=100)
return lines
검출된 직선의 각도 분포를 분석하여 ±5° 내에 근접한 수평선 쌍을 선별하고, 그 간격이 번호판 높이(일반적으로 80~120px)에 부합하는지 계산하여 후보 영역으로 표시한다.
3.4 연결 영역 분석 및 정밀 검출 실전
허프 변환을 통한 초기 선별 후에도 여러 후보 영역이 존재할 수 있다. 이 때 연결 영역 분석을 통해 번호판 위치를 더욱 정밀하게 추출한다. 번호판은 고정된 비율(약 4.5:1)을 가지므로, 이 규칙을 활용해 필터링한다.
def filter_by_geometric_features(label_image, min_area=1000, max_area=5000, ratio_range=(3.5, 5.5)):
valid_regions = []
for label_id in range(1, label_image.max() + 1):
coords = np.where(label_image == label_id)
y_coords, x_coords = coords
area = len(x_coords)
if not (min_area < area < max_area):
continue
x_min, x_max = x_coords.min(), x_coords.max()
y_min, y_max = y_coords.min(), y_coords.max()
width = x_max - x_min
height = y_max - y_min
if height == 0:
continue
aspect_ratio = width / height
if ratio_range[0] < aspect_ratio < ratio_range[1]:
density = area / (width * height)
if density > 0.3:
valid_regions.append((x_min, y_min, width, height))
return valid_regions
이 방법은 차량 전조등, 표지판 등 가짜 목표를 효과적으로 제거할 수 있다. 일반적인 실패 원인으로 심각한 기울기로 인한 경계 단절, 오염·가림으로 인한 에지 결손, 다중 번호판 병렬 배치 등이 있으며, 이는 각각 허프 직선 보완 메커니즘 도입, 색상 정보 결합 보조 검출, 딥러닝 분류기 우선순위 선정 등으로 개선할 수 있다.
4. 문자 분할 및 템플릿 라이브러리 구축 방법론
4.1 문자 분할 전 핵심 준비 단계
4.1.1 번호판 기울기 보정: 투영법 또는 아핀 변환 기반 교정 전략
실제 촬영 과정에서 카메라 설치 각도 편차, 차량 자세 변화, 운동 흐림 등으로 인해 추출된 번호판 영역이 일정한 회전 기울기를 갖는 경우가 많다. 이는 수직 투영 곡선의 골짜기 분포 규칙을 심각하게 훼손하여 문자 분할 오류를 초래한다.
투영법 각도 추정 및 회전 교정 구현: 번호판 문자 행이 수평 방향으로 주기적 간격을 가진다는 특징을 활용한다. 그레이스케일 이미지에 Sobel 수평 방향 그래디언트 검출을 적용하여 횡방향 에지 정보를 향상시키고, 수직 방향으로 픽셀 강도를 누적하여 열 투영 곡선을 생성한다. 이미지가 기울어지면 골짜기 위치가 오프셋되므로, 다양한 회전 각도에서의 투영 에너지 엔트로피 최소값을 스캔하여 최적 회전각을 추정한다.
import cv2
import numpy as np
def estimate_skew_angle(plate_img, angle_range=(-10, 10), step=0.5):
gray = cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY)
optimal_angle = 0
min_entropy = float('inf')
for angle in np.arange(angle_range[0], angle_range[1] + step, step):
rotation_matrix = cv2.getRotationMatrix2D(
(gray.shape[1]//2, gray.shape[0]//2), angle, 1)
rotated = cv2.warpAffine(gray, rotation_matrix,
(gray.shape[1], gray.shape[0]),
flags=cv2.INTER_CUBIC)
projection = np.sum(rotated, axis=0)
probability = projection / np.sum(projection)
probability = probability[probability > 0]
entropy = -np.sum(probability * np.log2(probability))
if entropy < min_entropy:
min_entropy = entropy
optimal_angle = angle
return optimal_angle
이 방법의 장점은 사전 문자 구조 지식이 불필요하다는 것이며, 대부분의 표준 파란색 번호판, 노란색 번호판 등 규칙적 배치 장면에 적용 가능하다. 그러나 계산 오버헤드가 크므로 오프라인 훈련 또는 저지연 요구가 낮은 시스템에 적합하다.
허프 직선 검출과 아핀 변환 기반 정밀 교정: 번호판 상하 경계의 평행 직선 특성을 활용하여 Canny 에지 검출과 허프 변환으로 가장 긴 두 수평 직선을 추출하고, 그 평균 기울기로부터 기울기 각도를 역산하는 방식이다. 이 방법은 고해상도 이미지에서 더 은 정확도를 제공하나, 극단적인 조명 또는 부분 가림 상황에서 오검출 가능성이 있다. 실무에서는 투영법과 결합하여 이중 검증 메커니즘을 형성하는 것이 바람직하다.
4.1.2 번호판 색상과 바탕무늬 제거: 형태학적 열기运算의 적용
중국 기동차 번호판은 파란색 바탕에 흰색 글씨(소형차), 노란색 바탕에 검은색 글씨(대형차) 등의 형태가 일반적이며, 배경에 밀그리드 질감이나 위조 방지 패턴이 포함되어 있다. 이러한 시각적 요소는 이진화 후 문자 연결성을 방해하여 문자 단절이나 연착을 유발한다.
형태학적 열기运算(Opening Operation)은 침식 후 팽창의 연산 조합으로, 작은 면적의 노이즈와 가는 선분을 효과적으로 제거하면서 대형 구조는 변형시키지 않는다.
structuring_element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opened_image = cv2.morphologyEx(binary_image, cv2.MORPH_OPEN, structuring_element)
closed_image = cv2.morphologyEx(opened_image, cv2.MORPH_CLOSE, structuring_element)
구조 요소 크기는 문자 크기에 동적으로 조정해야 하며, 너무 크면 문자 에지를 침식하고 너무 작으면 노이즈 제거 효과가 부족하다. 실무에서는 먼저 원본 이미지의 주파수 특성을 관찰하고 바탕무늬 주기를 통계적으로 분석하여 구조 요소 크기를 설계하는 것을 권장한다.
4.2 수직 투영법을 통한 문자 분할 구현
수직 투영법은 원리가 간단하고 계산이 효율적이어 번호판 문자 분할 분야에서 오랫동안 주류를 이루고 있다. 핵심 아이디어는 전처리된 이진화 번호판 이미지를 수직 방향(열 방향)으로 픽셀값을 누적하여 각 열의 "문자 밀도"를 반영하는 투영 곡선을 생성하는 것이다.
4.2.1 투영 곡선 생성 및 골짜기 검출 알고리즘 설계
입력 이미지 크기를 W×H, 이진화 후 행렬을 I(x,y) ∈ {0,255}라 하면, x번째 열의 수직 투영값은 P(x) = Σy=0H-1 I(x,y)로 정의된다. 이 공식은 공간 차원의 차원 축소 연산을 구현하며, 2차원 이미지를 1차원 신호 시퀀스로 매핑한다.
from scipy.signal import find_peaks
def vertical_projection_segment(binary_plate):
projection = np.sum(binary_plate, axis=0)
smoothed = np.convolve(projection, np.ones(3)/3, mode='same')
inverted = -smoothed
valleys, _ = find_peaks(inverted, distance=8)
return valleys, smoothed
distance=8은 인접 골짜기 간 최소 8픽셀 간격을 강제하여, 한자+알파벳+숫자의 전형적인 문자 너비(약 15–25px)에 부합하도록 과도한 분할을 방지한다. 추가로 진폭 임계값 height=-threshold를 설정하여 얕은 파동을 제외할 수 있다.
4.2.2 연착 문자의 분할점 식별 및 동적 임계값 조정
수직 투영법은 이상적인 조건에서 우수한 성능을 보이나, 실제 적용에서 문자 연착 문제에 자주 직면한다. 특히 "川", "申" 등 필획이 복잡한 한자나 오염, 흐림으로 인한 인접 문자 에지 융합 시 투영 곡선에 명확한 골짜기가 나타나지 않아 전통적인 고정 임계값 방법이 무효화된다.
개선 방안으로 동적 임계값법(국소 투영 평균에 기반한 부동 임계값 설정), 윤곽 분석 보조 판단(연결 영역 외접 사각형의 가로세로 비율로 연착 여부 판단), 분할점 예측 모델(역사적 샘플 학습을 통한 연착 문자의 잠재 분할점 분포 학습) 등이 있다.
def detect_adhesion_split(contours, projection_curve):
split_points = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
aspect_ratio = w / h
if aspect_ratio > 1.8:
center_x = x + w // 2
sub_projection = projection_curve[center_x-5:center_x+5]
local_min_idx = np.argmin(sub_projection)
split_point = center_x - 5 + local_min_idx
split_points.append(split_point)
return sorted(split_points)
4.3 틈새 검출 기반 보조 분할 메커니즘
저대비도, 부분 가림, 노후 번호판 등 도전적인 장면에서 분할 신뢰성을 더욱 향상시키기 위해 틈새 검출 기반의 선험적 지식 구동 메커니즘을 도입할 수 있다.
대규모 실제 번호판 샘플 통계 분석 결과, 합법적 번호판 문자 사이에는 일정한 폭의 고정 간격이 존재함을 발견했다. 예를 들어 중국 대륙 번호판에서 성·직할시 약칭과 문자 사이는 약 10–15px, 숫자 사이는 약 7px 정도의 간격이 형성된다. 이러한 "공백대"는 자연스러운 분할 단서가 된다.
규칙 엔진을 구축하여 문법 구조 정보를 통합하면, 초기 분할 결과가 번호판 형식에 부합하는지 검증하고 수정할 수 있다. 예를 들어 초기 분할이 7개 문자를 생성했으나 표준 민용 번호판은 7자리(예: "京A·12345")여야 하므로, 강제 재분할 또는 병합 연산을 통해 올바른 구조에 근접하도록 유도한다.
4.4 문자 템플릿 라이브러리의 체계적 구축
고품질 문자 템플릿 라이브러리는 템플릿 매칭식 인식 알고리즘의 기초이다. 구축 과정은 포괄성, 일관성, 확장성을 겸비해야 한다.
4.4.1 분류 체계 설계
3단계 분류 체계를 구축한다: 1차 카테고리는 한자(성·직할시 약칭), 영문자, 아라비아 숫자; 2차 카테고리는 글꼴 스타일(명조, 고딕, 변형); 3차 카테고리는 변형 등급(경미 기울기, 신축, 손상 시뮬레이션).
4.4.2 템플릿 표준화 프로세스
모든 템플릿을 32×32 픽셀로 통일하여 이중선형 보간법으로 스케일링하고, 질량 중심 정렬을 수행한다.
def normalize_character_template(char_img):
resized = cv2.resize(char_img, (32, 32), interpolation=cv2.INTER_LINEAR)
moments = cv2.moments(resized)
cx = int(moments['m10'] / moments['m00'])
cy = int(moments['m01'] / moments['m00'])
tx, ty = 16 - cx, 16 - cy
shift_matrix = np.float32([[1, 0, tx], [0, 1, ty]])
aligned = cv2.warpAffine(resized, shift_matrix, (32, 32))
return aligned
정렬 연산은 매칭 정확도를 대폭 향상시키며, 특히 미세 변위에 민감한 장면에서 현저한 효과를 보인다.
4.4.3 다중 글꼴 스타일 템플릿 수집 전략
다양한 도시, 연도, 제조업체의 실제 번호판 이미지에서 전형적인 문자 샘플을 추출하고, 글꼴 렌더링+노이즈 주입 등 합성 데이터 증강을 보완하여 주류 스타일을 포괄하는 데이터셋을 형성한다. 카테고리당 최소 5–10가지 전형적 템플릿을 보유하여 다중 템플릿 투표 메커니즘을 지원하는 것을 권장한다.
5. 문자 인식 알고리즘 원리 및 템플릿 매칭 실전
5.1 광학 문자 인식 기본 원리 및 발전 맥락
광학 문자 인식(OCR)은 컴퓨터 비수단을 통해 이미지의 문자 내용을 편집 가능한 텍스트로 변환하는 과정이다. 번호판과 같이 구조화되고 제한된 문자 집합을 가진 응용 장면에서, 초기 템플릿 매칭 기반 OCR 기술은 구현이 간단하고 반응이 빠르다는 이유로 오랫동안 주류를 이루었다.
발전 단계는 규칙 기반 방법, 통계적 패턴 인식 방법, 현재 주도적인 딥러닝 방법으로 구분된다. HOG(Histogram of Oriented Gradients) 등의 특징이 국부 에지 방향 분포를 효과적으로 포착하여 문자의 기하학적 구조를 기술하는 데 적합하며, SVM 등 분류기와 결합하여 형변과 노이즈에 대한 견고성을 일정 부분 향상시킬 수 있다.
5.2 고전적 템플릿 매칭 알고리즘 구현
5.2.1 정규화 상호상관(NCC) 매칭도 계산식 유도
정규화 상호상관(NCC)은 밝도 오프셕이 큰 상황에 특히 적합한 이미지 매칭의 고전적 방법이다.
NCC(f,t) = [ΣΣ(f(x,y)-f̄)(t(x,y)-t̄)] / [√(ΣΣ(f(x,y)-f̄)² · ΣΣ(t(x,y)-t̄)²)]
여기서 f̄, t̄는 각각 이미지와 템플릿의 평균 그레이스케일값이다. NCC가 1에 가까울수록 두 이미지가 높은 유사성을 가짐을 의미하며, 0 또는 음수는 큰 차이를 나타낸다. 단순 제곱차(SSD) 대비 전역 밝기 변화에 더 강건하다.
import numpy as np
def calculate_ncc(image, template):
img_float = image.astype(np.float32)
tmp_float = template.astype(np.float32)
img_mean = np.mean(img_float)
tmp_mean = np.mean(tmp_float)
img_centered = img_float - img_mean
tmp_centered = tmp_float - tmp_mean
numerator = np.sum(img_centered * tmp_centered)
denom_img = np.sqrt(np.sum(img_centered ** 2))
denom_tmp = np.sqrt(np.sum(tmp_centered ** 2))
denominator = denom_img * denom_tmp
if denominator == 0:
return 0.0
return numerator / denominator
5.2.2 슬라이딩 윈도우 검색 및 최대 유사도 판정 로직
def match_against_library(input_char, template_collection):
best_match = None
max_similarity = -1.0
for char_label, template_img in template_collection.items():
similarity = calculate_ncc(input_char, template_img)
if similarity > max_similarity:
max_similarity = similarity
best_match = char_label
confidence_threshold = 0.7
if max_similarity < confidence_threshold:
return "UNKNOWN", max_similarity
return best_match, max_similarity
효율성 향상을 위해 템플릿의 평균과 노름을 초기화 단계에서 미리 계산하여 저장하고, 다단계 매칭 메커니즘(저해상도 버전으로 대략적 선별 후 정밀 매칭) 및 해시 색인 가속(PCA 차원 축소 후 LSH 구축)을 적용할 수 있다.
5.3 SVM을 활용한 문자 분류 엔지니어링 적용
템플릿 매칭이 단순한 장면에서 양호한 성능을 보이나, 복잡한 조명, 흐림, 기울기 등의 상황에서 성능 저하가 두드러진다. 이에 머신러닝 분류기 도입이 필수적이며, SVM은 중소규모 샘플 조건에서 우수한 성능을 보이는 고전적인 감독학습 모델이다.
HOG 특징 추출 설정: 셀 크기 8×8, 블록 크기 2×2 셀, 그래디언트 방향 수 9 bins(0°~180°). 32×32 문자 이미지의 경우 특징 벡터 길이는 약 324차원이다.
from skimage.feature import hog
from sklearn.svm import SVC
from sklearn.preprocessing import LabelEncoder
import joblib
def train_plate_svm(X_train, y_train, model_path="plate_svm.pkl"):
features = []
for img in X_train:
hog_features = hog(img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(2, 2), visualize=False)
features.append(hog_features)
X_hog = np.array(features)
encoder = LabelEncoder()
y_encoded = encoder.fit_transform(y_train)
classifier = SVC(kernel='rbf', C=1.0, gamma='scale', probability=True)
classifier.fit(X_hog, y_encoded)
joblib.dump({'model': classifier, 'encoder': encoder}, model_path)
print(f"SVM 모델 저장 완료: {model_path}")
SVM은 본질적으로 이진 분류기이므로, 다중 클래스 문제 처리 시 One-vs-Rest(OvR) 또는 One-vs-One(OvO) 확장 전략이 필요하다. 번호판 문자(약 35개 클래스)의 경우 OvR을 권장하며 probability=True를 설정하여 각 클래스의 신뢰도 분포를 획득한다. 예측 시 최고 점수 레이블뿐 아니라 상위 K개 후보를 후처리 모듈에 제공할 수 있다.
5.4 CNN 모델 훈련 및 배포 최적화
하드웨어 연산력 향상과 함께 CNN은 번호판 문자 인식의 선호 방안이 되었다. 자동으로 다층적 공간 특징을 추출하는 능력이 수작업 특징 공학을 현저히 능가한다.
5.4.1 LeNet-5 구조 개조 적용
import torch
import torch.nn as nn
class PlateRecognizerCNN(nn.Module):
def __init__(self, num_classes=35):
super(PlateRecognizerCNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
self.relu1 = nn.ReLU()
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.relu2 = nn.ReLU()
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(64 * 8 * 8, 512)
self.dropout = nn.Dropout(0.5)
self.fc2 = nn.Linear(512, num_classes)
def forward(self, x):
x = self.pool1(self.relu1(self.conv1(x)))
x = self.pool2(self.relu2(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8)
x = self.relu1(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
이 네트워크는 32×32×1 그레이스케일 이미지를 입력으로 받아 두 차례의 합성곱+풀링을 거쳐 펼치기 후 완전연결층으로 분류한다. 10만 장의 레이블링된 문자 데이터셋에서 훈련 후 Top-1 정확도는 98.7%에 달한다.
5.4.2 데이터 증강 기술
과적합 방지를 위해 훈련 단계에서 데이터 증강을 도입한다:
from torchvision import transforms
train_transform = transforms.Compose([
transforms.RandomRotation((-10, 10)),
transforms.RandomResizedCrop(32, scale=(0.9, 1.1)),
transforms.ColorJitter(brightness=0.2, contrast=0.2),
transforms.ToTensor(),
])
이러한 변환은 실제 장면의 시각적 편차, 스케일 변화, 노출 이상을 시뮬레이션하여 모델의 견고성을 향상시킨다.
5.4.3 모델 경량화 설계
IPC 또는 엣지 디바이스 배포를 위해 지식 증류(대형 모델이 소형 모델 훈련 지도), 양자화(FP32 가중치를 INT8로 변환하여 메모리 점유 감소), 가지치기(불필요한 채널 제거하여 계산량 감소) 등의 기술을 적용한다. 최적화 후 라즈베리파이 4B에서 단일 문자 인식 소요 시간이 20ms 미만으로 실시간 요구를 충족한다.
6. 다조건 적응 설계 및 시스템 성능 평가 체계
6.1 다중 글꼴·다중 조명 조건에서의 템플릿 적응 메커니즘
6.1.1 동적 템플릿 선택: 이미지 선명도에 따른 매칭 템플릿 세트 전환
인식 견고성 향상을 위해 여러 하위 템플릿 라이브러리를 구축하여, 각각 다른 글꼴 스타일과 이미징 품질 등급에 대응한다. 시스템은 전처리 단계에서 라플라스 방분(Var(Laplacian)) 등 이미지 선명도 평가 지표를 통해 입력 이미지 품질을 자동 판단하고, 해당 템플릿 세트를 동적으로 로드하여 매칭을 수행한다.
def evaluate_image_sharpness(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
return laplacian_var
img = cv2.imread("plate.jpg")
sharpness = evaluate_image_sharpness(img)
if sharpness > 300:
template_set = "Template_A_HighDef"
elif sharpness > 150:
template_set = "Template_B_Standard"
else:
template_set = "Template_D_Degraded"
이 메커니즘은 "정적 매칭"에서 "상황 인식 매칭"으로의 도약을 실현하여 복잡한 환경에서의 인식 안정성을 효과적으로 향상시킨다.
6.1.2 적응형 밝도 보정 및 대비도 향상 전처리 체인 통합
CLAHE 기반의 국부 향상 전략에 감마 보정을 결합하여 밝도 자동 조절을 구현한다:
def adaptive_brightness_correction(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(gray)
mean_val = np.mean(enhanced)
gamma = 1.0 if mean_val > 120 else 0.8
corrected = np.power(enhanced / 255.0, gamma) * 255
return corrected.astype(np.uint8)
6.2 인식 결과 문법 검증 및 형식 규칙 검증
6.2.1 중국 번호판 부호 규칙 모델링
| 번호판 유형 | 부호 구조 | 예시 | 특징 |
|---|---|---|---|
| 소형 자동차 | 성·직할시 약칭 + 문자 + 5자리 숫자/문자 조합 | 京A·12345 | 3번째부터 문자 포함 가능 |
| 신에너지차 | 성·직할시 약칭 + 문자 + 6자리 숫자/문자(시작·끝 문자) | 沪D·F1234 | 녹색 번호판, 2·6번째 문자 |
| 군용 차량 | 한자 + 문자 + 5자리 숫자 | 军A·12345 | 특수 접두사 |
| 대사관 차량 | 使 + 3자리 숫자 + 문자 + 3자리 숫자 | 使123·AB456 | 외교 전용 |
6.2.2 유한 상태 기계 기반 합법 번호판 형식 검증
유한 상태 기계(FSM)를 사용하여 문자 시퀀스의 합법성을 판정한다. 상태 전이 그래프를 정의하여 번호판의 각 위치별 허용 문자 유형을 제한하고, 인식 후 즉시 출력 문자열이 국가 규범에 부합하는지 검증하여 불법 조합을 거부한다.
6.3 혼동 문자 교정 전략 설계
6.3.1 혼동 문자 쌍 분석
| 원본 문자 | 혼동 대상 | 발생 빈도(%) | 주요 원인 |
|---|---|---|---|
| 0 | D, Q | 12.3 | 원형 폐쇄 구조 유사 |
| 1 | I, l | 9.7 | 수직 선분 구분 특징 없음 |
| 5 | S | 6.1 | 곡선 윤곽 유사 |
| 8 | B | 5.4 | 이중 환 구조 오판 |
| Z | 2 | 4.8 | 사각 유사 |
6.3.2 문맥 의미 제약 하의 치환 제안 생성
전후 문자의 문맥 정보를 활용하여 확률적 수정을 수행한다. 예를 들어 성·직할시 약칭 뒤에는 일반적으로 도시 코드 문자(A-Z)가 오므로, "京0"으로 인식된 경우 "0"을 "A-Z" 범위에서 외관이 가장 유사한 후보 문자로 우선 치환한다.
베이즈 사후 확률 모델 P(c|x) ∝ P(x|c)·P(c)를 적용하여, P(x|c)는 템플릿 매칭 점수, P(c)는 역사 데이터베이스 통계 기반의 선험적 언어 모델 확률을 의미한다. 이를 통해 전체 인식 파이프라인의 정확도를 추가로 향상시킬 수 있다.