调整图像大小及其边界框

jej*_*ejd 10 math opencv numpy image-processing python-3.x

我有一个带有边界框的图像,我想调整图像的大小.

img = cv2.imread("img.jpg",3)
x_ = img.shape[0]
y_ = img.shape[1]
img = cv2.resize(img,(416,416));
Run Code Online (Sandbox Code Playgroud)

现在我想计算比例因子:

x_scale = ( 416 / x_)
y_scale = ( 416 / y_ )
Run Code Online (Sandbox Code Playgroud)

并绘制图像,这是原始边界框的代码:

( 128, 25, 447, 375 ) = ( xmin,ymin,xmax,ymax)
x = int(np.round(128*x_scale))
y = int(np.round(25*y_scale))
xmax= int(np.round  (447*(x_scale)))
ymax= int(np.round(375*y_scale))
Run Code Online (Sandbox Code Playgroud)

但是使用这个我得到:

在此输入图像描述

原来是:

在此输入图像描述

我没有在这个逻辑中看到任何旗帜,这有什么不对?

整码:

imageToPredict = cv2.imread("img.jpg",3)
print(imageToPredict.shape)

x_ = imageToPredict.shape[0]
y_ = imageToPredict.shape[1]

x_scale = 416/x_
y_scale = 416/y_
print(x_scale,y_scale)
img = cv2.resize(imageToPredict,(416,416));
img = np.array(img);


x = int(np.round(128*x_scale))
y = int(np.round(25*y_scale))
xmax= int(np.round  (447*(x_scale)))
ymax= int(np.round(375*y_scale))
Box.drawBox([[1,0, x,y,xmax,ymax]],img)
Run Code Online (Sandbox Code Playgroud)

和drawbox

def drawBox(boxes, image):
    for i in range (0, len(boxes)):
        cv2.rectangle(image,(boxes[i][2],boxes[i][3]),(boxes[i][4],boxes[i][5]),(0,0,120),3)
    cv2.imshow("img",image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

边界框的图像和数据分别加载.我正在图像中绘制边界框.图像不包含框本身.

Ser*_*gGr 7

我相信有两个问题:

  1. 您应该交换x_y_因为shape[0]实际上是y维度,shape[1]是x维度
  2. 您应该在原始和缩放的图像上使用相同的坐标。在原始图像上,矩形是(160, 35)- (555, 470)而不是(128,25)- (447,375)您在代码中使用的矩形。

如果我使用以下代码:

import cv2
import numpy as np


def 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()
Run Code Online (Sandbox Code Playgroud)

并将您的“原始”图片用作“ 49466033 \ img.png”,

原始图片

我得到以下图像

处理的图像

正如您所看到的,我的细蓝线恰好位于您的原始红线之内,并且无论targetSize您选择什么,它都会停留在该位置(因此缩放实际上可以正常工作)。


小智 5

另一种方法是使用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())
Run Code Online (Sandbox Code Playgroud)

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

点安装奇特拉

  • CHITRA 看起来很漂亮。看来此功能的底层实现位于“imgaug”库中,如何使用“imgaug”执行此操作的示例如下:https://imgaug.readthedocs.io/en/latest/source/examples_bounding_boxes.html?突出显示=bbs#将bbs投影到重新缩放的图像上 (2认同)