如何使用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
相关产品推荐
相关产品推荐

