You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在OpenCV 3.4.8中如何从Python向C++传递cv::KeyPoint数组?

问题:Python向OpenCV C++传递cv::KeyPoint列表失败

背景信息

  • cv::KeyPoint从Python视角的字段及类型:
    • x:np.float32
    • y:np.float32
    • size:np.float32
    • angle:np.float32
    • response:np.float32
    • octave:np.int32
    • class_id:np.int32
  • 单组关键点数量通常为200-500+

Python端代码

# Detect keypoints and compute descriptors
orb = cv2.ORB_create()
keypoints1 = orb.detect(img1, None)
keypoints2 = orb.detect(img2, None)
keypoints1, descriptors1 = orb.compute(img1, keypoints1)
keypoints2, descriptors2 = orb.compute(img2, keypoints2)

# Convert keypoints to Python lists of cv::KeyPoint objects
keypoints1_list = [cv2.KeyPoint(kp.pt[0], kp.pt[1], kp.size, kp.angle, kp.response, kp.octave, kp.class_id) for kp in keypoints1]
keypoints2_list = [cv2.KeyPoint(kp.pt[0], kp.pt[1], kp.size, kp.angle, kp.response, kp.octave, kp.class_id) for kp in keypoints2]

arr_kp1= np.ascontiguousarray(keypoints1_list)
arr_kp2= np.ascontiguousarray(keypoints2_list)

opencvwrapper.evaluateFeatureDetector(arr_img1, arr_img2, arr_kp1, arr_kp2)

C++端绑定代码(基于OpenCV 3.4.8 + pybind11)

float evaluateFeatureDetector(py::array_t<uint8_t>& arr1, py::array_t<uint8_t>& arr2, py::array_t<cv::KeyPoint>& keypoints1, py::array_t<cv::KeyPoint>& keypoints2){
... 
cv::Mat H1to2= cv::findHomography(keypoints1, keypoints2, cv::RANSAC);
// Do some more computations here
}

错误信息

TypeError: evaluateFeatureDetector(): incompatible function arguments. The following argument types are supported:
    1. (arg0: cv::Mat, arg1: cv::Mat, arg2: List[cv::KeyPoint], arg3: List[cv::KeyPoint]) -> float

Invoked with: array([[[ 2,  4,  4],
        [ 1,  3,  3],
        [ 0,  2,  2],
        ...,
        [ 1,  4,  2],
        [ 0,  3,  1]]], dtype=uint8), array([[[12, 12, 12],
        [11, 11, 11],
        [11, 11, 11],
        ...,
        [44, 44, 44],
        [47, 47, 47],
        [47, 47, 47]]], dtype=uint8), [<KeyPoint 0x7f96a7239060>, <KeyPoint 0x7f96a7239090>, <KeyPoint 0x7f96a72390c0>, ...

已尝试的无效方法

  • 使用std::vector<cv::KeyPoint>&作为参数,报错;改用py::array_t<cv::KeyPoint>&后错误依旧
  • 用np.ascontiguousarray()转换关键点列表,但cv::KeyPoint不是numpy支持的数值类型
  • 将C++参数改为float类型,导致cv::findHomography()因输入类型不匹配报错

解决建议

1. 修正C++函数参数类型

错误提示已明确支持的参数类型,直接调整函数定义,同时确保包含STL转换的头文件:

#include <pybind11/stl.h> // 必须包含以支持std::vector与Python列表的自动转换

float evaluateFeatureDetector(cv::Mat& img1, cv::Mat& img2, std::vector<cv::KeyPoint>& keypoints1, std::vector<cv::KeyPoint>& keypoints2) {
    cv::Mat H1to2 = cv::findHomography(keypoints1, keypoints2, cv::RANSAC);
    // 后续计算逻辑
    return 0.0f; // 根据实际需求返回结果
}

2. 简化Python端代码

不需要将关键点转为numpy数组,直接传递原始关键点列表即可:

# Detect keypoints and compute descriptors
orb = cv2.ORB_create()
keypoints1 = orb.detect(img1, None)
keypoints2 = orb.detect(img2, None)
keypoints1, descriptors1 = orb.compute(img1, keypoints1)
keypoints2, descriptors2 = orb.compute(img2, keypoints2)

# 直接传递原始关键点列表,无需额外转换
opencvwrapper.evaluateFeatureDetector(img1, img2, keypoints1, keypoints2)

3. 确认pybind11绑定配置

  • 确保绑定代码中包含pybind11/stl.h,pybind11会自动处理std::vector<cv::KeyPoint>与Python列表的转换
  • OpenCV 3.4.8的cv::Mat和cv::KeyPoint可被pybind11自动识别,无需额外配置

关键说明

  • Python中的cv::KeyPoint对象列表可直接被pybind11转换为C++的std::vector<cv::KeyPoint>,无需手动转numpy数组
  • Python的numpy图像数组会自动转为C++的cv::Mat,无需额外处理

内容的提问来源于stack exchange,提问作者dev_4a_living

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:49:56