숫자인식프로그램(1개의 숫자 인식하기)
학교 중간과제로 숫자인식 프로그램을 만들라는 프로젝트를 내주셨다. mnist데이터를 이용하여 모델링을하였다. 모델 model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input..
lsn5963.tistory.com
저번에는 1개의 숫자만 인식하였다.
하지만 이번에는 여러개의 숫자를 인식하는 프로그램을 작성해볼 것 이다.
전에 내용과 거의 비슷하지만 전처리 하는 과정이 다르다.
그래서 전의 내용과 다른 부분만 다루려고 한다.
모델을 가져와서 최적화를 하고 mnist데이터를 전처리하는 과정까지는 같다.
사진 확인하기
import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab.patches import cv2_imshow
%matplotlib inline
src = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
#이미지의 크기가 워낙 크기 때문에 5분의1로 줄여서 확인을 합니다.
src = cv2.resize(src , (int(src.shape[1]/5),int(src.shape[0]/5)))
cv2_imshow(src)

이렇게 사진을 캠에서 찍었다.
사진 전처리
#양 옆의 노이즈를 제거합니다.(만약 노이즈가 없다거나 사진을 다시찍을 경우 이 코드는 필요가 없습니다.)
src = src[1:src.shape[0]-5, 10:src.shape[1]-38]
사진의 양 옆에 있는 빈 공간을 없애주는 것이다.
하지만 수동적으로 사진마다 해결해주어야 되기 때문에 번거롭다.
실험을 해본 결과 이 코드의 유무가 결과의 큰 차이를 가져오지는 않기 때문에 없애도 괜찮을 것 같다.
#영상 이진화를 해줍니다.(사람마다 카메라의 상태가 다르기 때문에 필요시 보정이 필요합니다.)
ret , binary = cv2.threshold(src,105,255,cv2.THRESH_BINARY_INV)
cv2_imshow(binary)
mnist데이터는 흰글씨에 검은 바탕이지만 웹캠사진은 검은글씨에 흰 바탕이기 때문에 threshold를 사용하여 이진화 해줬다.

contours , hierarchy = cv2.findContours(binary , cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_SIMPLE) #외곽선 검출을 해줍니다.
color = cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR) #이진화 이미지를 color이미지로 복사를 해줍니다.(확인용)
cv2.drawContours(color , contours , -1 , (0,255,0),3) #초록색으로 외곽선을 그려줍니다.
#리스트연산을 위해 초기변수 선언해줍니다.
bR_arr = []
digit_arr = []
digit_arr2 = []
count = 0
#검출한 외곽선에 사각형을 그려서 배열에 추가해줍니다.
for i in range(len(contours)) :
bin_tmp = binary.copy()
x,y,w,h = cv2.boundingRect(contours[i])
bR_arr.append([x,y,w,h])
글씨를 초록색으로 바꿔주고 숫자를 분류해주는 작업이다.
#작은 노이즈데이터 버림,사각형그리기,12개씩 리스트로 다시 묶어서 저장을 해줍니다.
for x,y,w,h in bR_arr :
tmp_y = bin_tmp[y-2:y+h+2,x-2:x+w+2].shape[0]
tmp_x = bin_tmp[y-2:y+h+2,x-2:x+w+2].shape[1]
if tmp_x and tmp_y > 10 :
count += 1
cv2.rectangle(color,(x-2,y-2),(x+w+2,y+h+2),(0,0,255),1)
digit_arr.append(bin_tmp[y-2:y+h+2,x-2:x+w+2])
if count == 12 :
digit_arr2.append(digit_arr)
digit_arr = []
count = 0
cv2_imshow(color)
그 다음 digit_arr변수에 분류한 숫자 사진들을 넣어주는 작업을 해준다.

사진을 잘 분류한 것을 알 수 있다.
from tensorflow.keras.applications.nasnet import preprocess_input, decode_predictions
count = 0
nrows = 3
ncols = 4
for n in digit_arr:
img = cv2.resize(n,(28,28))
cv2_imshow(img)
img = img.reshape((-1,28,28,1))
x = np.array(img)
x = preprocess_input(x)
preds = model.predict(x)
print('Predicted:', np.argmax(preds, axis=-1))
이제 이 사진들을 모델에 넣어 예측을 해준다.

결과를 보면 100% 정확하게 나오지는 않는다.
전의 글을 보면 전저치를 하면서 생기는 loss, 캠의 환경등에 따라 결과가 달라진다.
하지만 2,3개를 틀리는 것을 보아 나쁘지는 않다.
다음에는 다른데이터를 통해 프로젝트를 해보고 싶다.
전체 소스코드는 밑에 링크에서 확인할 수 있다.
GitHub - lsn5963/number-recognition-program.
Contribute to lsn5963/number-recognition-program. development by creating an account on GitHub.
github.com