OpenCV3 亚像素角点检测:cv2.cornerSubPix()

        exact_corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)

前言:cv::goodFeaturesToTrack()提取到的角点只能达到像素级别【OpenCV3 角点检测:goodFeaturesToTrack()】,在很多情况下并不能满足实际的需求,这时,我们则需要使用cv::cornerSubPix()对检测到的角点作进一步的优化计算,可使角点的精度达到亚像素级别。

函数原型:

 
  1. void cv::cornerSubPix(

  2. cv::InputArray image, // 输入图像

  3. cv::InputOutputArray corners, // 角点(既作为输入也作为输出)

  4. cv::Size winSize, // 区域大小为 NXN; N=(winSize*2+1)

  5. cv::Size zeroZone, // 类似于winSize,但是总具有较小的范围,Size(-1,-1)表示忽略

  6. cv::TermCriteria criteria // 停止优化的标准

  7. );

参数解析:

 
  1. 第一个参数是输入图像,和cv::goodFeaturesToTrack()中的输入图像是同一个图像。

  2. 第二个参数是检测到的角点,即是输入也是输出。

  3.  
  4. 第三个参数是计算亚像素角点时考虑的区域的大小,大小为NXN; N=(winSize*2+1)。

  5.  
  6. 第四个参数作用类似于winSize,但是总是具有较小的范围,通常忽略(即Size(-1, -1))。

  7.  
  8. 第五个参数用于表示计算亚像素时停止迭代的标准,可选的值有cv::TermCriteria::MAX_ITER 、cv::TermCriteria::EPS(可以是两者其一,或两者均选),

  9. 前者表示迭代次数达到了最大次数时停止,后者表示角点位置变化的最小值已经达到最小时停止迭代。二者均使用cv::TermCriteria()构造函数进行指定。

程序示例:

 
  1. #include <iostream>

  2. #include <vector>

  3. #include <opencv2/opencv.hpp>

  4. #include <opencv2/core/core.hpp>

  5. #include <opencv2/highgui/highgui.hpp>

  6.  
  7. int main()

  8. {

  9. cv::Mat image_color = cv::imread("house.jpg", 1);

  10.  
  11. //用于绘制亚像素角点

  12. cv::Mat image_copy = image_color.clone();

  13. //使用灰度图像进行角点检测

  14. cv::Mat image_gray;

  15. cv::cvtColor(image_color, image_gray, cv::COLOR_BGR2GRAY);

  16.  
  17. //设置角点检测参数

  18. std::vector<cv::Point2f> corners;

  19. int max_corners = 100;

  20. double quality_level = 0.01;

  21. double min_distance = 10;

  22. int block_size = 3;

  23. bool use_harris = false;

  24. double k = 0.04;

  25.  
  26. //角点检测

  27. cv::goodFeaturesToTrack(image_gray,

  28. corners,

  29. max_corners,

  30. quality_level,

  31. min_distance,

  32. cv::Mat(),

  33. block_size,

  34. use_harris,

  35. k);

  36.  
  37. //将检测到的角点绘制到原图上

  38. for (int i = 0; i < corners.size(); i++)

  39. {

  40. cv::circle(image_color, corners[i], 5, cv::Scalar(0, 0, 255), 2, 8, 0);

  41. }

  42.  
  43. //指定亚像素计算迭代标注

  44. cv::TermCriteria criteria = cv::TermCriteria(

  45. cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,

  46. 40,

  47. 0.01);

  48.  
  49. //亚像素检测

  50. cv::cornerSubPix(image_gray, corners, cv::Size(5, 5), cv::Size(-1, -1), criteria);

  51.  
  52. //将检测到的亚像素角点绘制到原图上

  53. for (int i = 0; i < corners.size(); i++)

  54. {

  55. cv::circle(image_copy, corners[i], 5, cv::Scalar(0, 255, 0), 2, 8, 0);

  56. }

  57.  
  58. cv::imshow("corner", image_color);

  59. cv::imshow("sub pixel corner", image_copy);

  60.  
  61. cv::imwrite("corner.jpg", image_color);

  62. cv::imwrite("corner_sub.jpg", image_copy);

  63.  
  64. cv::waitKey(0);

  65. return 0;

  66. }

 

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
亚像素角点检测是一种精细的角点检测方法,可以更准确地定位图像中的角点。OpenCV中提供了cornerSubPix()函数来实现亚像素角点检测。 使用方法如下: 1. 首先进行角点检测,可以使用cornerHarris()或者cornerMinEigenVal()等函数。 2. 对于检测到的角点,使用cornerSubPix()函数进行亚像素级别的精细定位。 3. 调用cornerSubPix()函数时,需要传入原始图像、角点坐标、搜索窗口大小等参数,函数会返回精细定位后的角点坐标。 示例代码如下: ``` import cv2 # 读取图像 img = cv2.imread('test.jpg') # 进行角点检测 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) corners = cv2.cornerHarris(gray, 2, 3, 0.04) # 取出角点坐标 corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10) corners = np.int0(corners) # 进行亚像素角点检测 corners_sub = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)) # 在图像上绘制角点 for i in corners: x, y = i.ravel() cv2.circle(img, (x, y), 3, (0, 0, 255), -1) for i in corners_sub: x, y = i.ravel() cv2.circle(img, (x, y), 3, (0, 255, 0), -1) # 显示图像 cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们先使用cornerHarris()函数进行角点检测,然后使用goodFeaturesToTrack()函数取出角点坐标。最后使用cornerSubPix()函数进行亚像素级别的角点精细定位,并在图像上绘制出检测结果。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值