Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy阵列的矢量化操作_Python_Opencv_Numpy_Vectorization - Fatal编程技术网

Python numpy阵列的矢量化操作

Python numpy阵列的矢量化操作,python,opencv,numpy,vectorization,Python,Opencv,Numpy,Vectorization,我有一个包含许多三维numpy数组的numpy数组,其中每个子元素都是灰度图像。我想使用numpy对数组中的每个图像应用仿射变换 下面是一个再现问题的最小示例: import cv2 import numpy as np from functools import partial # create four blank images data = np.zeros((4, 1, 96, 96), dtype=np.uint8) M = np.array([[1, 0, 0], [0, 1,

我有一个包含许多三维numpy数组的numpy数组,其中每个子元素都是灰度图像。我想使用numpy对数组中的每个图像应用仿射变换

下面是一个再现问题的最小示例:

import cv2
import numpy as np
from functools import partial

# create four blank images
data = np.zeros((4, 1, 96, 96), dtype=np.uint8)

M = np.array([[1, 0, 0], [0, 1, 0]], dtype=np.float32) # dummy affine transformation matrix
size = (96, 96) # output image size
现在我想将数据中的每个图像传递给。在对其进行矢量化之前,我首先创建一个绑定M和dsize的分部函数:

warpAffine = lambda M, size, img : cv2.warpAffine(img, M, size) # re-order function parameters
partialWarpAffine = partial(warpAffine, M, size)

vectorizedWarpAffine = np.vectorize(partialWarpAffine)
print data[:, 0].shape # prints (4, 96, 96)
vectorizedWarpAffine(data[:, 0])
但这会产生:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 1573, in __call__
    return self._vectorize_call(func=func, args=vargs)
  File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 1633, in _vectorize_call
    ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
  File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 1597, in _get_ufunc_and_otypes
    outputs = func(*inputs)
  File "<stdin>", line 1, in <lambda>
TypeError: src is not a numpy array, neither a scalar

我做错了什么?为什么我不能在numpy数组上对操作进行矢量化?

问题是,仅仅使用partial并不能为了矢量化而消除其他参数的存在。分部对象下面的函数将是vectoriazedwarpaffine.pyfunc,它将跟踪调用vectoriazedwarpaffine.pyfunc.func时希望它使用的任何预定义参数,该函数仍然是一个多参数函数

导入inspect后,您可以这样看到:

要解决此问题,可以使用排除选项np.vectorize,该选项说明在包装矢量化行为时要忽略哪些参数positional或关键字:

vectorizedWarpAffine = np.vectorize(partialWarpAffine, 
                                    excluded=set((0, 1)))
当我进行此更改时,代码现在似乎实际执行了矢量化函数,但它在imagewarp.cpp代码中遇到了一个实际错误,可能是由于此测试数据的一些错误数据假设:

In [21]: vectorizedWarpAffine(data[:, 0])
OpenCV Error: Assertion failed (cn <= 4 && ssize.area() > 0) in remapBilinear, file -------src-dir-------/opencv-2.4.6.1/modules/imgproc/src/imgwarp.cpp, line 2296
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-21-3fb586393b75> in <module>()
----> 1 vectorizedWarpAffine(data[:, 0])

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in __call__(self, *args, **kwargs)
   1570             vargs.extend([kwargs[_n] for _n in names])
   1571 
-> 1572         return self._vectorize_call(func=func, args=vargs)
   1573 
   1574     def _get_ufunc_and_otypes(self, func, args):

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in _vectorize_call(self, func, args)
   1628         """Vectorized call to `func` over positional `args`."""
   1629         if not args:
-> 1630             _res = func()
   1631         else:
   1632             ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in func(*vargs)
   1565                     the_args[_i] = vargs[_n]
   1566                 kwargs.update(zip(names, vargs[len(inds):]))
-> 1567                 return self.pyfunc(*the_args, **kwargs)
   1568 
   1569             vargs = [args[_i] for _i in inds]

/home/ely/programming/np_vect.py in <lambda>(M, size, img)
     10 size = (96, 96) # output image size
     11 
---> 12 warpAffine = lambda M, size, img : cv2.warpAffine(img, M, size) # re-order function parameters
     13 partialWarpAffine = partial(warpAffine, M, size)
     14 

error: -------src-dir-------/opencv-2.4.6.1/modules/imgproc/src/imgwarp.cpp:2296: error: (-215) cn <= 4 && ssize.area() > 0 in function remapBilinear
它的工作原理是:

In [29]: vectorizedWarpAffine(M, size, data[:, 0])
Out[29]: 
array([[[ array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ..., 
       ...

我认为这更好,因为现在当你调用vectoriazedwarpaffine时,你仍然显式地利用了其他位置参数,而不是误导层,它们被部分,但是第三个参数仍然是矢量化的。

问题是,仅仅使用部分参数并不会为了矢量化而使其他参数的存在消失。分部对象下面的函数将是vectoriazedwarpaffine.pyfunc,它将跟踪调用vectoriazedwarpaffine.pyfunc.func时希望它使用的任何预定义参数,该函数仍然是一个多参数函数

导入inspect后,您可以这样看到:

要解决此问题,可以使用排除选项np.vectorize,该选项说明在包装矢量化行为时要忽略哪些参数positional或关键字:

vectorizedWarpAffine = np.vectorize(partialWarpAffine, 
                                    excluded=set((0, 1)))
当我进行此更改时,代码现在似乎实际执行了矢量化函数,但它在imagewarp.cpp代码中遇到了一个实际错误,可能是由于此测试数据的一些错误数据假设:

In [21]: vectorizedWarpAffine(data[:, 0])
OpenCV Error: Assertion failed (cn <= 4 && ssize.area() > 0) in remapBilinear, file -------src-dir-------/opencv-2.4.6.1/modules/imgproc/src/imgwarp.cpp, line 2296
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-21-3fb586393b75> in <module>()
----> 1 vectorizedWarpAffine(data[:, 0])

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in __call__(self, *args, **kwargs)
   1570             vargs.extend([kwargs[_n] for _n in names])
   1571 
-> 1572         return self._vectorize_call(func=func, args=vargs)
   1573 
   1574     def _get_ufunc_and_otypes(self, func, args):

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in _vectorize_call(self, func, args)
   1628         """Vectorized call to `func` over positional `args`."""
   1629         if not args:
-> 1630             _res = func()
   1631         else:
   1632             ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)

/home/ely/anaconda/lib/python2.7/site-packages/numpy/lib/function_base.pyc in func(*vargs)
   1565                     the_args[_i] = vargs[_n]
   1566                 kwargs.update(zip(names, vargs[len(inds):]))
-> 1567                 return self.pyfunc(*the_args, **kwargs)
   1568 
   1569             vargs = [args[_i] for _i in inds]

/home/ely/programming/np_vect.py in <lambda>(M, size, img)
     10 size = (96, 96) # output image size
     11 
---> 12 warpAffine = lambda M, size, img : cv2.warpAffine(img, M, size) # re-order function parameters
     13 partialWarpAffine = partial(warpAffine, M, size)
     14 

error: -------src-dir-------/opencv-2.4.6.1/modules/imgproc/src/imgwarp.cpp:2296: error: (-215) cn <= 4 && ssize.area() > 0 in function remapBilinear
它的工作原理是:

In [29]: vectorizedWarpAffine(M, size, data[:, 0])
Out[29]: 
array([[[ array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ..., 
       ...

我认为这更好,因为现在当你调用vectoriazedwarpaffine时,你仍然显式地使用了其他位置参数,而不是误导层,在那里它们被预先绑定为partial,而第三个参数仍然是向量处理的。

谢谢!4,10,10只是我自己的愚蠢,我现在已经解决了。在应用关于excluded=set0,1的更改后,它对我有效。奇怪的是,我还看到一个OpenCV错误,尽管partialWarpAffine现在在传递数据数组的各个元素时可以正常工作。我使用vectorize的原因是因为代码会更干净,我知道它不会带来性能好处。但是,现在我想知道使用标准循环是否更容易。除非你能提出一个替代方案来对许多图像应用一个转换?一个标准的循环可能很好,它几乎肯定会更可读。此外,我将在一秒钟内在底部添加一些编辑,以展示如何使用np.vectorize直接执行此操作,而您根本不需要部分。感谢您提供的有用解释!我同意,在这种情况下,最好避免使用部分。我仍在试图找出OpenCV出现错误的原因,但我开始认为标准循环可能是解决这个问题的方法。谢谢!4,10,10只是我自己的愚蠢,我现在已经解决了。在应用关于excluded=set0,1的更改后,它对我有效。奇怪的是,我还看到一个OpenCV错误,尽管partialWarpAffine现在在传递数据数组的各个元素时可以正常工作。我使用vectorize的原因是因为代码会更干净,我知道它不会带来性能好处。但是,现在我想知道使用标准循环是否更容易。除非你能提出一个替代方案来对许多图像应用一个转换?一个标准的循环可能很好,它几乎肯定会更可读。此外,我将在一秒钟内在底部添加一些编辑,以展示如何使用np.vectorize直接执行此操作,而您根本不需要部分。感谢您提供的有用解释!我同意,在这种情况下,最好避免使用部分。我仍在试图找出OpenCV出现错误的原因,但我开始认为标准循环可能是解决这个问题的方法。如果不需要,只需将循环隐藏在函数中。矢量化有助于广播。如果你不需要,只要 在函数中隐藏循环。