一:内容介绍

本节主要介绍OpenCV的imgproc模块的角点检测(Feature Detection)部分:

1. Harris角点检测

2. Shi-Tomasi角点检测

3. 亚像素级角点检测

二:学习笔记

1. harris角点还是挺常见的,Harris角点 这篇文章介绍的比较好。

————————–补充于16/11/10————————————-

昨天帮老师做几页关于harris的PPT,又回顾了一遍harris算法,这里有几页比较好的讲解,分享一下。另参考wiki Corner detection

PPT上字写的烂,不要介意,哈哈。

opencv直角检测 opencv检测三角形_#include


opencv直角检测 opencv检测三角形_角点_02


opencv直角检测 opencv检测三角形_角点检测_03


opencv直角检测 opencv检测三角形_角点检测_04


opencv直角检测 opencv检测三角形_角点检测_05


opencv直角检测 opencv检测三角形_角点检测_06


opencv直角检测 opencv检测三角形_角点_07


opencv直角检测 opencv检测三角形_角点_08


opencv直角检测 opencv检测三角形_角点检测_09


opencv直角检测 opencv检测三角形_#include_10


opencv直角检测 opencv检测三角形_opencv直角检测_11


opencv直角检测 opencv检测三角形_#include_12


opencv直角检测 opencv检测三角形_角点检测_13


opencv直角检测 opencv检测三角形_角点检测_14


opencv直角检测 opencv检测三角形_角点_15


—————————————————————

2. 亚像素级角点检测这一点,书中介绍的比较简略。定理是:在角点q附近的点的灰度梯度均垂直于该点与角点的连线。根据这条定理,我们可以找到多个关于p和q的方程组,从而求解出q的位置。

3 . 本节函数清单

opencv直角检测 opencv检测三角形_opencv直角检测_16


三:相关源码及解析

本章示例较多,示例列表:

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);
}

素材:

opencv直角检测 opencv检测三角形_角点检测_17


效果图:

opencv直角检测 opencv检测三角形_角点_18


opencv直角检测 opencv检测三角形_opencv直角检测_19


提示:


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);
}

素材:

opencv直角检测 opencv检测三角形_opencv直角检测_20


效果图:

opencv直角检测 opencv检测三角形_#include_21


提示:


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;
    }
}

素材:

opencv直角检测 opencv检测三角形_角点_22


效果图:

opencv直角检测 opencv检测三角形_角点检测_23


opencv直角检测 opencv检测三角形_角点检测_24


提示: