자동차판 번호인식은 이전 OCR 문제와는 달리 자동차 번호판을 인식할 수 있는 모델(Haar Cascade feature set, XML 파일)을 다른 팩키지 사용하는 것과 비슷한 방식으로 사용한다. haarcascade_russian_plate_number.xml
파일을 XML 파일 다운로드 한다.
먼저 차량 번호판 인식에 필요한 모듈을 설치한다. pytesseract
에서는 쉘로 tesseract
를 호출해서 OCR 작업을 수행하기 때문에 tesseract
를 설치하고 pytesseract
에서 불러와서 사용하도록 설정작업을 한다. 번호판 인식을 위해서 앞서 다운로드 받은 Haar Cascade feature set, XML 파일을 지정한다.
# 관련 작업 모듈 불러오기 ---------------
import cv2
import pytesseract
import matplotlib.pyplot as plt
# Tesseract 설정 ------------------------
= r"/usr/local/bin/tesseract"
pytesseract.pytesseract.tesseract_cmd
# 번호판 인식 모듈 -----------------------
= cv2.CascadeClassifier('data/haarcascade_russian_plate_number.xml') carplate_haar_cascade
OpenCV를 통해 자동차 이미지를 확인해보자.
# 차량 번호판 인식 ------------------
= cv2.imread('fig/ocr-bmw-car-plate.jpg')
carplate_img = cv2.cvtColor(carplate_img, cv2.COLOR_BGR2RGB)
carplate_img_rgb plt.imshow(carplate_img_rgb)
원본 이미지를 그대로 Haar Cascade feature set에 넣어 번호판을 제대로 인식하는지 확인하자. 자동차 번호판이 삐뚤어져 있어 엉뚱한 영역을 차량 번호판으로 인식한 것을 확인할 수 있다.
# 차량 번호판 인식 함수 -----------------
def carplate_detect(image):
= image.copy()
carplate_overlay = carplate_haar_cascade.detectMultiScale(carplate_overlay, scaleFactor=1.1, minNeighbors=3)
carplate_rects
for x,y,w,h in carplate_rects:
+w,y+h), (255,0,0), 5)
cv2.rectangle(carplate_overlay, (x,y), (x
return carplate_overlay
= carplate_detect(carplate_img_rgb)
detected_carplate_img plt.imshow(detected_carplate_img)
다양한 전처리 작업이 있지만, 먼저 자동차 이미지를 적절한 각도 15도 회전하여 차량 번호표 인식기에 넘겨 제대로 번호표를 추출했는지 시각적으로 확인해보자.
# 차량 이미지 회전 후 번호판 인식 ---------------------
= carplate_img_rgb.shape
height, width, channel = cv2.getRotationMatrix2D((width/2, height/2), 15, 1)
matrix = cv2.warpAffine(carplate_img_rgb, matrix, (width, height))
carplate_rotated_rgb
= carplate_detect(carplate_rotated_rgb)
carplate_rotated_rgb
plt.imshow(carplate_rotated_rgb)
OCR
본 작업수행을 위해서 추출된 이미지를 그레이(회색) 이미지로 변환시키고 나서 텍스트 추출작업을 수행한다.
# 번호판 추출 -----------------------------------------
def carplate_extract(image):
= carplate_haar_cascade.detectMultiScale(image,scaleFactor=1.1, minNeighbors=5)
carplate_rects
for x,y,w,h in carplate_rects:
= image[y+15:y+h-10 ,x+55:x+w-7]
carplate_img
return carplate_img
= carplate_extract(carplate_rotated_rgb)
carplate_extract_img
# OCR 이미지 전처리 작업 -----------------------------
= cv2.cvtColor(carplate_extract_img, cv2.COLOR_RGB2GRAY)
carplate_extract_img_gray # carplate_extract_img_gray_blur = cv2.medianBlur(carplate_extract_img_gray, 3)
'off') plt.axis(
(0.0, 1.0, 0.0, 1.0)
= 'gray'); plt.imshow(carplate_extract_img_gray, cmap
이제 tesseract를 호출해서 이미지 속에 담긴 번호판을 추출한다. 깔끔한 OCR 결과 추출을 위해서 tessedit_char_whitelist
에 인식할 대상 문자를 미리 지정한다.
# OCR 작업 -------------------------------------------
= pytesseract.image_to_string(carplate_extract_img_gray, lang='kor',
car_plate_text = f'--psm 8 --oem 3 -c tessedit_char_whitelist=오ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
config
car_plate_text
'19오1777\n\x0c'
사진속 이미지에서 번호판이 위치한 곳의 좌표를 특정하여 리스트 객체로 저장한다.
def carplate_coordinate(image):
= carplate_haar_cascade.detectMultiScale(image,scaleFactor=1.1, minNeighbors=5)
carplate_rects
for x,y,w,h in carplate_rects:
= [x, y, w, h]
carplate_coord
return carplate_coord
= carplate_coordinate(carplate_rotated_rgb)
carplate_coord carplate_coord
[334, 246, 258, 86]
상기 좌표를 반영하여 사진 속 이미지 위에 번호판 위치와 인식된 글씨를 동시에 표식한다. magick
팩키지를 사용해서 파이썬에서 인식한 OCR 객체를 다시 이미지 위에 표식한다.
library(tidyverse)
library(magick)
<- image_read("fig/ocr-car-plate.jpeg")
car_image
# Not working ----------------------------------
# carplate_position <- glue::glue("{py$carplate_coord[[3]]} x {py$carplate_coord[[4]]} + {py$carplate_coord[[1]]} + {py$carplate_coord[[2]]}")
#
# car_image %>%
# image_crop(geometry = carplate_position)
library(extrafont)
loadfonts()
%>%
car_image image_annotate(text = py$car_plate_text %>% str_extract(., pattern = "[가-힣0-9]+"),
location = "+100+15",
degrees = 10,
color = "red",
size = 20,
font = "NanumBarunGothic")
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com