DKD*_*DDK 7 python opencv numpy python-3.x
I'm currently working on visualizing some images and found this weired behaviour of opencv's cv2.rectangle:
when input image is an np.ndarray, say arr, cv2.rectangle() returns an np.ndarray, and arr is drawn with a rectangle.
when input image is some variant of arr, like arr[:, :, [2, 0, 1]], cv2.rectangle() returns a cv2.UMat, and no rectangle is drawn.
My current environment is :
Here are the codes:
import numpy as np
import cv2
import copy
img = np.random.randint(0, 255, (100, 120, 3)).astype("uint8")
Run Code Online (Sandbox Code Playgroud)
a = copy.deepcopy(img)
ret = cv2.rectangle(a, (0, 0), (10, 10), color=(255, 255, 255), thickness=2)
Run Code Online (Sandbox Code Playgroud)
You'll find:
Try another way:
b = copy.deepcopy(img)
c = b[:, :, [2, 1, 0]]
ret = cv2.rectangle(c, (0, 0), (10, 10), color=(255, 255, 255), thickness=2)
Run Code Online (Sandbox Code Playgroud)
You'll find:
I'm really curious that is there anything wrong with my code? Or there is something hidden behind it?
我会尽力回答这个问题,因为我经常偶然发现这个问题,并且在评论中我看到了很多正确的东西!
OpenCV 只能处理连续数组,这意味着它们必须在内存中以某种方式布局。切片时np.array,numpy只需更改读取顺序即可提高速度(而不是耗时的复制)并使其不连续(在此处找到)。
@Das Masek 和 @Eric 的说法都是正确的。使用索引数组对 an 进行切片总是np.array会创建一个副本,如此处所述。然而,不幸的是复制数组但不会将其更改回连续数组(对我来说这似乎是不好的行为)。numpy
解决方案是以下之一:
copy()这np.array; 通过显式复制,numpy将布局更改回连续的,这与索引数组切片不同。您可以使用等等检查flags您的阵列。a.flags如果您想要自动化某些操作,这显然是最昂贵的,因为您实际上每次都在复制。np.ascontiguousarray(). 仅当数组已经不连续时,此函数才会更改数组的布局,但事实并非如此copy。另一方面:根据文档,所有 OpenCV 绘图函数实际上都有一个None返回值,因为它们是就地函数。因此我建议这样使用它们。
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |