opencv版本3. * HogDescriptor最多接受1个参数(给定5个) [英] opencv version 3.* HogDescriptor takes at most 1 argument (5 given)
问题描述
我正在尝试使用HogDescriptor,但出现此错误.我在文档中看到,构造函数可以接受一个以上的参数.我正在python 3.6和opencv 3.2中工作
I am trying to use HogDescriptor and I am getting this error. I saw in the document that the constructor can take more then one argument. I am working in python 3.6 and opencv 3.2
这是我的代码:
def _extract_feature(X):
"""Performs feature extraction
:param X: data (rows=images, cols=pixels)
:param feature: which feature to extract
- "hog": HOG features
:returns: X (rows=samples, cols=features)
"""
X = [cv2.cvtColor(x, cv2.COLOR_BGR2GRAY) for x in X]
# operate on smaller image
small_size = (32, 32)
X = [cv2.resize(x, small_size) for x in X]
# histogram of gradients
block_size = (small_size[0] / 2, small_size[1] / 2)
block_stride = (small_size[0] / 4, small_size[1] / 4)
cell_size = block_stride
num_bins = 9
hog = cv2.HOGDescriptor(small_size, block_size, block_stride,
cell_size, num_bins)
X = [hog.compute(x) for x in X]
X = [x.flatten() for x in X]
return X
那我为什么会收到错误消息:
So why am I getting the error:
TypeError: HogDescriptor takes at most 1 argument (5 given)
更新:我安装了python 2.7并对其进行了尝试.
Update: I installed python 2.7 and tried it and it works.
推荐答案
您所观察到的问题是由于多种因素共同导致的:
The issue you're observing is due to combination of several factors:
- PEP-238 –更改除法运算符
- 映射到Python并分派重载的C ++函数(在OpenCV中完成)
- PEP-238 – Changing the Division Operator
- Mapping to Python and dispatching of overloaded C++ functions (as done in OpenCV)
在Python 2.x和Python 3.x之间,运算符/
的含义已更改.
The meaning of operator /
has changed between Python 2.x and Python 3.x.
从PEP-238:
- 经典除法将保留为Python 2.x的默认设置 系列;真正的划分将是Python 3.0中的标准
- Classic division will remain the default in the Python 2.x series; true division will be standard in Python 3.0
例如,在Python 2.x中,您拥有
For example, in Python 2.x you have
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16, 16)
在Python 3.x中,您拥有
And in Python 3.x you have
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16.0, 16.0)
为了获得相同的结果,您的Python 3.x代码将需要使用运算符//
In order to get the same result, your Python 3.x code would need to use operator //
>>> small_size = (32, 32)
>>> block_size = (small_size[0] // 2, small_size[1] // 2)
>>> print(block_size)
(16, 16)
过载的映射和处理
在不详细介绍(这将需要一个单独的问题)的情况下,重载解决方案取决于参数的类型.类型的匹配非常严格,例如您不能将浮点数传递给整数参数.
Mapping and Handling of Overloads
Without going into detail (that would warrant a separate question), the overload resolution depends on the types of arguments. The matching of types is quite strict, e.g. you may not pass a floating point number to an integer argument.
所讨论的构造函数的C ++签名(仅被截断为相关参数)是
The C++ signature of the constructor in question (truncated to only the relevant arguments) is
HOGDescriptor (Size _winSize
, Size _blockSize
, Size _blockStride
, Size _cellSize
, int _nbins, ...)
cv::Size
是一个类,其中包含两个整数.在Python API中,它表示为包含两个整数的元组.
cv::Size
is a class that contains two integers. In the Python API, it is represented as a tuple containing two integers.
因此,要在Python中调用此重载,我们需要提供:
Therefore, to call this overload in Python, we need to provide:
- 4x一个包含两个整数(对于
_winSize
,_blockSize
,_blockStride
和_cellSize
)的元组 - 1x整数(用于
_nbins
)
- 4x a tuple containing two integers (for
_winSize
,_blockSize
,_blockStride
, and_cellSize
) - 1x an integer (for
_nbins
)
我们可以在Python解释器中对此进行测试.
We can test this out in the Python interpreter.
>>> import cv2
>>> cv2.HOGDescriptor((1,1),(1,1),(1,1),(1,1),1)
<HOGDescriptor 0393D0F0>
这符合我们的期望.让我们尝试其他选择.
This matches our expectations. Let's try some other options.
>>> cv2.HOGDescriptor((1,1,1),(1,1),(1,1),(1,1),1)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
>>> cv2.HOGDescriptor((1,),(1,1),(1,1),(1,1),1)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
我们看到元组需要有2个值,不多也不少.
We see the tuples need to have 2 values, no more, no less.
>>> cv2.HOGDescriptor([1,1],(1,1),(1,1),(1,1),1)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
列表不会,它必须是一个元组.
Lists won't do, it has to be a tuple.
>>> cv2.HOGDescriptor((1.0,1.0),(1,1),(1,1),(1,1),1)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
成千上万个浮标也不起作用.
Tuples of floats won't work either.
>>> cv2.HOGDescriptor((1,1),(1,1),(1,1),(1,1),1.0)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
我们也不能用浮点数代替整数.
Nor can we substitute an float for an integer.
考虑到上述情况,就您通过构造函数传递的值而言,两个变体是:
Considering the above, in terms of the values you pass the constructor, the two variants are:
- Python 2.x:
cv2.HOGDescriptor((32,32),(16,16),(8,8),(8,8),9)
- Python 3.x:
cv2.HOGDescriptor((32,32),(16.0,16.0),(8.0,8.0),(8.0,8.0),9)
- Python 2.x:
cv2.HOGDescriptor((32,32),(16,16),(8,8),(8,8),9)
- Python 3.x:
cv2.HOGDescriptor((32,32),(16.0,16.0),(8.0,8.0),(8.0,8.0),9)
我们可以清楚地看到Python 3.x中的参数不满足重载的要求.
We can clearly see that the parameters in Python 3.x don't satisfy the requirements of the overload.
关于为什么我们得到误导性错误消息,这似乎是另一个需要单独解决的问题,而我还没有做所有必要的研究来回答这个问题.
As to why we get the misleading error message, that seems like another topic warranting a separate question, and I haven't done all the research necessary to answer this authoritatively.
这篇关于opencv版本3. * HogDescriptor最多接受1个参数(给定5个)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!