**角点检测(Harris)基于Opencv2.4.9版本+VS2012开发平台进行编**

角点检测(Harris)基于Opencv2.4.9版本+VS2012开发平台进行编

角点检测
角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。也称为特征点检测。

角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。而实际应用中,大多数所谓的角点检测方法检测的是拥有特定特征的图像点,而不仅仅是“角点”。这些特征点在图像中有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、某些梯度特征等。

现有的角点检测算法并不是都十分的鲁棒。很多方法都要求有大量的训练集和冗余数据来防止或减少错误特征的出现。角点检测方法的一个很重要的评价标准是其对多幅图像中相同或相似特征的检测能力,并且能够应对光照变化、图像旋转等图像变化。

Harris角点检测

当一个窗口在图像上移动,在平滑区域如图(a),窗口在各个方向上没有变化。在边缘上如图(b),窗口在边缘的方向上没有变化。在角点处如图(c),窗口在各个方向上具有变化。Harris角点检测正是利用了这个直观的物理现象,通过窗口在各个方向上的变化程度,决定是否为角点。

【相关代码】

定义一个回调函数:
void on_CornerHarris( int, void* );//回调函数

    void on_CornerHarris( int, void* );//回调函数
    void on_CornerHarris( int, void* )
    {

        //---------------------------【1】定义一些局部变量-----------------------------

        Mat dstImage;//目标图
        Mat normImage;//归一化后的图
        Mat scaledImage;//线性变换后的八位无符号整型的图
        //---------------------------【2】初始化--------------------------------------
        //置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
        dstImage = Mat::zeros( g_srcImage.size(), CV_32FC1 );
        g_srcImage1=g_srcImage.clone( );
        //---------------------------【3】正式检测-------------------------------------
        //进行角点检测
        cornerHarris( g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT );
        // 归一化与转换
        normalize( dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
        convertScaleAbs( normImage, scaledImage );//将归一化后的图线性变换成8位无符号整型

        //---------------------------【4】进行绘制-------------------------------------

        // 将检测到的,且符合阈值条件的角点绘制出来
    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 );

            }

        }

    }
        //---------------------------【4】显示最终效果---------------------------------
        imshow( WINDOW_NAME1, g_srcImage1 );
        imshow( WINDOW_NAME2, scaledImage );
    }

【给出完整代码】

// ———————————-

// 基于Opencv2.4.9 + VS2012开发平台
// 角点检测(Harris)

扫描二维码关注公众号,回复: 1927120 查看本文章

//————————————

include

include

include

include

include

using namespace std;
using namespace cv;

define WINDOW_NAME1 “【程序窗口1】”

define WINDOW_NAME2 “【程序窗口2】”

Mat g_srcImage, g_srcImage1,g_grayImage;
int thresh = 20; //当前阈值
int max_thresh = 100; //最大阈值

void on_CornerHarris( int, void* );//回调函数
static void ShowHelpText();


int main()
{
    system("color 5F");  
    ShowHelpText();

    //【1】载入原始图并进行克隆保存
    g_srcImage = imread( "jianzhu.jpg", 1 );
    if(!g_srcImage.data ) 
    { 
        printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~!"); 
        return false; 
    } 

    /*imshow("原始图",g_srcImage);*/

    g_srcImage1=g_srcImage.clone( );
    //【2】存留一张灰度图
    cvtColor( g_srcImage1, g_grayImage, CV_BGR2GRAY );
    //【3】创建窗口和滚动条
    namedWindow( WINDOW_NAME1, CV_WINDOW_AUTOSIZE );
    createTrackbar( "阈值: ", WINDOW_NAME1, &thresh, max_thresh, on_CornerHarris );


    //【4】调用一次回调函数,进行初始化

    on_CornerHarris( 0, 0 );
    waitKey(0);
    return(0);

    }

void on_CornerHarris( int, void* )
{

    //---------------------------【1】定义一些局部变量-----------------------------

    Mat dstImage;//目标图
    Mat normImage;//归一化后的图
    Mat scaledImage;//线性变换后的八位无符号整型的图
    //---------------------------【2】初始化--------------------------------------
    //置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
    dstImage = Mat::zeros( g_srcImage.size(), CV_32FC1 );
    g_srcImage1=g_srcImage.clone( );
    //---------------------------【3】正式检测-------------------------------------
    //进行角点检测
    cornerHarris( g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT );
    // 归一化与转换
    normalize( dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
    convertScaleAbs( normImage, scaledImage );//将归一化后的图线性变换成8位无符号整型

    //---------------------------【4】进行绘制-------------------------------------

    // 将检测到的,且符合阈值条件的角点绘制出来
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 );

        }

    }

}
    //---------------------------【4】显示最终效果---------------------------------
    imshow( WINDOW_NAME1, g_srcImage1 );
    imshow( WINDOW_NAME2, scaledImage );
}

static void ShowHelpText()
{
//输出一些帮助信息
        printf("【欢迎来到Harris角点检测示例程序~】"); 
        printf("请调整滚动条观察图像效果~");

        printf("编辑人:姚永祥");
}

“`
效果图:
效果图1

角点检测后的图

检测后的灰度图

猜你喜欢

转载自blog.csdn.net/yyx20125084014/article/details/52453252