import cv2
import numpy as np
net = cv2.dnn.readNetFromTorch('models/eccv16/starry_night.t7')
img = cv2.imread('imgs/01.jpg')
cv2.imshow('img', img)
cv2.waitKey(0)
모델의 성능을 높이기 위해 이미지 전처리라는 방법을 쓴다.
모델의 성능이라고 하면 일반적으로는 딥러닝 모델이 얼마나 정답을 잘 맞추는지를 가리키는 정확도를 말한다.
h, w, c = img.shape
img = cv2.resize(img, dsize=(500, int(h / w * 500)))
MEAN_VALUE = [103.939, 116.779, 123.680]
blob = cv2.dnn.blobFromImage(img, mean=MEAN_VALUE)
img.shape
: 이미지의 높이, 너비, 채널을 받을 수 있다. 우리는 이 이미지를 너비 500으로 이미지의 크기를 변형시켜서 아무리 큰 이미지를 사용해도 모델의 추론 속도가 비슷하도록 만들어야 한다. 왜냐하면 큰 이미지를 사용 할 수록 연산 속도가 느리기. 때문!!MEAN_VALUE
: 연구원들이 사용했던 전처리 방법cv2.dnn.blobFromImage
: 우리가 하기 귀찮은 작업들을 한꺼번에 할 수 있도록 도와준다.딥러닝 모델에 넣기 위해선 이미지의 차원 변형이 필요하다.
print(img.shape) # 차원 변형 전 (325, 500, 3)
MEAN_VALUE = [103.939, 116.779, 123.680]
blob = cv2.dnn.blobFromImage(img, mean=MEAN_VALUE)
print(blob.shape) # 차원 변형 후 (1, 3, 325, 500)
(높이, 너비, 채널) 의 순서를 (1, 채널, 높이, 너비) 로 변형했다. 데이터의 형태만 변형된 것이지 값이 변형된 것은 아니다.
차원 변형 후 (1, 채널, 높이, 너비) 모양에서 1은 딥러닝에서 배치 사이즈를 의미한다. 딥러닝 모델을 학습시키는 과정에서 이미지를 한 장씩 학습시키지 않고 여러 이미지를 한꺼번에 학습시키는데 만약 이미지를 32개씩 묶어서 학습시킨다면 배치 사이즈는 32가 된다. (32, 채널, 높이, 너비)
우리는 이 모델을 연구한 연구원들이 어떤 배치 사이즈를 사용했는지는 관심이 없고, 1개의 테스트 이미지를 사용할 것이므로 배치 사이즈가 1이 된다.
따라서 (1, 채널, 높이, 너비) 형태가 되는 것!!
net.setInput(blob)
output = net.forward()
전처리한 이미지(blob)를 모델에 넣고 추론(forward)한다.
output 변수에 추론한 결과가 저장된다.
우리는 추론한 결과를 숫자로 볼 수도 있지만 이미지로 보기를 원하기 때문에 숫자 → 이미지 변환 과정을 거쳐야한다.
이미지를 전처리했듯이 결과값을 후처리하여 다시 이미지로 만드는 과정!!
output = output.squeeze().transpose((1, 2, 0))
output += MEAN_VALUE
output = np.clip(output, 0, 255)
output = output.astype('uint8')
전처리했던 과정을 거꾸로 진행한다!!
차원 줄이기
차원 변형했던 것을 원래대로 (높이, 너비, 채널) 순으로 되돌려놓는다. squeeze()
를 사용하여 추가했던 첫 번째 차원을 삭제하여 (1, 채널, 높이, 너비)에서 (1, ) 부분을 없애고 (채널, 높이, 너비) 형태로 만든다.
순서 바꾸기
transpose()
를 사용하여 (채널, 높이, 너비) → (높이, 너비, 채널) 형태로 변형한다.
MEAN_VALUE
더하기
전처리 했을 때 MEAN_VALUE 를 뺐는데 후처리 할 때는 MEAN_VALUE를 다시 더해준다.
범위 넘어가는 값 잘라내기
이미지 픽셀 값은 0-255 범위 안에 들어와야하는데 계산 과정에서 간혹 픽셀 값이 0 미만이거나 255를 초과하는 픽셀이 생긴다. 이런 값들을 np.clip()
을 사용하여 없애줄 수 있다.
자료형 바꾸기
마지막으로 이미지의 자료형을 일반 이미지에서 쓰이는 정수형(uint8
)으로 바꿔준다.
cv2.imshow('img', img)
cv2.imshow('output')
cv2.waitKey(0)
import cv2
import numpy as np
net = cv2.dnn.readNetFromTorch('models/eccv16/starry_night.t7')
img = cv2.imread('imgs/01.jpg')
h, w, c = img.shape
img = cv2.resize(img, dsize=(500, int(h / w * 500)))
MEAN_VALUE = [103.939, 116.779, 123.680]
blob = cv2.dnn.blobFromImage(img, mean=MEAN_VALUE)
net.setInput(blob)
output = net.forward()
output = output.squeeze().transpose((1, 2, 0))
output += MEAN_VALUE
output = np.clip(output, 0, 255)
output = output.astype('uint8')
cv2.imshow('img', img)
cv2.imshow('output', output)
cv2.waitKey(0)
img = cv2.imread('imgs/02.jpg')
h, w, c = img.shape
img = cv2.resize(img, dsize=(500, int(h / w * 500)))
img = img[162:513, 185:428]
import cv2
import numpy as np
net = cv2.dnn.readNetFromTorch('models/eccv16/la_muse.t7')
img = cv2.imread('imgs/02.jpg')
h, w, c = img.shape
img = cv2.resize(img, dsize=(500, int(h / w * 500)))
img = img[162:513, 185:428]
MEAN_VALUE = [103.939, 116.779, 123.680]
blob = cv2.dnn.blobFromImage(img, mean=MEAN_VALUE)
net.setInput(blob)
output = net.forward()
output = output.squeeze().transpose((1, 2, 0))
output += MEAN_VALUE
output = np.clip(output, 0, 255)
output = output.astype('uint8')
cv2.imshow('img', img)
cv2.imshow('output', output)
cv2.waitKey(0)
import cv2
import numpy as np
net = cv2.dnn.readNetFromTorch('models/instance_norm/mosaic.t7')
img = cv2.imread('imgs/03.jpg')
h, w, c = img.shape
img = cv2.resize(img, dsize=(500, int(h / w * 500)))
MEAN_VALUE = [103.939, 116.779, 123.680]
blob = cv2.dnn.blobFromImage(img, mean=MEAN_VALUE)
net.setInput(blob)
output = net.forward()
output = output.squeeze().transpose((1, 2, 0))
output += MEAN_VALUE
output = np.clip(output, 0, 255)
output = output.astype('uint8')
cv2.imshow('img', img)
cv2.imshow('result', output)
cv2.waitKey(0)
net2 = cv2.dnn.readNetFromTorch('models/instance_norm/the_scream.t7')
net2.setInput(blob)
output2 = net2.forward()
output2 = output2.squeeze().transpose((1, 2, 0))
output2 = output2 + MEAN_VALUE
output2 = np.clip(output2, 0, 255)
output2 = output2.astype('uint8')
output3 = np.concatenate([output[:, :250], output2[:, 250:]], axis=1)
cv2.imshow('output3', output3)