使用Python在OpenCv中设置ORB参数

3
我一直在使用Python中的OpenCV 2.4来匹配两张图片之间的特征,但我想更改“ORB”检测器的一个参数(提取的特征数“nfeatures”),但在Python中似乎没有办法这样做。
对于C++,您可以通过FeatureDetector / DescriptorExtractor的“read”(或java的“load”)方法加载参数yml / xml文件。然而,Python绑定缺少此功能/方法。
它还缺少直接创建ORB对象的绑定,因此我无法在那里传递参数(Python绑定似乎要求您使用字符串名称的cv2.DescriptorExtractor_create——如果您传递错误的字符串名称或其中的参数将导致段错误……此外,该函数似乎无法接受任何其他参数以传递到构造函数中)。
我唯一的希望似乎是使用cv2.cv.Load(filename)从xml中加载完整对象,但似乎它需要一个对象实例而不是算法定义,而我在新旧语法中都找不到任何Python绑定。我尝试了几种文件加载步骤的变体,包括模仿OpenCV保存的xml文件的样式,但都没有成功。
是否有人在上述步骤中成功地传递了参数到OpenCV中的检测器(SURF或ORB或任何通用算法)?
以下是我用于提取特征的代码:
def findFeatures(greyimg, detector="ORB", descriptor="ORB"):
    nfeatures = 2000 # No way to pass to detector...?
    detector = cv2.FeatureDetector_create(detector)
    descriptorExtractor = cv2.DescriptorExtractor_create(descriptor)
    keypoints = detector.detect(greyimg)
    (keypoints, descriptors) = descriptorExtractor.compute(greyimg, keypoints)
    return keypoints, descriptors

编辑

更改探测器设置似乎仅在Windows实现中导致段错误 - 等待OpenCV网站上的补丁或修复。

1个回答

5
import cv2

# to see all ORB parameters and their values
detector = cv2.FeatureDetector_create("ORB")    
print "ORB parameters (dict):", detector.getParams()
for param in detector.getParams():
    ptype = detector.paramType(param)
    if ptype == 0:
        print param, "=", detector.getInt(param)
    elif ptype == 2:
        print param, "=", detector.getDouble(param)

# to set the nFeatures
print "nFeatures before:", detector.getInt("nFeatures")
detector.setInt("nFeatures", 1000)
print "nFeatures after:", detector.getInt("nFeatures")

输出结果:

ORB参数(字典):['WTA_K', 'edgeThreshold', 'firstLevel', 'nFeatures', 'nLevels', 'patchSize', 'scaleFactor', 'scoreType']
WTA_K = 2
edgeThreshold = 31
firstLevel = 0
nFeatures = 500
nLevels = 8
patchSize = 31
scaleFactor = 1.20000004768
scoreType = 0
更改前nFeatures:500
更改后nFeatures:1000

编辑:现在使用OpenCV 3.0完成相同操作更加容易

import cv2

detector = cv2.ORB_create()
for attribute in dir(new_detector):
    if not attribute.startswith("get"):
        continue
    param = attribute.replace("get", "")
    get_param = getattr(new_backend, attribute)
    val = get_param()
    print param, '=', val

并且与setter类似。


在发布问题之前,我曾经尝试过这个。在运行32位Python的Windows 7 64位和运行32位Python的Windows Vista 32位上使用OpenCV 2.4时,detector.getParams()导致了Segmentation Fault,没有堆栈跟踪,没有异常可捕获,也没有来自OpenCV的错误消息。你使用的设置是什么,让它不会立即Segfault? - Pyrce
只有在 DescriptorMatcher 的 getParams() 上会崩溃,但检测器可以正常工作。我使用的是 Fedora 17 64 位、OpenCV 2.4.3 和 Python 2.7.3 64 位。 - pevogam
探测器可以工作,但我无法设置或获取探测器上的任何参数,这使得它无法使用,因为默认值不符合所有视觉问题(结果我使用了另一个探测器)。如果在getParams时崩溃,你是如何打印上面的输出的?我可能会尝试在我的机器上使用Fedora虚拟机,看看是否会在相同的调用上崩溃。 - Pyrce
你说得完全正确,可调参数对于任何计算机视觉问题都至关重要。上面的代码在我的设置中完全正常运行(就是我之前提到的那个),并且给出了相同的输出结果。我不知道 Windows 的问题可能是什么,但我建议你尝试类似的设置或者查看 http://code.opencv.org/projects/opencv/issues 以了解 Windows 已知的 bug。 - pevogam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接