OpenCV之图像特征提取与检测(七) 亚像素级别角点检测

提高检测精准度
    理论与现实总是不一致的,实际情况下几乎所有的角点不会是一个真正的准确像素点。 检测出的点(100, 5) 实际上可能是(100.234, 5.789),可以使用亚像素定位确定准确位置
        - 跟踪
        - 三维重建
        - 相机校正

亚像素定位方法
    - 插值方法
    - 基于图像矩计算
    - 曲线拟合方法 -(高斯曲面(最常用)、多项式、椭圆曲面)

这里写图片描述

代码

    #include "../common/common.hpp"

    static Mat src, gray;
    static const char title[] = "subpixel";
    static int subpixel_corners = 20; // 亚像素定位,浮点数运算,比较耗时
    static int subpixel_max = 50;
    static RNG rng(12345);

    static void subpixel(int, void*);

    void main(int argc, char** argv)
    {
        src = imread(getCVImagesPath("images/home.jpg"), IMREAD_COLOR);
        imshow("src2-8", src);
        cvtColor(src, gray, COLOR_BGR2GRAY);
        namedWindow(title, CV_WINDOW_AUTOSIZE);
        createTrackbar("subpixel:", title, &subpixel_corners, subpixel_max, subpixel);
        subpixel(0, 0);

        waitKey(0);
    }

    void subpixel(int, void*)
    {
        if (subpixel_corners < 5) subpixel_corners = 5;
        vector<Point2f> corners;
        double qualityLevel = 0.01;
        double minDistance = 10;
        int blockSize = 3;
        double k = 0.04;
        goodFeaturesToTrack(gray, corners, subpixel_corners, qualityLevel, minDistance, Mat(), blockSize, false, k);
        cout << "tomasi corners.size=" << corners.size() << endl;
        Mat retImg = gray.clone();
        cvtColor(retImg, retImg, CV_GRAY2BGR);
        for (int i = 0; i < corners.size(); i++)
        {
            cout << i << ".point[x,y]=" << corners[i].x << "," << corners[i].y << endl; // 整数值
            circle(retImg, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8, 0);
        }
        imshow(title, retImg);

        Size winSize = Size(5, 5); // 窗口不要太大,不然亚像素可能会被干扰
        Size zerozone = Size(-1, -1); // 拟合时使用 零区域
        //TermCriteria类是用来作为迭代算法的终止条件的,参数:类型(EPS表示迭代到阈值终止),第二个参数为迭代的最大次数,最后一个是特定的阈值
        TermCriteria tc = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
        cornerSubPix(gray, corners, winSize, zerozone, tc);// 亚像素定位,为后续计算提供更高精确度的值
        cout << "subpixel corners.size=" << corners.size() << endl;
        for (size_t i = 0; i < corners.size(); i++)
        {
            cout << i << ".point[x,y]=" << corners[i].x << "," << corners[i].y << endl; // 亚像素定位出来的,精确度较高,浮点值
        }
    }

效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/81268227