如何在 Opencv 中使用 Vec2w Python

How to use Vec2w in Opencv Python

我有这部分代码在 C++ 中工作

Mat mapFrame5(Size(321,262), CV_16UC2);
for (int y = 0; y < mapFrame5.rows; y++) {
    for (int x = 0; x < mapFrame5.cols; x++) {
        mapFrame5.at<Vec2w>(y, x) = Vec2w(y, x);
        cout<<mapFrame5.at<Vec2w>(y,x);
    }
}

我很难找到 Python 中是否有等效的表达式:

mapFrame5.at<Vec2w>(y, x) = Vec2w(y, x);

我按照建议尝试了以下操作:

testArr2 = np.zeros([262,321], np.uint16)

y,yy = 0,0
byteCount = 0
while yy < 262:
    x,xx = 0,0
    while xx < 321:
        testArr2[yy,xx] = [yy,xx]
        xx+=1
        x+=1        
        byteCount+=1
    yy+=1
    y+=1 

但它只给我这个错误:

builtins.TypeError: int() argument must be a string, a bytes-like object or a real number, not 'list'

为了清楚起见,我正在尝试将 y、x 值保存到小端二进制文件中。

示例:

y = 0

0 0 0 1 0 2 0 3 ... 0 320

y = 261

261 0 261 1 261 2 ... 261 320

C++ 文件正好给我 336408 字节

天真的方法是将算法转录为 Python:

def gen_grid_1(rows, cols):
    result = np.zeros((rows, cols, 2), np.uint16)
    for r in range(rows):
        for c in range(cols):
            result[r,c,:] = [r, c]
    return result

3 行 5 列的示例输出:

[[[0 0]
  [0 1]
  [0 2]
  [0 3]
  [0 4]]

 [[1 0]
  [1 1]
  [1 2]
  [1 3]
  [1 4]]

 [[2 0]
  [2 1]
  [2 2]
  [2 3]
  [2 4]]]

但是,这种方法有一个严重的缺点 -- 由于 Python 解释器开销,它会非常慢 -- 对于您的示例 321x262 数组,这几乎需要 1 秒才能完成。


更好的方法是重申算法的目标,并使用 Numpy 提供的优化函数重新实现。

我们要生成的是一个 16 位无符号整数的双通道数组,其中每个元素的第一个通道保存其行索引,第二个通道保存列索引。

这听起来与 numpy.meshgrid 函数的作用非常接近:“Return 来自坐标向量的坐标矩阵。”

唯一的问题是它 returns 2 个单独的数组。我们可以简单地使用 numpy.dstack 将它们与频道按所需顺序组合成一个。

def gen_grid_2(rows, cols):
    cc, rr = np.meshgrid(np.arange(cols, dtype=np.uint16), np.arange(rows, dtype=np.uint16))
    return np.dstack([rr,cc])

此函数的输出与第一个相同,但运行时间约为。 2 毫秒(即比原始方法快约 500 倍)。


带有时序比较的完整脚本:

import numpy as np

ROWS = 262
COLS = 321

def gen_grid_1(rows, cols):
    result = np.zeros((rows, cols, 2), np.uint16)
    for r in range(rows):
        for c in range(cols):
            result[r,c,:] = [r, c]
    return result

def gen_grid_2(rows, cols):
    cc, rr = np.meshgrid(np.arange(cols, dtype=np.uint16), np.arange(rows, dtype=np.uint16))
    return np.dstack([rr,cc])


assert(np.array_equal(gen_grid_1(ROWS, COLS), gen_grid_2(ROWS, COLS)))


import timeit
print(timeit.timeit('r1 = gen_grid_1(ROWS, COLS)'
    , number=10
    , setup="from __main__ import gen_grid_1, ROWS, COLS"))
print(timeit.timeit('r1 = gen_grid_2(ROWS, COLS)'
    , number=10
    , setup="from __main__ import gen_grid_2, ROWS, COLS"))