Python OpenCV2(cv2)包装器获取图像大小?

141

如何在Python OpenCV(numpy)中使用cv2包装器获取图像的大小。除了使用numpy.shape()之外,还有没有其他正确的方法来实现此目标。我如何以这种格式获得尺寸:(宽度, 高度)列表?


1
numpy.shape 不可调用。它只是一个普通的 tuple。不幸的是,它可以是 3 或 2 个元素长。 - Tomasz Gandor
3个回答

300

cv2 使用 numpy 来操作图像,因此获取图像尺寸的正确和最佳方式是使用 numpy.shape。假设您正在使用 BGR 图像,则以下是一个示例:

>>> import numpy as np
>>> import cv2
>>> img = cv2.imread('foo.jpg')
>>> height, width, channels = img.shape
>>> print height, width, channels
  600 800 3

如果你正在使用二进制图像,img将具有两个维度,因此你必须更改代码为:height, width = img.shape


37
别这样嘛,不要假设图像是BGR或单色,而是写成更通用的形式——h,w = img.shape[:2],特别是当OP对深度不感兴趣的时候。(我也不感兴趣)。请查看我的答案获取更多详细信息。 - Tomasz Gandor
2
我发现这个链接很有用:http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#accessing-image-properties - djwbrown
1
如果您只对高度和宽度感兴趣,那么一个更符合Python风格的替代方案是:h, w, _ = img.shape - Zenahr
h, w, *_ = img.shape - fferri

28

很抱歉,获取这个尺寸没有更好的方法,但这并不太痛苦。

当然,你的代码应该对二进制/单通道图像和多通道图像都安全,但图像的主要维度总是排在numpy数组的shape的最前面。如果你想要可读性,或者不想麻烦地输入这些内容,你可以将其包装成一个函数,并给它一个你喜欢的名字,例如cv_size

import numpy as np
import cv2

# ...

def cv_size(img):
    return tuple(img.shape[1::-1])

如果您使用终端或ipython,您也可以使用lambda表达式:

>>> cv_size = lambda img: tuple(img.shape[1::-1])
>>> cv_size(img)
(640, 480)

使用def编写函数在交互式工作时并不好玩。

编辑

最初我认为使用[:2]是可以的,但是numpy的形状是(height, width[, depth]),我们需要的是(width, height),就像cv2.resize所需的那样,所以我们必须使用[1::-1]。甚至比[:2]更难记。而且谁还记得反向切片?

Python 3元组解包

当我们都转移到Python 3,并且有了https://peps.python.org/pep-3132/ - 我们也可以通过使用元组解包来获取hw

h, w, *_ = img.shape

这一次,我们不用担心单通道图像 :)


1
也许并不是非常有帮助,但你也可以将其切片为 img.shape[:2][::-1] - billyjmc
22
你没有必要喜欢在索引中使用冒号。return (image.shape[1], image.shape[0])的表达简洁易读。 - mcduffee
使用通配符进行 as is 解包: h, w, _ = image.shape - Zenahr
1
@Zenahr -- 这种解包方式对于单通道图像会失败。 - Tomasz Gandor

0
import cv2
import numpy as np

def main():
    # init cv
    cap = cv2.VideoCapture(0)

    while True:
        success, img = cap.read()
# WAY 1
        img = cv2.flip(img, 1)

        print(img.shape)
# WAY 2
        print(
            f"width: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}, height: {cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}, fps: {cap.get(cv2.CAP_PROP_FPS)}")
        cv2.imshow(winname="universal control", mat=img)
        cv2.waitKey(1)


if __name__ == '__main__':
    main()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接