본문 바로가기
프로젝트+스터디

AI기반 OCR 프로젝트 1_주제선정

by 코낄2 2024. 3. 12.
웹개발 프로젝트와 자연어 처리 프로젝트가 끝나고, 이어서 진행이 된 OCR 프로젝트.

 

총 5명의 구성으로 팀을 짜서 진행을 하게 되었다.

 

프로젝트는 AI 기반이지만 당시 수업 진도는 CV(computer vision) 단계였고, AI 모델들에 대한 지식이 없는 상태에서 기획을 먼저 시작하다보니 🤔 , 다들 주제를 잡는데 어려움을 느끼고있었다.

 

우선 강사님께서 "아무래도 시간이 정해져있는 프로젝트다 보니" 자연어 처리때처럼 데이터를 직접 만드는데는 한계가 있다고 하시면서, "최대한 데이터를 충분히 구할 수 있는 주제"를 잡으라고 힌트를 주셨다. 그리고 이전 기수가 진행했던 프로젝트를 보면서 대충 어떤 방식으로 진행이 되는지 감을 잡아갔다.

그 당시 cv로 다양한 영상 처리 기법을 배우고 있었기 때문에, 전처리로 영상을 최대한 다양하게 처리해서 입력 혹은 학습을 시키고 모델의 param을 다양하게 변화시켜 모델을 완성시키겠구나 예상을 해보면서 기획 아이디어를 냈다.

 

1. 주제 선정

AI-Hub에서 데이터를 보면서 "패션 추천 서비스", "반려동물 훈련 혹은 진단 서비스", "청각장애인 분들을 위한 구화 서비스", "자동 레시피화 서비스", "약품 관리 서비스", "시각 장애인을 위한 보행 장애물 안내 서비스", "스포츠, 운동 자세 교정 서비스" 등 재미있는 의견이 다양하게 제시되었다. 

 

아직 기업의 상업적 서비스보다 내가 흥미있는 주제를 선택할 수 있는 지금, 배운 기술을 좀 더 사회적으로 공헌하고 공익적인 발전에 도움이 되는 서비스를 해보고 싶었다.

다행히 조원들도 나의 의견에 동의를 해주어 단순히 재미있는 주제보다는 공익적으로 의미가 있는 주제들로 선택 폭을 좁혀갈 수 있었다. 아무래도 VisionRecognition 을 기반으로 하는 프로젝트기 때문에 "시각 장애인을 위한 서비스" 쪽으로 의견이 기울었고, 모든 조원이 흥미를 느낀 주제는 시각장애인을 위한 보행자 신호 감지 서비스였다.

 

 

-문제-

문제는 "보행자 신호등에 대한 데이터를 구하는데 어려움이 있다"는 것이었다. AI-Hub에는 차량 신호등에 대한 데이터밖에 없었고, 기한이 2주밖에 남지 않은 시점에서 직접 발품을 팔고 인터넷에서 보행자 신호등에 대한 데이터를 모으기에는 한계가 있었다. 

이 때문에 몇몇 조원들은 데이터가 충분해서 의미있는 결과를 도출할 수 있는 다른 주제를 원했고, '도로 장애물/표면 인지 영상'을 이용한 도로 파손과 낙하물을 인지하는 주제를 새로 제시했다.

 

"보행자 신호 감지" : 기한이 짧고 데이터가 부족해서 결과가 잘 안나오는 부분은 현직에서도 충분히 이해를 해줄 수 있는 부분이다. 조금 어렵더라도 도전을 해야 공부가 되고, 즐겁게 진행할 수 있다.
"도로 장애물 인지" : 하고싶은 주제를 하는 것도 중요하지만 현실적으로 진행이 가능해야한다. 2주동안 대부분의 시간을 직접 데이터를 모으고 라벨링을 하는데만 쓰는 것도 공부에 도움이 되지 않는다.

 

-해결 과정-

두가지의 의견으로 갈린 상황에서 해결 방법을 찾기 위해,

1. 첫번째로 모든 조원들이 흥미를 느꼈던 보행자 서비스가 얼마나 현실성 있는지를 파악해보기로 했다. 조장이 깃허브에 나온 코드를 바탕으로 우선 차량 신호등을 학습시키고, 그 모델에 보행자 신호등을 인식시켰을 때 어느 정도까지 인식이 되는지 알아보았다. 

2. 두번째로 나는 도로 장애물에 대한 주제가 싫은 이유가 '너무 단순해서 재미가 없을 것 같다'라는 것을 파악하고 조금 더 덧붙일 기술이 없을지를 고민해보았다.

 

그 결과 첫번째 해결책에서는 차량 신호를 학습한 모델에서 보행자 신호등을 '확대시켜서 넣었을 때', 신호등이라는 것은 인식하지 못하지만 초록불이나 빨간불이라는 결과는 도출할 수 있음을 알아내었다. 따라서 사용자가 찍은 화면을 구간을 나눠서 확대한 후 모델에 넣어 빨간불과 초록불을 인식하게 하는식으로 프로젝트를 진행할 수 있을 지 컨펌을 받아보기로 했다. 하지만  강사님께서 보행자 신호등의 모양이 매우 다양하기 때문에, 제시한 방법으로도 의미있는 결과를 얻어내기 힘들거라고 하셨고, 제한된 시간안에 충분한 데이터를 라벨링하기에는 한계가 있다고 피드백을 주셨다.

 

그래서 두 번째 방안으로 마련해둔 '과적차량 인식'이라는 주제를 진행해보기로 했다!! 

 

두 번째 방안은 내가 도로 장애물에서 착안하여 새로 찾아낸 주제로 조원들에게 과적차량 신고에 대한 필요성을 설명하고 해당 차량을 인식하는데서 그치지 않고 실시간으로 신고까지 해주는 시스템을 만드려면 지금 배우고 있는 OCR을 통해 번호판을 읽어내는 과정까지 필요함을 어필했다.

따라서 과적차량을 인식하고, 번호판의 위치까지 인식하는 '복합적인 모델 학습'이 필요함
어필되어 '단순한 프로젝트가 재미없을 것 같다'는 조원들까지 설득할 수 있었다.👍

 

 

-결과-

과적 차량을 자동으로 인식하고 실시간으로 기록하는 시스템을 진행해보기로 했다.

 

2. OCR 세미 프로젝트

아무래도 번호판은 개인정보이기때문에 구할 수 있는 데이터들은 차량 번호판이 블러처리가 되어있었고, 라벨링된 데이터로는 '번호판의 위치'만 인식할 수 있었다. 따라서 "번호판의 위치가 인식되면 해당 위치에서 번호를 읽어올 수 있는가?"를 인증하는 것이 우선 과제였다. 따라서 AI 모델을 학습시키기 전, OCR 모델의 성능을 먼저 확인해보기로 했다.

 

결론부터 말하자면, OCR 모델을 이용하여 "번호판 위치에서 번호를 충분히 읽어올 수 있다."

 

원본에서 번호판 위치를 그냥 확대를 해오면 이미지 픽셀이 많이 깨지지만, perspective를 이용하여 확대하면 이미지가 많이 깨지지 않는다는 점을 발견했다.

img_path_1 = "/content/drive/MyDrive/KDT/resize.jpg"

# resize
# 510*850/579*850/ 510*889/579*889
image = cv2.imread(img_path)

img_big1 = cv2.resize(image[850:890, 510:580], (70, 40), interpolation=cv2.INTER_CUBIC)

w, h = 700, 400
srcQuad = np.array([[510, 850], [580, 850], [510, 890], [580, 890]], np.float32)
dstQuad = np.array([[0, 0], [w, 0], [0, h], [w, h]], np.float32)
pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
img_big2 = cv2.warpPerspective(image, pers, (w, h))

# 시각화
plt.figure(figsize=(21, 12))

plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(img_big1, cv2.COLOR_BGR2RGB))
plt.title('Cropped and Resized Image')
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(img_big2, cv2.COLOR_BGR2RGB))
plt.title('Perspective Transformed Image')
plt.axis('off')

plt.show()
 

원본사진 / resize한 이미지/ perspective로 불러온 이미지

 

따라서 해상도와 노이즈가 다양한 5단계 이미지를 perspective로 확대하여 다양한 모델의 성능 평가 진행하였다. 

이미지와 다양한 전처리를 적용시킨 결과

 

TESSERACT, CLOVA, EASYOCR, GOOGLE API, PADDLE 총 5가지 모델을 평가 하였다.

위는 전처리 없이 원본 사진에서 문자를 인식하였을 때의 결과이다. paddle 모델이 전처리 없이도 꽤 좋은 결과를 보였다. 심지어 전역 오츠 이진화 전처리를 통해 5개의 모든 결과물에서 정확한 문자 인식에 성공했다.

norm_img = cv2.normalize(image4, None, 0, 255, cv2.NORM_MINMAX)
gray_image = cv2.cvtColor(norm_img, cv2.COLOR_BGR2GRAY)

_, bi_img = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

 

따라서, paddle 모델을 통해 과적차량 인식과 실시간 번호판 기록 시스템을 구축해보기로 했다.