Python opencv版本3.*HogDescriptor最多接受1个参数(给定5个)
我正在尝试使用HogDescriptor,我得到了这个错误。我在文档中看到构造函数可以接受多个参数。我正在使用python 3.6和opencv 3.2 这是我的代码:Python opencv版本3.*HogDescriptor最多接受1个参数(给定5个),python,opencv,Python,Opencv,我正在尝试使用HogDescriptor,我得到了这个错误。我在文档中看到构造函数可以接受多个参数。我正在使用python 3.6和opencv 3.2 这是我的代码: def _extract_feature(X): """Performs feature extraction :param X: data (rows=images, cols=pixels) :param feature: which feature to extract
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
那么,为什么我会出现错误:
TypeError: HogDescriptor takes at most 1 argument (5 given)
更新:我安装了Python2.7并试用了它,它运行正常。HOGDescriptor是一个重载函数 如果你看一下,它显示了4个版本——一个没有参数,一个有12个,一个有字符串,还有一个有我不太熟悉的选项
您已尝试使用一个包含5个参数的参数。没有这样的函数。您需要使用none、all 12或one。如果您看到,此人为控制规范提供了一个xml文件-这符合字符串文件名选项,因此是一个有效的函数。您观察到的问题是由于以下几个因素的组合:
- –更改除法运算符
- 映射到Python和重载C++函数的调度(如OpenCV中的)
/
的含义在Python2.x和Python3.x之间发生了变化
来自PEP-238:
- 在Python2.x中,Classic除法仍然是默认的 系列真正的除法在Python 3.0中是标准的
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16, 16)
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16.0, 16.0)
在Python3.x中,您有
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16, 16)
>>> small_size = (32, 32)
>>> block_size = (small_size[0] / 2, small_size[1] / 2)
>>> print(block_size)
(16.0, 16.0)
为了得到相同的结果,Python3.x代码需要使用操作符/
>>> small_size = (32, 32)
>>> block_size = (small_size[0] // 2, small_size[1] // 2)
>>> print(block_size)
(16, 16)
重载的映射和处理
在不深入讨论细节的情况下(这需要一个单独的问题),重载解决方案取决于参数的类型。类型的匹配非常严格,例如,不能将浮点数传递给整型参数
所涉及的构造函数的C++签名(仅截断相关参数)为
cv::Size
是一个。在Python API中,它表示为包含两个整数的元组
因此,要在Python中调用此重载,我们需要提供:
- 4x一个包含两个整数的元组(用于
,\u winSize
,\u blockSize
和\u blockStride
)\u cellSize
- 1x一个整数(用于
)\u nbins
>>> import cv2
>>> cv2.HOGDescriptor((1,1),(1,1),(1,1),(1,1),1)
<HOGDescriptor 0393D0F0>
我们看到元组需要有两个值,不多也不少
>>> cv2.HOGDescriptor([1,1],(1,1),(1,1),(1,1),1)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
列表不行,它必须是一个元组
>>> cv2.HOGDescriptor((1.0,1.0),(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),1.0)
TypeError: HOGDescriptor() takes at most 1 argument (5 given)
我们也不能用浮点数代替整数
把这一切都集中起来
考虑到上述情况,就传递给构造函数的值而言,有两种变体:
- Python2.x:
cv2.HOGDescriptor((32,32)、(16,16)、(8,8)、(8,8)、9)
- Python3.x:
cv2.HOGDescriptor((32,32),(16.0,16.0),(8.0,8.0),(8.0,8.0),9)
至于我们为什么会收到误导性的错误信息,这似乎是另一个值得单独提问的话题,我还没有做所有必要的研究来权威地回答这个问题。我不确定你在说什么文档,因为Python绑定实际上没有任何文档,所以这里有很多问题在抱怨这个事实。你到底在哪里看到它可以包含五个参数?@DanielRoseman
help(cv2.HOGDescriptor)
显示了它。此外,重载的前缀为CV\u WRAP
。无法调用此构造函数似乎是Python映射中的一个错误——我猜这是由于多重重载造成的。在12个参数中,最后7个提供了默认值。通常,OpenCV Python API映射也反映了这一点。i、 e.您应该能够仅使用提供的5个参数调用构造函数,其余参数使用默认值。这一特定内容的前缀是CV_WRAP
,因此它打算在Python中公开。甚至帮助(cv2.HOGDescriptor)也列出了它。您不能调用它的事实对我来说似乎是一个bug。因此,Dan Mašek,我不知道它是否是opencv和python 3.6版本的bug,但我安装了python 2.7并尝试了它。在进一步的测试中,它被证明是一个稍微误导的错误消息,这是由重载解析的工作方式引起的。它对参数非常挑剔——前4个必须是每个都有2个整数的元组,第5个是整数。如果不匹配,则不会选择过载。误导性错误很可能是Python实现的副作用。@neca OK,现在我们找到了问题的真正原因-。运算符/
的含义已更改。在Python3变体中,32/2
给出一个浮点,而不是int。由于参数不匹配,重载失败。:)您可以使用floor操作(//)恢复整数除法。(small_size[0]//2,small_size[1]//2)给出int。在整数参数上发现得很好,我错过了!你为什么不发布一个答案,这样它就可以被接受?