【问题标题】:How to use Vec2w in Opencv Python如何在 Opencv Python 中使用 Vec2w
【发布时间】:2022-01-06 08:44:57
【问题描述】:

我有这部分代码在 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 字节

【问题讨论】:

  • 如果你能用简单的语言解释你想用你的表达方式为非 C++ 读者实现什么,这可能会有所帮助......
  • opencv Mat 在 python 中只是 numpy 数组。你的代码在 python 中可以是mapFrame5[y,x] = [y,x]
  • @QuangHoang 已编辑帖子,我无法让您的解决方案发挥作用
  • 您需要将阵列设为 2 通道 - np.zeros([262,321,2], np.uint16)

标签: python c++ numpy opencv opencv-python


【解决方案1】:

天真的方法是将算法转录为 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 位无符号整数的 2 通道数组,其中每个元素的第一个通道保存其行索引,第二个通道保存列索引。

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

唯一的问题是它返回 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"))

【讨论】:

  • 是的!这正是我需要的,谢谢!我虽然这样可能有一个 numpy 函数。
猜你喜欢
  • 2011-06-29
  • 1970-01-01
  • 2020-10-18
  • 2019-09-10
  • 2018-09-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
相关资源
最近更新 更多