Keras-RetinaNet을 이용한 모델 로딩 및 예측¶
- https://github.com/fizyr/keras-retinanet 을 이용한 모델 로딩과 예측
In [4]:
import random
from keras_retinanet import models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
from keras_retinanet.utils.gpu import setup_gpu
from keras_retinanet.models import load_model
from keras_retinanet.utils.colors import label_color
import os
import pydicom
import cv2
import pandas as pd
import numpy as np
from tqdm import tqdm_notebook as tqdm
GPU 설정¶
- 사용가능한 GPU가 있는 경우 설정
In [106]:
gpu = 0
setup_gpu(gpu)
기존 모델 로드¶
- 레티나넷에서 제공하는 load_model을 이용한다.
- 백본은 resnet이 될수도 있고, 다른 네트워크가 될수도 있음
In [108]:
model = load_model('../input/model_weight.h5', backbone_name='resnet101')
추론 모드로 변환¶
- 추론모드로 변환하지 않으면 추후 아규먼트가 맞지 않음
In [ ]:
model = models.convert_model(model)
기존의 파일에서 랜덤으로 뽑기¶
- 가용성을 보기위해 하나만 일단 뽑는다.
In [159]:
file_list = os.listdir('../images/')
random_file = random.choice(file_list)
dcm = pydicom.read_file('../images/' + random_file)
image = dcm.pixel_array
image.shape
Out[159]:
(참조) PNG로 변환할경우¶
- PNG로 변환할때 MONOCHROME을 참조한다.
- 윈도우사이즈나, 파일의 속성에 따라 노말라이제이션이 필요할 수 있다.
- 실제 훈련에는 DICOM을 그대로 활용하는편이 활용성이 낫다.
In [160]:
# import pylab
# PATH = '../test_png/'
# for name in tqdm(os.listdir('../images/')):
# dcm = pydicom.read_file('../images/' + name)
# image = dcm.pixel_array
# if dcm[('0028','0004')].value == 'MONOCHROME1':
# pylab.imsave(PATH + name + '.png', image, cmap='binary')
# elif dcm[('0028','0004')].value == 'MONOCHROME2':
# pylab.imsave(PATH + name + '.png',image, cmap='gray')
- 변환한 PNG파일 확인
In [161]:
file_list_png = os.listdir('../test_png/')
random_file = random.choice(file_list_png)
bgr = read_image_bgr('../test_png/' + random_file)
image = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) #필요없음, 참조
image.shape
- DICOM은 몇가지 처리방법이 있을 수 있는데, pretrained이 3채널을 가지는 경우 stack을 해서 사용하기도 한다. 혹은 채널별로 윈도우 범위를 다르게 잡을 수 있다.
- 1채널 모델인경우 stack할 필요가 없어 보인다.
- 현재 변환된 PNG의 경우 채널은 총 세개지만, 각각이 가지는 값은 같다.
In [163]:
resized_image = cv2.resize(image, (1024,1024), interpolation=cv2.INTER_LINEAR)
# normalized_image = normalize(resized_image)
# stacked_image = np.stack((normalized_image, normalized_image, normalized_image))
# stacked_image = np.stack((resized_image, resized_image, resized_image))
# stacked_image = np.swapaxes(stacked_image,0,1)
# stacked_image = np.swapaxes(stacked_image,1,2)
추론 (예측)¶
- 추론모드로 RTX2060으로 약 3초정도 걸린다.
In [167]:
boxes, scores, labels = model.predict_on_batch(np.expand_dims(resized_image, axis=0))
Out[167]:
시각화¶
- 0.05이상의 확률을 가지는 패치의 경우만을 나타낸다.
In [ ]:
labels_to_names = {0: 'spot'} # 클래스는 다수가 있을 수 있음
for box, score, label in zip(boxes[0], scores[0], labels[0]):
if score < 0.05: # 그림에 표시할 쓰레시홀드를 정한다.
break
color = label_color(label)
b = box.astype(int)
draw_box(resized_image, b, color=color)
caption = "{} {:.3f}".format(labels_to_names[label], score)
draw_caption(resized_image, b, caption)
plt.figure(figsize=(15, 15))
plt.axis('off')
plt.imshow(resized_image)
plt.show()