为什么 cv2.resize 调换要求的尺寸?

Why is cv2.resize transposing the requested dimensions?

            s1 = image.shape  # Image is an opencv2 image (ndarray)
            w,h,d = s1
            image_ = cv2.resize(image, (w*2, h*2), interpolation = cv2.INTER_CUBIC)
            s2 = image_.shape

在上面,我要求将输出调整为 (960,1280),但我得到 (1280, 960)。

这是怎么回事?

  image_ = cv2.resize(image, None, fx=2, fy=2, interpolation = cv2.INTER_CUBIC)

... 按预期工作。 (指出这一点没有分数)。

可运行示例:

import cv2

def run():
    cap = cv2.VideoCapture(0)

    while cap.isOpened():
        success, image = cap.read()  # (480, 640, 3)
        if not success:
            print("Ignoring empty camera frame.")
            continue

        s1 = image.shape
        w, h, d = s1
        s2 = (w * 2, h * 2)
        image_ = cv2.resize(image, s2, interpolation=cv2.INTER_CUBIC)
        s3 = image_.shape
        cv2.imshow('Camera',
                   image_
                   )

        key = cv2.waitKey(5)
        if key & 0xFF == 27:
            break
    cap.release()


if __name__ == '__main__':
    run()

基于 OpenCV 文档:

img.shape returns (Height, Width, Number of Channels) where

  1. Height represents the number of pixel rows in the image or the number of pixels in > each column of the image array
  2. Width represents the number of pixel columns in the image or the number of pixels in each row of the image array.
  3. Number of Channels represents the number of components used to represent each pixel.

所以在 opencv 中调整大小应该像这样发生:

import cv2
 
cap = cv2.VideoCapture(0)
_, img = cap.read()
cap.release()
 
print('Original Dimensions : ',img.shape)
 
scale_percent = 60 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
  
# resize image
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)

而你的问题是关于为什么 fx=2, fy=2 会按预期工作,基于 this link,如果没有给出所需的大小,它会根据 fx 和 [=14 计算新的维度=] 来计算所需的 dsize:

  • FX:沿水平轴的比例因子。为0时,计算为(double)dsize.width/image.cols
  • FY:沿垂直轴的比例因子。为0时,计算为(double)dsize.height/image.rows

总结一下,我想那是因为在 OpenCV C++ 版本中,他们考虑了水平方向(列)的 X 和垂直方向(行)的 Y 并且因为CV2 只是 OpenCV-C++ 的包装,考虑到我们在 Numpy 数组中的第一个维度和第二个维度,发生了这种不匹配。

更新 HansHirse 评论:

OpenCV 是一个 C++ 库,带有专用的 cv::Mat class 表示图像。并且,例如,对于某些 cv::Mat 图像,image.size return 是一个 cv::Size 对象,它具有宽度和高度的顺序,这样维度参数 (width, height)在几个 OpenCV 函数中与此一致。 OpenCV 的 Python API 使用 NumPy 数组,默​​认使用行优先顺序,这样对于某些 NumPy 数组图像, image.shape 将 return 高度和宽度的顺序。这不是故意的设计选择。