计算机视觉(2)——图像检测

本文介绍了学习opencv图像检测的知识
主要有FAST与HARRIS,图像的匹配与测距
代码部分只展示FAST,HARRIS,图像的匹配
文章开头,借学长照片一用

https://img-blog.csdn.net/20161128000624391

背景知识:

一、FAST
在FAST特质点的检测是根据角点来判断的,什么是角点?“如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们就把它称之为角点”,通俗的讲是在这一点的灰度值与其他地方有很大的区别,我们就是通过这样的点去判断。
一般情况下我们会检测周围16个点(半径为3的膨胀)是否与该点有很大的区别来判断该点是否是角点,如图:
https://img-blog.csdn.net/20161127231724862
但是为了效率,我们通常只比较4个点,同时循环也是从i=3开始的(下面代码会有介绍)

实验证明,比较9个点是最有效率的。
二、HARRIS
对于HARRIS特质点检测而言,检测的对象是“方块”,同样如果这个“方块”左右移动灰度值改变非常大,那么这就是你找的点。如图:
https://img-blog.csdn.net/20161127233712119)
R=det(M)-k*(trace(M)^2)

详情代码:

一、FAST

//判断两点灰度值的差距大小
bool isdif(uchar a, uchar b)
{
    if (abs(a - b)<30)
    {
        return false;
    }
    else
    {
        return true;
    }

}
VideoCapture cap(0);

    while (true)
    {
        Mat frame;
        cap >> frame;

        /*
        fast
        */
        Mat frame_rgb;
        frame.copyTo(frame_rgb);
        //FAST是对灰度图检测的
        cvtColor(frame, frame, CV_64FC1);
        //cout<<frame.at<uchar>(0,0);

        //FAST 角点检测

        int pos[4][2];
        //初始化FAST检测的四个位置
        pos[0][0] = 0;
        pos[0][1] = -3;
        pos[1][0] = 3;
        pos[1][1] = 0;
        pos[2][0] = 0;
        pos[2][1] = 3;
        pos[3][0] = -3;
        pos[3][1] = 0;
        //由于检测角点是用圆来判断,所以i从3开始循环
        for (int i = 3; i<frame.rows - 3; i++)
        {
            for (int j = 3; j<frame.cols - 3; j++)
            {
                int num = 0;
                uchar cen = frame.at<uchar>(i, j);
                for (int k = 0; k<4; k++)
                {
                    //
                    uchar temp = frame.at<uchar>(i + pos[k][0], j + pos[k][1]);
                    //如果cen与temp差距很大,就加入其中,num是代表4个位置检查比较相差比较大的位置数量
                    if (isdif(cen, temp))
                    {
                        num++;
                    }
                }
                //如果num是1 3 4,表示该点是角点,画出该点
                if ((num == 1) || (num == 3) || (num == 4))
                {
                    //画圆
                    circle(frame_rgb, cvPoint(j, i), 2, CV_RGB(255, 0, 0), 2);
                }
            }
        }

二、HARRIS

for (int i = 1; i < frame.rows - 1; i++)
        {
            for (int j = 1; j < frame.cols - 1; j++)
            {
                double IX, IY;
                //求导
                IX = frame.at<uchar>(i, j - 1) - frame.at<uchar>(i, j + 1);
                IY = frame.at<uchar>(i - 1, j) - frame.at<uchar>(i + 1, j);

                double R = IX*IX*IY*IY - 0.1*(IX*IX + IY*IY);
                //R=x*x*y*y-k*(x*x-y*y),原理是一个矩阵的值
                //k越大抑制越大
                cout << R << endl;
                if (R>10000)
                {
                    circle(frame_rgb, cvPoint(j, i), 1, CV_RGB(255, 0, 0));
                    //CV_RGB(255,0,0)代表最红的颜色,红色 绿色 蓝色
                }
            }
        }

三、API调用HARRIS

        Mat con;
        Mat cornerStrength;
        Mat frame_gray=frame.clone();

        cornerHarris(frame_gray, cornerStrength, 2, 3, 0.1);
        Mat harrisCorner;
        //进行二值化
        threshold(cornerStrength, harrisCorner, 0.000001, 255, THRESH_BINARY);
        imshow("角点检测后的二值效果图", harrisCorner);
        //二值化增强图片显示效果,将阈值设置成0或者255

        imshow("【原灰度图】", frame);
        imshow("【二值化HARRIS图】", frame_rgb);
        waitKey(10);
总结:
    自从入了opencv的坑,我发现自己的数学功底十分欠缺,之前学的线性代数,高数都是一些小儿科的东西,如果要想学好opencv,数学是非常关键的。虽千万人吾往矣!

ps:

图像的测距我没有贴出代码块。以上都是我自己的学习体会以及自己的理解,如果想要更加了解以上内容,请参考一下博客:

    FAST特征点检测

http://blog.csdn.net/yang_xian521/article/details/7411438

    HARRIS角点估计

http://blog.csdn.net/crzy_sparrow/article/details/7391511

    HARRIS的API调用

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

    代码文件及ppt

http://download.csdn.net/detail/typedef_dc/9695210

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值