《OpenCV3编程入门》学习笔记十:角点检测

一:内容介绍
本节主要介绍OpenCV的imgproc模块的角点检测(Feature Detection)部分:
1. Harris角点检测
2. Shi-Tomasi角点检测
3. 亚像素级角点检测
二:学习笔记
1. harris角点还是挺常见的,Harris角点 这篇文章介绍的比较好。
————————–补充于16/11/10————————————-
昨天帮老师做几页关于harris的PPT,又回顾了一遍harris算法,这里有几页比较好的讲解,分享一下。另参考wiki Corner detection
PPT上字写的烂,不要介意,哈哈。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
—————————————————————
2. 亚像素级角点检测这一点,书中介绍的比较简略。定理是:在角点q附近的点的灰度梯度均垂直于该点与角点的连线。根据这条定理,我们可以找到多个关于p和q的方程组,从而求解出q的位置。深入探讨,详见Harris角点提取实现亚像素级摄像机自标定
3 . 本节函数清单
这里写图片描述
三:相关源码及解析
本章示例较多,示例列表:
1.Harris角点检测与绘制
2.Shi-Tomasi角点检测
3.亚像素级角点检测
1 . Harris角点检测与绘制
源码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

#define WINDOW_NAME1 "【程序窗口1】"
#define WINDOW_NAME2 "【程序窗口2】"
Mat g_srcImage, g_srcImage1, g_grayImage;
int thresh = 30;  //当前阈值
int max_thresh = 175; //最大阈值
void on_CornerHarris(int, void*); //回调函数

int main() {
    g_srcImage = imread("poster_house.jpg");
    imshow("【原始图】", g_srcImage);
    g_srcImage1 = g_srcImage.clone();
    cvtColor(g_srcImage1, g_grayImage, COLOR_BGR2GRAY);
    namedWindow(WINDOW_NAME1);
    createTrackbar("阈值:", WINDOW_NAME1, &thresh, max_thresh, on_CornerHarris);
    on_CornerHarris(0, 0);

    while (waitKey(9)!=27);
    return 0;
}

void on_CornerHarris(int, void*) {
    Mat dstImage, normImage, scaledImage;
    dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
    g_srcImage1 = g_srcImage.clone();
    cornerHarris(g_grayImage, dstImage, 2, 3, 0.04);  //进行角点检测
    normalize(dstImage, normImage, 0, 255, NORM_MINMAX);  //归一化
    convertScaleAbs(normImage, scaledImage);  //转换为8位无符号整形
    //将检测到的,且符合阈值条件的角点绘制出来
    for (int j = 0; j < normImage.rows; j++) {
        for (int i = 0; i < normImage.cols; i++) {
            if ((int)normImage.at<float>(j, i)>thresh+80) {
                circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2);
                circle(scaledImage, Point(i, j), 5, Scalar(10, 10, 255), 2);
            }
        }
    }
    imshow(WINDOW_NAME1, g_srcImage1);
    imshow(WINDOW_NAME2, scaledImage);
}

素材:
这里写图片描述
效果图:
这里写图片描述
这里写图片描述
提示:

2 . Shi-Tomasi角点检测
源码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

#define WINDOW_NAME "【Shi-Tomasi 角点检测】"
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = 33, g_maxTrackbarNumber=500;
RNG g_rng;
void on_GoodFeaturesToTrack(int, void*);

int main() {
    g_srcImage = imread("poster_castle_1.jpg");
    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
    namedWindow(WINDOW_NAME);
    createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
    imshow(WINDOW_NAME, g_srcImage);
    on_GoodFeaturesToTrack(0, 0);
    while (waitKey(9)!=27);
    return 0;
}

void on_GoodFeaturesToTrack(int, void*) {
    if (g_maxCornerNumber <= 1) g_maxCornerNumber = 1;

    vector<Point2f> corners;
    double qualityLevel = 0.01;  //角点检测可接受的最小特征值
    double minDistance = 10; //角点之间的最小距离
    goodFeaturesToTrack(g_grayImage, //输入图像
        corners,  //检测到角点的
        g_maxCornerNumber,  //角点的最大数量
        qualityLevel,   //角点检测可接受的最小特征值
        minDistance );  //角点之间的最小距离
    cout << "此次检测到的角点数量为:" << corners.size() << endl;
    Mat copy = g_srcImage.clone();  //复制源图像到一个临时变量
    int r = 4;
    for (unsigned int i = 0; i < corners.size(); i++)
        circle(copy, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1);
    imshow(WINDOW_NAME, copy);
}

素材:
这里写图片描述
效果图:
这里写图片描述
提示:

3 . 亚像素级角点检测
源码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

#define WINDOW_NAME "【Shi-Tomasi 角点检测】"
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = 33, g_maxTrackbarNumber = 500;
RNG g_rng;
void on_GoodFeaturesToTrack(int, void*);

int main() {
    g_srcImage = imread("poster_building_2.jpg");
    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
    namedWindow(WINDOW_NAME);
    createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
    imshow(WINDOW_NAME, g_srcImage);
    on_GoodFeaturesToTrack(0, 0);
    while (waitKey(9) != 27);
    return 0;
}

void on_GoodFeaturesToTrack(int, void*) {
    if (g_maxCornerNumber <= 1) g_maxCornerNumber = 1;

    vector<Point2f> corners;
    double qualityLevel = 0.01;  //角点检测可接受的最小特征值
    double minDistance = 10; //角点之间的最小距离
    goodFeaturesToTrack(g_grayImage, //输入图像
        corners,  //检测到角点的
        g_maxCornerNumber,  //角点的最大数量
        qualityLevel,   //角点检测可接受的最小特征值
        minDistance);  //角点之间的最小距离
    cout << "此次检测到的角点数量为:" << corners.size() << endl;
    Mat copy = g_srcImage.clone();  //复制源图像到一个临时变量
    int r = 4;
    for (unsigned int i = 0; i < corners.size(); i++)
        circle(copy, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1);
    imshow(WINDOW_NAME, copy);

    cornerSubPix(g_grayImage, corners, Size(5, 5), Size(-1, -1), TermCriteria(TermCriteria::EPS+TermCriteria::MAX_ITER, 40, 0.001));
    for (int i = 0; i < corners.size(); i++) {
        cout << ">>精确点坐标[" << i << "] (" << corners[i].x << "," << corners[i].y << ")" << endl;
    }
}

素材:
这里写图片描述
效果图:
这里写图片描述
这里写图片描述
提示:

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值