CV进阶操作【8】——Harris角点检测C++实现

编程环境:

VS + OpenCV + C++
完整代码已经更新至GitHub,欢迎fork~GitHub链接


声明:创作不易,未经授权不得复制转载
statement:No reprinting without authorization


内容概述:

  • Harris角点检测:实现Harris角点检测算法,并与OpenCV的cornerHarris函数的结果进行比较。

一、角点检测相关介绍

1、经典的Harris角点检测

基本算法步骤:

1.利用Soble计算出XY方向的梯度值得到Ix和Iy
2.计算出Ix2,Iy2,IxIy
3.(可选)利用高斯函数对Ix2,Iy2,Ix
Iy进行滤波,或用全一窗口
4.计算局部特征结果矩阵M的特征值和响应函数的值
R(i,j)=Det(M)-k(trace(M))^2 (0.04<=k<=0.06)
5.将计算出响应函数的值C进行局部极大值抑制,滤除一些不是角点的点,防止重叠,同时要满足大于设定的阈值

2、改进的Shi-Tomasi角点检测

(1) 经典的Harris角点检测方法不难看出,该算法的稳定性和k有关,而k是个经验值,不好把握,浮动也有可能较大。鉴于此,改进的Harris方法()直接计算出两个特征值,通过比较两个特征值直接分类,这样就不用计算Harris响应函数了。
(2) 另一方面,我们不再用非极大值抑制了,而选取容忍距离,容忍距离内只有一个特征点:该算法首先选取一个具有最大最小特征值(把每个harris矩阵的最小特征值作为其衡量,认为其更有代表性)的点(即:max(min(e1,e2)),e1,e2是harris矩阵的特征值)作为角点,然后依次按照最大最小特征值顺序寻找余下的角点,当然和前一角点距离在容忍距离内的新角点被忽略,防止重叠。
在opencv中的实现为:goodFeatureTrack()

void goodFeaturesToTrack(InputArray image, OutputArray corners,  
                          int maxCorners, double qualityLevel, double minDistance,  
                          InputArray mask=noArray(), int blockSize=3,  
                          bool useHarrisDetector=false, double k=0.04 );

3、FAST角点检测算法
        该算法检测的角点定义为在像素点的周围邻域内有足够多的像素点与该点处于不同的区域。应用到灰度图像中,即有足够多的像素点的灰度值大于该点的灰度值或者小于该点的灰度值,便是角点。算法原理比较简单,但实时性很强。
        Eg:若某像素点圆形邻域圆周上有3/4的点和该像素点不同(编程时不超过某阈值th),则认为该点就是候选角点。(这一思路可以使用机器学习的方法进行加速。对同一类图像,例如同一场景的图像,可以在16个方向上进行训练,得到一棵决策树,从而在判定某一像素点是否为角点时,不再需要对所有方向进行检测,而只需要按照决策树指定的方向进行2-3次判定即可确定该点是否为角点。)
        和Harris算法类似,该算法需要非极大值抑制。
        补充:SUSAN 提取算子
        基本原理是,与每一图像点相关的局部区域具有相同的亮度。如果某一窗口区域内的每一像元亮度值与该窗口中心的像元亮度值相同或相似,这一窗口区域将被称之为“USAN”。计算图像每一像元的“USAN”,为我们提供了是否有边缘的方法。位于边缘上的像元的“USAN”较小(像素值一般是连续变化的),位于角点上的像元的“USAN”更小。因此,我们仅需寻找最小的“USAN”,就可确定角点。该方法由于不需要计算图像灰度差,因此,具有很强的抗噪声的能力。
        Fast在opencv中的实现:FastFeatureDetector fast(参数列表);

    //示例代码
    Mat  image, image1 = cv::imread ("test.jpg");
    cv::cvtColor (image1,image,CV_BGR2GRAY);
    //快速角点检测
    std::vector<cv::KeyPoint> keypoints;
    cv::FastFeatureDetector fast(40,true);
    fast .detect (image,keypoints);
    drawKeypoints(image,keypoints,image,cv::Scalar::all(255),cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);

二、具体Harris角点检测实现介绍

1、图像的梯度计算:
直接调用opencv的sobel算子进行滤波:

Ix:Sobel(img, dst, CV_64FC1, 0, 1, 3);
Iy:Sobel(img, dst, CV_64FC1, 1, 0, 3);

2、Ixx、Iyy、Ixy的计算及局部特征结果矩阵M的特征值和响应函数的值:
        通过第一步的大的Ix和Iy,分别遍历对应元素值进行相乘得到新的所需Mat,针对是否进行高斯的滤波(使用opencv库函数 GaussianBlur),设计两个计算的函数接口:

Gauss: Mat computeImage(Mat& ixx, Mat& iyy, Mat& ixy, int wsize);
NoGauss: Mat computeImage(Mat& ix, Mat& iy, int wsize, int para);

两种的Harris检测主要框架代码如下:

//使用全一的窗口函数
void myHarrisCorner_ave(Mat &srcImg) {
    Mat image,src_grayImg,Ix,Iy,I_xx,I_yy,I_xy,R,filter_R,result;
    cvtColor(srcImg, src_grayImg, COLOR_BGR2GRAY);
    image = srcImg.clone();
    
    int wsize = 3;//窗口大小
    sobelGradient(src_grayImg, Ix,1);
    sobelGradient(src_grayImg,Iy, 2);
    I_xx = computeImage(Ix, Iy, wsize, 1);
    I_yy = computeImage(Ix, Iy, wsize, 2);
    I_xy = computeImage(Ix, Iy, wsize, 4);
    //计算响应值
R = computeImage(Ix, Iy, wsize, 3);
//局部非极大值抑制
    filter_R = filterR(R, 10);
    mixP(filter_R, image, 2);
    imshow("Ave", image);
    imwrite("myHarris_Ave05.jpg", image);
}
//使用高斯平滑
void myHarrisCorner_Gauss(Mat &srcImg) {
    Mat image, src_grayImg, Ix, Iy, I_xx, I_yy, I_xy, R, filter_R, result;
    cvtColor(srcImg, src_grayImg, COLOR_BGR2GRAY);
    image = srcImg.clone();
    int wsize = 3;//窗口大小
    sobelGradient(src_grayImg, Ix, 1);
    sobelGradient(src_grayImg, Iy, 2);
    I_xx = computeImage(Ix, Iy, wsize, 1);
    GaussianBlur(I_xx, I_xx, Size(3, 3), 0, 0);
    I_yy = computeImage(Ix, Iy, wsize, 2);
    GaussianBlur(I_yy, I_yy, Size(3, 3), 0, 0);
    I_xy = computeImage(Ix, Iy, wsize, 4);
    GaussianBlur(I_xy, I_xy, Size(3, 3), 0, 0);
    //计算响应值
    R = computeImage(I_xx, I_yy,I_xy, wsize);
//局部非极大值抑制
    filter_R = filterR(R, 10);
    //显示结果
    mixP(filter_R, image, 2);
    imshow("Gauss", image);
    imwrite("myHarris_gauss05.jpg", image);

三、四种方法的结果对比分析

        对于opencv自带的Harris角点检测、改进的Shi-Tomasi角点检测、FAST角点检测算法、自己实现的Harri的使用高斯平滑以及不使用的五种输入同样的测试图片结果如下,每一种都调好参数后便固定不变测试对于不同大小角度的图片:(图片顺序为:①Fast、②Harris(opencv)、③myHarris(noGauss)、④myHarris(Gauss)、⑤ST)

1、第一组分辨率:692*910
image.png
image.png

image.png
image.png

image.png
2、第二组分辨率:240*319
image.png
image.png
image.png

image.png
image.png
3、第三组:340*256(翻转)
image.png
image.png

image.png
image.png

image.png
4、第四组:480*316
image.png

image.png

image.png

image.png

image.png

小结:

        通过对上诉几组图片结果的观察发现,其中Shi-Tomasi的效果应该是最好的,角点标记的很全面,而且没有像Harris那样阈值很难调节,对不同图片变化很大(使用高斯的阈值大概为10^12很大!),而Fast得有点就在于简单速度快,但是精准不够,opencv库内的Harris角点检测个人感觉很难用,阈值很难调,而且可能是为了不检测出错,检测出来的角点数量比较少,效果不是很好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容