如何在 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"))
我有这部分代码在 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"))