SSD의 정DBox를 보여 줍니다.

SSD 레이블의 손실을 평가하기 위한 적극적인 기본 상자를 보여 주고 싶습니다.SSD를 사용하는 파이썬 설치amdegroot/ssd.pytorch를 설치합니다.
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 사이즈로 다운로드한 것이다.

좋은 웹페이지 즐겨찾기