SSD의 정DBox를 보여 줍니다.
1개 이상의 이미지와 이미지에 둘러싸인 상자가 주어지면 SSD 모델과 직접적인 관계가 없는 긍정적 기본 상자와 부정적 기본 상자를 결정할 수 있다.우선 그림을 불러오기 위해 다음 데이터 마운트를 생성합니다.
# 画像を300x300にリサイズするのに使用します
image_size = 300
# 今回は1画像のみ扱うのでバッチサイズは1にします
batch_size = 1
# transformで本来学習中はデータオーグメントさせますが、
# ここでは可視化のため300x300リサイズとRGBの平均値を引く操作のみ行う
# BaseTransformを使用します。
dataset = VOCDetection(root = '/path/to/root',
transform=BaseTransform(image_size, MEANS))
data_loader = data.DataLoader(dataset,
batch_size = batch_size,
num_workers=0,
shuffle=False,
collate_fn = detection_collate)
# ssd.pytorchの関連するコードがcuda前提のため、これを設定しないとエラーになります
torch.set_default_tensor_type('torch.cuda.FloatTensor')
데이터 캐리어에서 이미지images
와 포위함, 라벨 정보targets
를 불러오고 기본 박스와 모든 포위함 사이의 jaccard 계수의 최대치를 계산하여 jaccard 계수가 가장 큰 포위함의 위치 정보loc_t
를탭 정보를 넣습니다 conf_t
.단,jaccard 계수의 최대 값이 한도값보다 작을 때 (이번에는 0.5보다 작을 때) 배경으로 다시 표시합니다.이 기본 상자는 소극적인 기본 상자라고 하고, 다른 기본 상자는 적극적인 기본 상자라고 한다.images, targets = next(iter(data_loader))
images = images.cuda()
targets = [ann.cuda() for ann in targets]
priors = PriorBox(voc).forward()
num_priors = priors.size(0)
loc_t = torch.Tensor(batch_size, num_priors, priors.size(1))
conf_t = torch.LongTensor(batch_size, num_priors)
# loc_t: DBoxからBBoxまでの差分とconf_t: jaccard係数 0.5を閾値としたときのラベル付けを計算
# matchはloc_t、conf_tに値をセットします
match(threshold = 0.5,
truths = targets[0][:, :-1].data,
priors = priors.data,
variances = [0.1, 0.2],
labels = targets[0][:, -1].data,
loc_t = loc_t,
conf_t = conf_t,
idx = 0)
jaccard계수의 계산은 경사가 없는 직사각형이기 때문에 간단하게 다음과 같이 계산할 수 있다.def calc_jaccard(a, b):
w = min(a[2], b[2]) - max(a[0], b[0])
h = min(a[3], b[3]) - max(a[1], b[1])
# interはa, bが互いに素であれば、w, hのどちらか、またはどちらもが
# ネガティブになるのでmaxでこのときinterが0になるように調整する
inter = max(w, 0) * max(h, 0)
area_a = (a[2] - a[0]) * (a[3] - a[1])
area_b = (b[2] - b[0]) * (b[3] - b[1])
return inter / (area_a + area_b - inter)
양의 기본 상자에 해당하는 포위함을 표시합니다.image = (images[0].to('cpu').detach().numpy().transpose(1, 2, 0) + (MEANS[2], MEANS[1], MEANS[0])).astype(np.uint8).copy()
image = cv2.resize(image, (image_size, image_size))
indices = [i for i, v in enumerate(list((conf_t > 1).to('cpu').detach().numpy().copy()[0])) if v]
colors = get_colors()
plt.figure(figsize=(16, 12))
for i, idx in enumerate(indices):
img = image.copy()
cx_d, cy_d, w_d, h_d = priors[idx].to('cpu').detach().numpy().copy()
xmin_d = int((cx_d - w_d / 2) * image_size)
ymin_d = int((cy_d - h_d / 2) * image_size)
xmax_d = int((cx_d + w_d / 2) * image_size)
ymax_d = int((cy_d + h_d / 2) * image_size)
pt1_d = (xmin_d, ymin_d)
pt2_d = (xmax_d, ymax_d)
cv2.rectangle(img, pt1=pt1_d, pt2=pt2_d, color=colors[5], thickness=2)
for box in targets[0]:
pt1 = (int(box[0] * image_size), int(box[1] * image_size) )
pt2 = (int(box[2] * image_size), int(box[3] * image_size))
jaccard = calc_jaccard((pt1_d[0], pt1_d[1], pt2_d[0], pt2_d[1]), (pt1[0], pt1[1], pt2[0], pt2[1]))
cv2.putText(img, f"{jaccard: .2f}", (pt1[0] + 5 , pt1[1] - 5), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)
cv2.rectangle(img, pt1=pt1, pt2=pt2, color=colors[10], thickness=2)
plt.subplot(3 , 4, i + 1)
plt.axis('off')
plt.imshow(img)
plt.show()
그림의 수치는jaccard 계수입니다.디스플레이에서도 알 수 있듯이 8732개의 기본 상자 중 12개의 적극적인 기본 상자가 있는데 대부분이 소극적인 기본 상자로 분류된다.마지막으로 적극적인 기본 상자를 모두 겹쳐서 표시합니다.
img_path = os.path.join(os.environ['HOME'], "data", "dogs_out", "dog_ssd_test-PascalVOC-export", "JPEGImages", "dog-3407906_640.jpg")
img = cv2.imread(img_path)
img_h_, img_w_, _ = img.shape
img = img[:, :, (2, 1, 0)].copy()
for i, idx in enumerate(indices):
cx, cy, w, h = priors[idx].to('cpu').detach().numpy().copy()
xmin = int((cx - w / 2) * img_w_)
ymin = int((cy - h / 2) * img_h_)
xmax = int((cx + w / 2) * img_w_)
ymax = int((cy + h / 2) * img_h_)
pt1 = (xmin, ymin)
pt2 = (xmax, ymax)
cv2.rectangle(img, pt1=pt1, pt2=pt2, color=colors[i % 10], thickness=2)
plt.axis('off')
plt.imshow(img)
plt.show()
여기에 사용된 원본 이미지는 여기. (Pixabay License: 상업용 무료 귀속 표시 필요 없음) 640x426 사이즈로 다운로드한 것이다.
Reference
이 문제에 관하여(SSD의 정DBox를 보여 줍니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/nnabeyang/articles/e0c5ebf19b3a1f0a7427텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)