opencv學習之路(32)、角點檢測


 一、角點檢測的相關概念

二、Harris角點檢測——cornerHarris()

參考網址: http://www.cnblogs.com/ronny/p/4009425.html

 

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

void main()
{
    Mat img = imread("E://3.jpg");
    imshow("src", img);
    Mat result = img.clone();
    Mat gray, dst , corner_img;//corner_img存放檢測后的角點圖像
    cvtColor(img, gray, CV_BGR2GRAY);

    cornerHarris(gray, corner_img, 2, 3, 0.04);//cornerHarris角點檢測
    //imshow("corner", corner_img);
    threshold(corner_img, dst, 0.015, 255, CV_THRESH_BINARY);
    imshow("dst", dst);

    int rowNumber = gray.rows;  //獲取行數
    int colNumber = gray.cols;  //獲取每一行的元素
    cout << rowNumber << endl;
    cout << colNumber << endl;
    cout << dst.type() << endl;

    for (int i = 0; i<rowNumber; i++)
    {
        for (int j = 0; j<colNumber; j++)
        {
            if (dst.at<float>(i, j) == 255)//二值化后,灰度值為255為角點
            {
                circle(result, Point(j, i),3, Scalar(0, 255, 0), 2, 8);
            }
        }
    }

    imshow("result", result);
    waitKey(0);
}

淺墨代碼

http://blog.csdn.net/poem_qianmo/article/details/29356187

#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*)
{
    Mat dstImage;//目標圖  
    Mat normImage;//歸一化后的圖  
    Mat 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, CV_32FC1, Mat());
    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, 8, 0);
                circle(scaledImage, Point(i, j), 5, Scalar(0, 10, 255), 2, 8, 0);
            }
        }
    }
    imshow(WINDOW_NAME1, g_srcImage1);
    imshow(WINDOW_NAME2, scaledImage);

}

static void ShowHelpText()
{
    printf("\n\n\n\t\t\t【歡迎來到Harris角點檢測示例程序~】\n\n");
    printf("\n\n\n\t請調整滾動條觀察圖像效果~\n\n");
    printf("\n\n\t\t\t\t\t\t\t\t by淺墨");
}


void main()
{
    system("color 3F");
    ShowHelpText();

    //載入原始圖並進行克隆保存  
    g_srcImage = imread("E://1.jpg", 1);
    if (!g_srcImage.data) { printf("讀取圖片錯誤,請確定目錄下是否有imread函數指定的圖片存在~! \n"); return ; }
    imshow("原始圖", g_srcImage);
    g_srcImage1 = g_srcImage.clone();
    cvtColor(g_srcImage1, g_grayImage, CV_BGR2GRAY);

    //創建窗口和滾動條  
    namedWindow(WINDOW_NAME1, CV_WINDOW_NORMAL);
    createTrackbar("閾值: ", WINDOW_NAME1, &thresh, max_thresh, on_CornerHarris);
    on_CornerHarris(0, 0);//調用一次回調函數,進行初始化
    
    waitKey(0);
}

三、Shi-Tomasi角點檢測——goodFeaturesToTrack()

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

void main()
{
    Mat src = imread("E://0.jpg");
    imshow("src", src);
    Mat result = src.clone();
    Mat gray;
    cvtColor(src, gray,CV_BGR2GRAY);
    
    vector<Point2f>corners;//Point2f類型的向量:存儲每個角點的坐標
    //輸入圖,向量,最大角點數量,角點的最小特征值,角點間最小距離,掩碼(Mat()表示掩碼為空),blocksize,是否使用Harris角點檢測,權重系數
    goodFeaturesToTrack(gray, corners, 100,0.01,10,Mat(),3,false,0.04);
    cout << "角點數量" << corners.size() << endl;

    //畫圓標注角點
    for (int i = 0; i < corners.size(); i++)
        circle(result, corners[i], 5, Scalar(0, 255, 0),2,8);
    imshow("result", result);
    waitKey(0);
}
 

淺墨大神代碼(加了滑動條效果)

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

#define WINDOW_NAME "【Shi-Tomasi角點檢測】" 
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = 33;
int g_maxTrackbarNumber = 500;
RNG g_rng(12345);//初始化隨機數生成器


                 //-----------------------------【on_GoodFeaturesToTrack( )函數】----------------------------
                 //          描述:響應滑動條移動消息的回調函數
                 //----------------------------------------------------------------------------------------------
void on_GoodFeaturesToTrack(int, void*)
{
    //【1】對變量小於等於1時的處理
    if (g_maxCornerNumber <= 1) { g_maxCornerNumber = 1; }

    //【2】Shi-Tomasi算法(goodFeaturesToTrack函數)的參數准備
    vector<Point2f> corners;
    double qualityLevel = 0.01;//角點檢測可接受的最小特征值
    double minDistance = 10;//角點之間的最小距離
    int blockSize = 3;//計算導數自相關矩陣時指定的鄰域范圍
    double k = 0.04;//權重系數
    Mat copy = g_srcImage.clone();    //復制源圖像到一個臨時變量中,作為感興趣區域

                                    //【3】進行Shi-Tomasi角點檢測
    goodFeaturesToTrack(g_grayImage,//輸入圖像
        corners,//檢測到的角點的輸出向量
        g_maxCornerNumber,//角點的最大數量
        qualityLevel,//角點檢測可接受的最小特征值
        minDistance,//角點之間的最小距離
        Mat(),//感興趣區域
        blockSize,//計算導數自相關矩陣時指定的鄰域范圍
        false,//不使用Harris角點檢測
        k);//權重系數


           //【4】輸出文字信息
    cout << "\t>此次檢測到的角點數量為:" << corners.size() << endl;

    //【5】繪制檢測到的角點
    int r = 4;
    for (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, 8, 0);
    }

    //【6】顯示(更新)窗口
    imshow(WINDOW_NAME, copy);
}

static void ShowHelpText()
{
    //輸出歡迎信息和OpenCV版本
    printf("\n\n\t\t\t非常感謝購買《OpenCV3編程入門》一書!\n");
    printf("\n\n\t\t\t此為本書OpenCV2版的第87個配套示例程序\n");
    printf("\n\n\t\t\t   當前使用的OpenCV版本為:" CV_VERSION);
    printf("\n\n  ----------------------------------------------------------------------------\n");
    //輸出一些幫助信息
    printf("\n\n\n\t歡迎來到【Shi-Tomasi角點檢測】示例程序\n");
    printf("\n\t請調整滑動條觀察圖像效果\n\n");

}

void main()
{
    system("color 2F");
    ShowHelpText();

    //【1】載入源圖像並將其轉換為灰度圖
    g_srcImage = imread("3.jpg", 1);
    cvtColor(g_srcImage, g_grayImage, CV_BGR2GRAY);

    //【2】創建窗口和滑動條,並進行顯示和回調函數初始化
    namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);
    createTrackbar("最大角點數", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
    imshow(WINDOW_NAME, g_srcImage);
    on_GoodFeaturesToTrack(0, 0);

    waitKey(0);
}

由於VS2015和opencv2有些兼容問題,會出現斷言錯誤(具體原因在上一篇博客有講),這里就不貼效果圖了。

四、亞像素角點檢測——cornerSubPix()

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

void main()
{
    Mat img = imread("E://2.jpg");
    imshow("src", img);
    Mat result = img.clone();
    Mat gray;
    cvtColor(img, gray, CV_BGR2GRAY);

    //Shi-Tomasi角點檢測
    vector<Point2f> corners;
    goodFeaturesToTrack(gray, corners, 100, 0.01, 10, Mat(), 3, false, 0.04);
    cout << "角點數量" << corners.size() << endl;

    for (int i = 0; i<corners.size(); i++)
    {
        cout << "像素坐標:(" << corners[i].x << ", " << corners[i].y << ")" << endl;
        circle(result, corners[i], 5, Scalar(0, 255, 0), 2, 8);
    }
    imshow("result", result);

    Size winSize = Size(5, 5);
    Size zeroZone = Size(-1, -1);
                                        //精度或最大迭代數目,其中任意一個達到  迭代次數40,精度0.001
    TermCriteria criteria = TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001);
    cornerSubPix(gray, corners, winSize, zeroZone, criteria);

    for (int j = 0; j<corners.size(); j++)
    {
        cout << "亞像素坐標:(" << corners[j].x << ", " << corners[j].y << ")" << endl;
        circle(img, corners[j], 5, Scalar(0, 255, 0), -1, 8);
    }
    imshow("subPix", img);

    waitKey(0);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM