Resizing image and its bounding box Resizing image and its bounding box python-3.x python-3.x

Resizing image and its bounding box


I believe there are two issues:

  1. You should swap x_ and y_ because shape[0] is actually y-dimension and shape[1] is the x-dimension
  2. You should use the same coordinates on the original and scaled image. On your original image the rectangle is (160, 35) - (555, 470) rather than (128,25) - (447,375) that you use in the code.

If I use the following code:

import cv2import numpy as npdef drawBox(boxes, image):    for i in range(0, len(boxes)):        # changed color and width to make it visible        cv2.rectangle(image, (boxes[i][2], boxes[i][3]), (boxes[i][4], boxes[i][5]), (255, 0, 0), 1)    cv2.imshow("img", image)    cv2.waitKey(0)    cv2.destroyAllWindows()def cvTest():    # imageToPredict = cv2.imread("img.jpg", 3)    imageToPredict = cv2.imread("49466033\\img.png ", 3)    print(imageToPredict.shape)    # Note: flipped comparing to your original code!    # x_ = imageToPredict.shape[0]    # y_ = imageToPredict.shape[1]    y_ = imageToPredict.shape[0]    x_ = imageToPredict.shape[1]    targetSize = 416    x_scale = targetSize / x_    y_scale = targetSize / y_    print(x_scale, y_scale)    img = cv2.resize(imageToPredict, (targetSize, targetSize));    print(img.shape)    img = np.array(img);    # original frame as named values    (origLeft, origTop, origRight, origBottom) = (160, 35, 555, 470)    x = int(np.round(origLeft * x_scale))    y = int(np.round(origTop * y_scale))    xmax = int(np.round(origRight * x_scale))    ymax = int(np.round(origBottom * y_scale))    # Box.drawBox([[1, 0, x, y, xmax, ymax]], img)    drawBox([[1, 0, x, y, xmax, ymax]], img)cvTest()

and use your "original" image as "49466033\img.png",

Original image

I get the following image

Processed image

And as you can see my thinner blue line lies exactly inside your original red line and it stays there whatever targetSize you chose (so the scaling actually works correctly).


Another way of doing this is to use CHITRA

image = Chitra(img_path, box, label)# Chitra can rescale your bounding box automatically based on the new image size.image.resize_image_with_bbox((224, 224))print('rescaled bbox:', image.bounding_boxes)plt.imshow(image.draw_boxes())

https://chitra.readthedocs.io/en/latest/

pip install chitra


you can use the resize_dataset_pascalvoc

it's easy to use python3 main.py -p <IMAGES_&_XML_PATH> --output <IMAGES_&_XML> --new_x <NEW_X_SIZE> --new_y <NEW_X_SIZE> --save_box_images <FLAG>"

It resize all your dataset and rewrite new annotations files to resized images