3

我一直在 Python 中使用 OpenCV 2.4 来匹配两个图像之间的特征,但我想更改“ORB”检测器的参数之一(它提取“nfeatures”的特征数量),似乎没有办法在 Python 中这样做。

对于 C++,您可以通过 FeatureDetector/DescriptorExtractor 的“读取”(或 java 的“加载”?)方法加载参数 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 的网站上。

4

1 回答 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 参数 (dict): ['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 before: 500
nFeatures after: 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

并与二传手类比。

于 2013-02-26T21:21:41.100 回答