728x90
반응형
www.youtube.com/watch?v=TV3oplqa5VA(유튜브 영상)참고
!pip install tensorflow-gpu==2.0.0-rc1
import tensorflow as tf
#손글씨모듈
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.image import ImageDataGenerator
batch_size = 128
num_classes = 10
epochs = 12
# 데이터셋 불러오기
img_rows, img_cols = 28,28
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 컨볼루션 신경망 모델이 요구하는 형태로 이미지 배열 변환
# 마지막에 차원하나 추가
x_train = x_train.reshape(x_train.shpae[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1) # 28*28*1
# 이미지 실수타입으로 변경, 픽셀 0~1로 정규화
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
# 원핫인코딩
y_train = to_categorical(y_train, num_classes)
y_test = to_categorical(y_test, num_classes)
# 컨볼루션 신경망 모델 구축
model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3), activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
# 좋은 결과를 위해 회전, 평행이동으로 데이터셋 양 늘리기
datagen = ImageDataGenerator(rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
fill_mode='nearest')
# 모델 학습
modle.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
steps_per_epoch=x_train.shape[0] // batch_size,
validation_data=(x_test, y_test),
epochs=epochs, verbose=2)
# 성능평가
score = model.evatluate(x_test, y_test, verbose=2)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# 파일저장
model.save('model.h5')
#학습된 모델로 실제 손글씨 인식시키기
import cv2 as cv
import numpy as np
import tensorflow.keras.models import load_model
#이미지 파일 불러와서 그레이스케일 이미지로 변환
img_color = cv.imread('test3.jpg', cv.IMREAD_COLOR)
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)
#그레이스이미지 바이너리로 변환
ret,img_binary = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
#모폴로지 연산 적용(이진화 결과 혹시모를 빈 공간 메꾸기)
kernel = cv.getStrucuringElement(cv.MORPH_RECT, (5,5))
img_binary = cv.morphologyEx(img_binary, cv.MORPH_CLOSE, kernel)
cv.imshow('digit', img_binary)
cv.waitKey(0)
#숫자별로 분리하기 위해 컨투어 검출
contours, hierarchy = cv.findContours(img_binary, cv.RETR_EXTERNAL,
cv.CHAIN_APPROX_SIMPLE)
for contour in contours:
#숫자별로 경계박스 구하기
x,y,w,h = cv.boundingRect(contour)
#가로,세로 중 긴 방향 선택, 여분추가해 한 변의 크기 정하기
#잘라낼 이미지를 저장할 빈 이미지 생성
length = max(w, h) + 60
img_digit = np.zeros((length, length, 1),np.unint8)
#숫자가 이미지의 정중앙에 오도록 경계박스의 시작 위치 조정
new_x, new_y = x-(length - w)//2, y-(length - h)//2
# 바이너리 이미지에서 숫자 영역 가져와 변수에 저장
img_digit = img_binary[new_y:new_y+length, new_x:new_x+length]
#숫자가 잘 인식되도록 팽창 모폴로지 연산 적용
kernel = np.ones((5,5), np.unit8)
img_digit = cv.morphologyEx(img_digit, cv.MORPH_DILATE, kernel)
cv.imshow('digit', img_digit)
cv.waitKey(0)
#학습된 모델 불러오기
model = load_model('model.h5')
#이미지 크기를 학습된 모델에서 요구하는 가로세로 28로 변환
img_digit = cv.resize(img_digit, (28,28), interpolation=cv.INTER_AREA)
img_digit = img_digit /255.0 #이미지 픽셀도 변환
img_input = img_digit.reshape(1, 28, 28, 1) #이미지 형태도 변환
#이미지를 입력으로 사용해 예측 진행
predictions = model.predict(img_input)
#argmax함수를 사용해 softmax 결과를 숫자로 변환
number = np.argmax(predictions)
print(number)
#원본 이미지의 숫자마다 사각형 그려주기
cv.rectangle(img_color, (x,y), (x+w, y+h), (255,255,0), 2)
#이미지에 있는 숫자 위에 인식된 숫자 적어주기
location = (x+int(w*0.5), y-10)
font = cv.FONT_HERSHEY_COMPLEX
fontScale = 1.2
cv.putText(img_color, str(number), location, font, fontScale, (0,255,0),2)
#이미지에서 잘라낸 숫자를 가공한 결과
cv.imshow('digit', img_digit)
cv.waitKey(0)
#원본 이미지에 인식한 숫자를 적은 결과
cv.imshow('result' img_color)
cv.waitKey(0)
728x90
반응형
'딥러닝 (Deep Learning) > 딥러닝 분석연습' 카테고리의 다른 글
뉴스 기사 분류 : 로이터(Reuters) 데이터셋 (병목현상, 레이블을 벡터로 바꾸는 방법들 2가지) (0) | 2021.04.27 |
---|---|
영화 리뷰 분류 : IMDB(Internet Movie Database) (0) | 2021.04.26 |
Keras 정의, 특징, 사용법 (0) | 2021.04.21 |
MNIST - practice1,2 + 자세한 설명 (0) | 2021.04.11 |