Qt + Opencv 角点检测(Shi-Tomas + 亚像素精度角点)

直接上代码

 1 #include "mainwindow.h"
 2 #include "ui_mainwindow.h"
 3 
 4 #include<opencv2/opencv.hpp>
 5 #include<QDebug>
 6 #include<QElapsedTimer>
 7 
 8 using namespace cv;
 9 #pragma execution_character_set("utf-8")
10 MainWindow::MainWindow(QWidget *parent)
11     : QMainWindow(parent)
12     , ui(new Ui::MainWindow)
13 {
14     ui->setupUi(this);
15 
16     QElapsedTimer time;
17 
18     Mat img = imread("1.png");
19     if(img.empty())
20         return;
21 
22     Mat grayImg;
23     if(img.channels() == 3)
24         cvtColor(img, grayImg, COLOR_BGR2GRAY);
25     else
26         img.copyTo(grayImg);
27 
28     time.start();
29 //[0]  找角点
30     int x = 688, y = 63, w = 100, h = 100;
31     Rect rect(x, y, w, h);
32     Mat rectImag = grayImg(rect);
33     std::vector<Point2f> points;
34 
35     //  处理前要先截取图片,大图片很耗费时间
36     //  0.09比最小可接受质量corner大,可以过滤掉不需要的corner
37     goodFeaturesToTrack(rectImag, points, 2, 0.09, 10);
38     for (int i =0; i < points.size(); i++)
39         qDebug()<<"亚像素处理前: "<<points[i].x<<points[i].y;
40 
41     for (int i =0; i < points.size(); i++)
42     {
43         circle(img, Point(points[i].x + x, points[i].y + y), 3, Scalar(0, 0, 255), FILLED);
44     }
45 //[0]
46     qDebug()<<time.elapsed();   //  3ms
47 
48 //[1]  找到最小可接受质量corner
49     Mat dst(grayImg.rows, grayImg.cols, CV_32FC1);
50     cornerMinEigenVal(rectImag, dst, 3);
51     float bastCorner = 0;
52     for (int i =0; i < dst.rows; i++)
53     {
54         for (int j =0; j < dst.cols; j++)
55         {
56             if(dst.at<float>(i, j) > bastCorner)
57                 bastCorner = dst.at<float>(i, j);   //  记录最小可接受质量corner
58         }
59     }
60 
61     qDebug()<<bastCorner;   //  最小可接受质量corner为0.0342
62 //[1]
63 
64 //[2]  亚像素级的角点检测
65     time.start();
66     cornerSubPix(rectImag, points, Size(3, 3), Size(-1, -1),
67                  TermCriteria(TermCriteria::COUNT|TermCriteria::EPS, 20, 0.01));
68     for (int i =0; i < points.size(); i++)
69         qDebug()<<"亚像素处理后: "<<points[i].x<<points[i].y;
70     qDebug()<<time.elapsed();  //  0ms
71 //[2]
72 
73     imshow("rectImag", rectImag);
74     imshow("img", img);
75 }

 原图

rectImg

注意事项:

1、千万别用Harris!千万别用Harris!千万别用Harris!难调又难用!Shi-Tomas是Harris改良版。

2、goodFeaturesToTrack()算子处理的图片一定要截图,千万不要完整图片,加掩膜也没用,灰度原图(985*756)耗时150ms+,截图后才3ms。

3、goodFeaturesToTrack()算子处理前先运行cornerMinEigenVal()算子,将最小可接受质量的corner找到,才能写入合适的qualityLevel。

4、找角点还有另一种方法,通过两直线相交或者直线与圆相交的方法,但是找两条直线不如直接找角点快。

5、cornerSubPix()算子基本不耗时(本程序),观测结果可见至多能修正0.5个像素(±0.5取上下限),对于精度要求高的项目很有必要。

6、TermCriteria::COUNT:迭代次数或元素最大数目  TermCriteria::EPS:迭代算法终止所需精度条件。

 

posted @ 2021-08-22 23:43  补码  阅读(220)  评论(0编辑  收藏  举报