如何将 numpy 数组视图转换为 opencv 矩阵?
我正在使用 opencv v2.2 在 ndarray 上进行一些模板匹配,并且在使用其包装方法 cv.fromarray()
时遇到了内存泄漏的很大问题。我没有堵塞内存泄漏,而是避免使用 fromarray()
函数并直接使用 cv.SetData
,如下所示:
assert foo_numpy.dtype == 'uint8'
assert foo_numpy.ndim == 3
h, w = foo_numpy.shape[:2]
foo_cv = cv.CreateMat(h, w, cv.CV_8UC3)
cv.SetData(foo_cv, foo_numpy.data, foo_numpy.strides[0])
这似乎解决了内存泄漏,并且 foo_cv< /code> 超出范围时似乎已正确释放。但是,现在我遇到的问题是,如果
所以我应该能够以适当的步长以某种方式跨过它?我不知道如何以一种好的方式做到这一点,因为这个的基础也可以是另一个更大的数组的视图。foo_numpy
只是更大数组上的切片/视图,则不允许 foo_numpy.data
(无法获取单段缓冲区对于不连续的数组)。目前,我正在通过设置 foo_numpy.copy()
if foo_numpy.base != None
来解决这个问题,这允许在新副本上获取缓冲区。但我觉得这是不必要的,切片有 __array_struct__ 和 __array_interface__
I'm using opencv v2.2 to do some template matching on ndarrays, and I had great trouble with memory leaks when using their wrapped method cv.fromarray()
. Rather than plug the memory leaks I avoided the fromarray()
function and used cv.SetData
directly, like this:
assert foo_numpy.dtype == 'uint8'
assert foo_numpy.ndim == 3
h, w = foo_numpy.shape[:2]
foo_cv = cv.CreateMat(h, w, cv.CV_8UC3)
cv.SetData(foo_cv, foo_numpy.data, foo_numpy.strides[0])
This seems to solve the memory leaks and foo_cv
seems to be deallocated properly when it goes out of scope. However, now I have the issue where if foo_numpy
is just a slice/view on a bigger array, I'm not permitted foo_numpy.data
(cannot get single-segment buffer for discontiguous array). At the moment I'm working around this by making foo_numpy.copy()
if foo_numpy.base != None
, which permits getting the buffer on the new copy. But I have the feeling this is unnecessary, the slice has the __array_struct__
and __array_interface__
so I should be able to just stride it with the appropriate stepsizes somehow? I'm not sure how to do it in a nice way, because the base of this one can also be a view on another larger array ad infinitum.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您想要做的问题是您感兴趣的数组数据(即
foo_np_view
)实际上只存储在一个地方,即foo_np.data
>,并且 OpenCVSetData
方法不提供任何指定步幅设置的方法,从而允许您跳过不属于foo_np_view
的字节。但是,您可以使用 Numpy 的 tostring() 方法解决此问题,该方法将数组(或其中的视图)转换为字节字符串:
重现原始问题:
使用 tostring() 方法(有关步幅设置的说明,请参见下文):
值
w * d * foo_np_view.dtype.itemsize
为我们提供了与foo_np_view.copy()
,这是必要的,因为视图及其副本的字符串表示形式是相同的:I think the problem with what you were trying to do is that the array data you're interested in (ie.
foo_np_view
) is actually only stored in one place i.e.foo_np.data
, and the OpenCVSetData
method doesn't provide any way to specify stride settings that would allow you to skip the bytes that are not part offoo_np_view
.You can, however, get around this problem using Numpy’s
tostring()
method, which turns an array (or views therein) into a byte string:Recreating the original problem:
Using the
tostring()
method (see below for explanation of the stride setting):The value
w * d * foo_np_view.dtype.itemsize
gives us a stride value identical to that offoo_np_view.copy()
, which is necessary as the string representations of the view and its copy are identical: