[英]How to convert a numpy array view to opencv matrix?
我正在使用opencv v2.2在ndarrays上进行一些模板匹配,并且在使用其包装方法cv.fromarray()
时遇到内存泄漏的麻烦。 与其避免内存泄漏,我避免了fromarray()
函数, cv.SetData
直接使用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
似乎已被正确释放。 但是,现在我遇到的问题是,如果foo_numpy
只是更大数组上的一个切片/视图,则不允许我foo_numpy.data
(无法为不连续数组获取单段缓冲区)。 目前,我正在通过foo_numpy.base != None
来制作foo_numpy.copy()
解决此问题,这允许在新副本上获取缓冲区。 但是我感觉这是不必要的,切片具有__array_struct__
和__array_interface__
所以我应该能够以适当的步长以某种方式跨越它? 我不确定如何以一种很好的方式进行操作,因为此操作的基础也可以是另一个无限大数组广告的视图。
我认为您尝试执行的操作的问题在于,您感兴趣的数组数据(即foo_np_view
)实际上仅存储在一个位置,即foo_np.data
,而OpenCV SetData
方法没有提供任何方法来指定跨步设置,以允许您跳过不属于foo_np_view
的字节。
但是,您可以使用Numpy的tostring()
方法解决此问题,该方法将数组(或其中的视图)转换为字节字符串:
>>> import numpy as np
>>> import cv
>>> foo_np = np.array( 255 * np.random.rand( 200 , 300 , 3 ), dtype = 'uint8' )
>>> foo_np_view = foo_np [ 50:150:2 , 10:290:5 , : ]
>>> h,w,d = foo_np_view.shape
>>> foo_cv = cv.CreateMat( h , w , cv.CV_8UC3 )
重现原始问题:
>>> cv.SetData( foo_cv , foo_np_view.data, foo_np_view.strides[0] )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: cannot get single-segment buffer for discontiguous array
使用tostring()
方法(有关步幅设置的说明,请参见下文):
>>> cv.SetData( foo_cv , foo_np_view.tostring() , w * d * foo_np_view.dtype.itemsize )
>>> np.array_equal( np.asarray( foo_cv ) , foo_np_view )
True
w * d * foo_np_view.dtype.itemsize
值为我们提供了与foo_np_view.copy()
相同的步幅值,这是必需的,因为视图及其副本的字符串表示形式相同:
>>> foo_np_view.copy().tostring() == foo_np_view.tostring()
True
>>> foo_np_view.copy().strides[0] == w * d * foo_np_view.dtype.itemsize
True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.