728x90
OpenCV DNN(MNIST)
import sys
import numpy as np
import cv2
oldx, oldy = -1, -1
def on_mouse(event, x, y, flags, _):
global oldx, oldy
if event == cv2.EVENT_LBUTTONDOWN:
oldx, oldy = x, y
elif event == cv2.EVENT_LBUTTONUP:
oldx, oldy = -1, -1
elif event == cv2.EVENT_MOUSEMOVE:
if flags & cv2.EVENT_FLAG_LBUTTON:
cv2.line(img, (oldx, oldy), (x, y), (255, 255, 255), 40, cv2.LINE_AA)
oldx, oldy = x, y
cv2.imshow('img', img)
def norm_digit(img):
m = cv2.moments(img)
cx = m['m10'] / m['m00']
cy = m['m01'] / m['m00']
h,w = img.shape[:2]
aff = np.array([[1,0, w/2-cx], [0,1,h/2-cy]], dtype = np.float32)
dst = cv2.warpAffine(img, aff, (0,0))
return dst
net = cv2.dnn.readNet('mnist_cnn.pb')
if net.empty():
print('Network load failed!')
sys.exit()
img = np.zeros((400, 400), np.uint8) #숫자를 그릴 판
cv2.imshow('img', img)
cv2.setMouseCallback('img', on_mouse)
while True:
c = cv2.waitKey()
if c == 27:
break
elif c == ord(' '):
#직접 그린 숫자 400*400짜리 이미지를 blob이라는 객체로 변환
#blob은 4차원 형식의 ndarray (N,C,H,W)
#학습 시, 학습데이터 픽셀값을 0~1까지 정규화하여 학습했으므로 1/255.을 넣어서 똑같이 정규화 해준다
#학습 데이터 mnist 크기그 28*28이였으므로 똑같은 크기인 28*28 resize 시행
#내가 그린 숫자를 가운데에 위치시켜 놓고 진행: norm_digit
blob = cv2.dnn.blobFromImage(norm_digit(img), 1/255., (28, 28))
net.setInput(blob)
'''
prob: (1,10) 10개의 elemnet가 있고,
확률이 최대값인 element의 인덱스값 = 모델이 인식한 숫자
'''
prob = net.forward()
print('prob',prob)
#최대값인 확률값과 그 위치를 반환
_, maxVal, _, maxLoc = cv2.minMaxLoc(prob)
print('maxLoc',maxLoc)
digit = maxLoc[0] #최대값 성분의 index값
print(f'{digit} ({maxVal * 100:4.2f}%)')
img.fill(0)
cv2.imshow('img', img)
cv2.destroyAllWindows()
OpenCV DNN_googlenet
import sys
import numpy as np
import cv2
# 입력 영상 불러오기
filename = 'space_shuttle.jpg' #우주선
if len(sys.argv) > 1: #명령창에서 py명[0], 입력영상[1] 쓰면 같이 실행되게끔 하는 ㅋ코드
filename = sys.argv[1]
img = cv2.imread(filename)
if img is None:
print('Image load failed!')
sys.exit()
# 네트워크 불러오기
# Caffe
# model = 'googlenet/bvlc_googlenet.caffemodel'
# config = 'googlenet/deploy.prototxt'
# ONNX
model = 'googlenet/googlenet-9.onnx'
config = '' #ONNX에서는 config 필요 없음
net = cv2.dnn.readNet(model, config)
if net.empty():
print('Network load failed!')
sys.exit()
# 클래스 이름 불러오기
classNames = None
with open('googlenet/classification_classes_ILSVRC2012.txt', 'rt') as f:
classNames = f.read().rstrip('\n').split('\n') #공백 단위로 제거와 분리 진행
# 추론
#1: 학습 시 0~255를 사용했다는 의미
#(104, 117, 123): BGR평균값?
blob = cv2.dnn.blobFromImage(img, 1, (224, 224), (104, 117, 123))
net.setInput(blob)
prob = net.forward()
# 추론 결과 확인 & 화면 출력
out = prob.flatten()
classId = np.argmax(out) #가장 큰 값이 있는 위치 찾기
confidence = out[classId] #가장 큰 확률 값 나타내기
text = f'{classNames[classId]} ({confidence * 100:4.2f}%)'
cv2.putText(img, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 1, cv2.LINE_AA)
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
728x90
'실습 note' 카테고리의 다른 글
제조 공정 불량 검출 실습 (0) | 2021.03.11 |
---|---|
OpenCV_12(딥러닝2) (0) | 2021.03.05 |
OpenCV_10(머신러닝) (0) | 2021.03.03 |
OpenCV_9(객체 추적과 모션벡터) (0) | 2021.03.01 |
OpenCV_8(특징점 검출&매칭) (0) | 2021.02.26 |