Как мне преобразовать относительные ограничивающие рамки после обрезки?

#python #numpy #tensorflow #matplotlib

#python #numpy #тензорный поток #matplotlib

Вопрос:

Мне нужно использовать ограничивающие рамки в этом формате, согласно tf.image.draw_bounding_boxes :

 [y_min, x_min, y_max, x_max]
  

У меня есть это изображение формы (720, 1280, 3) (изображение в натуральную величину здесь):

введите описание изображения здесь

И у меня есть ограничивающие рамки:

 array([[0.134722 , 0.425    , 0.327778 , 0.5      ],
       [0.294444 , 0.3140625, 0.444444 , 0.4124995],
       [0.473611 , 0.294531 , 0.636111 , 0.417969 ],
       [0.5972225, 0.392968 , 0.7986115, 0.497656 ],
       [0.5416665, 0.486719 , 0.6999995, 0.645313 ],
       [0.3986115, 0.425    , 0.5319445, 0.546094 ],
       [0.3499995, 0.5726565, 0.5041665, 0.6710935],
       [0.215278 , 0.507031 , 0.383334 , 0.590625 ]])
  

Это работает с прямоугольным изображением:

 image = plt.imread(myimage) 
x = tf.image.draw_bounding_boxes(image[None, ...], 
                             np.array(bboxes)[None, ...], 
                             [[255., 0., 0.] for i in range(len(bboxes))])
plt.imshow(x[0, ...].numpy().astype(np.uint8))
plt.show()
  

введите описание изображения здесь

Но все это терпит неудачу, когда я обрезаю свое изображение в квадрат:

 image = plt.imread(myimage)[:, 280:-280]
x = tf.image.draw_bounding_boxes(image[None, ...], 
                             np.array(bboxes)[None, ...], 
                             [[255., 0., 0.] for i in range(len(bboxes))])
plt.imshow(x[0, ...].numpy().astype(np.uint8))
plt.show()
  

введите описание изображения здесь

Как я могу получить правильные ограничивающие рамки после обрезки до квадрата? Я ищу квадрат размером 640×640, затем я изменю размер до 320×320.

** Редактировать: ** Это сработало:

  h, w, c = image.shape
    h_pad = 640 - h
    w_pad = 640 - w
    image = np.pad(image, [[h_pad//2, h_pad//2], 
                           [w_pad//2, w_pad//2], [0, 0]], mode='edge')
    train_images_np.append(image) 
    
    annotations = []
    labels_temp = []
    with open(annot_path) as txtfile:
        reader = csv.reader(txtfile, delimiter=',')
        for row in reader:
            annotations.append(list([(h*(2*float(row[0])-1)/640 1)/2, 
                                     (w*(2*float(row[1])-1)/640 1)/2, 
                                     (h*(2*float(row[2])-1)/640 1)/2, 
                                     (w*(2*float(row[3])-1)/640 1)/2
                                    ]))
  

Ответ №1:

Это потому, что вы не учитываете изменение размера граничных рамок.
Сначала вы получаете граничные рамки из исходного изображения, а затем изменяете размеры рамок на основе вашего квадратного изображения.
Таким образом, при выполнении этого все ваши границы будут уменьшаться на ту же величину, что я вижу на выходном изображении.
Решение: не изменяйте размер граничных рамок, используя delta для замены их координат x

 delta = (width_orginal_image - width_new_image)//2
for each_boundary_box in all_boundary_box:
    new_box_x = each_boundary_box[0] - delta
  

вычтите эту дельту из x рядов граничных рамок