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

如何使用OpenCV从Harris角点检测器中提取关键点

解决Harris角点转std::vector<cv::KeyPoint>的问题

我太懂这种感觉了!SURF这类检测器直接给你返回KeyPoint列表,省心得很,但Harris就得我们手动转一下——不过其实真的不难,你已经完成了最核心的角点检测和筛选,只差最后一步把坐标包装成KeyPoint对象而已。

核心思路

你已经在双重循环里筛选出了符合阈值的角点坐标(i,j),现在只需要把每个符合条件的坐标,用cv::KeyPoint的构造函数包装起来,再塞进std::vector<cv::KeyPoint>里就行。

修改后的完整代码

我把你的代码补充了关键点提取的部分,看注释就能明白:

// 先定义存储KeyPoint的容器
std::vector<cv::KeyPoint> harris_keypoints;

/// Detecting corners
cv::cornerHarris(leftRoi, dst, blockSize, apertureSize, k, cv::BORDER_DEFAULT);

/// Normalizing
cv::normalize(dst, dst_norm, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
cv::convertScaleAbs(dst_norm, dst_norm_scaled);

/// Drawing a circle around corners AND extracting KeyPoints
for (int j = 0; j < dst_norm.rows; j++) {
    for (int i = 0; i < dst_norm.cols; i++) {
        if ((int)dst_norm.at<float>(j, i) > 165) {
            // 保留你原有的画圆逻辑
            cv::circle(dst_norm_scaled, cv::Point(i, j), 5, cv::Scalar(0), 2, 8, 0);
            
            // 核心:创建KeyPoint并加入容器
            // 参数说明:
            // - cv::Point2f(i, j): 关键点的坐标(注意i对应x轴,j对应y轴)
            // - 5: 关键点的大小,和你画的圆半径一致就行
            // - -1: Harris检测器不提供方向信息,设为-1表示无方向
            // - dst_norm.at<float>(j, i): 角点的响应值,用来区分关键点的强弱
            // - 0: octave(层级),Harris不需要,设为0即可
            // - 0: class_id,不需要分类的话设为0
            harris_keypoints.emplace_back(cv::Point2f(i, j), 5, -1, dst_norm.at<float>(j, i), 0, 0);
        }
    }
}

/// Showing the result
cv::namedWindow("corners_window", cv::WINDOW_AUTOSIZE);
cv::imshow("corners_window", dst_norm_scaled);

后续使用提示

现在harris_keypoints里就存好了所有符合条件的关键点,你可以直接把它传给描述子提取器(比如cv::ORB、cv::BRISK)来计算描述子,之后就能进行特征匹配了。

需要注意的是:Harris角点没有方向信息,如果你用依赖方向的描述子(比如SIFT),效果可能会比自带方向的检测器差一些;但如果用ORB这类不依赖方向的描述子,完全没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:04:14