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

+ Recent posts