Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步优化(1920*1080测试图11ms处理完成)。...

  搜索到某个效果很好的视频去燥的算法,感觉效果比较牛逼,就是速度比较慢,如果能做到实时,那还是很有实用价值的。于是盲目的选择了这个课题,遇到的第一个函数就是角点检测,大概六七年用过C#实现过Harris角点以及SUSAN角点。因此相关的理论还是有所了解的,不过那个时候重点在于实现,对于效率没有过多的考虑。

  那个代码里使用的Opencv的函数叫 goodFeaturesToTrack, 一开始我还以为是个用户自定义的函数呢,在代码里就根本没找到,后面一搜原来是CV自带的函数,其整个的调用为:

      goodFeaturesToTrack(img0Gray, featurePtSet0, 10000, 0.05, 5);

  这个的意思是从img0Gray图像中,找到10000个角点,角点之间的最小距离是5,使用Shi-Tomasi角点检测算子。

  我们查看了下Opencv的代码,写的不是很复杂,但是我是想对一副1920*1080的视频进行去燥,尝试了下仅仅运行goodFeaturesToTrack其中的一个子函数cvCornerHarris,大概就需要50多毫秒。这怎么玩的下去啊。 

   CV里关于这个函数的代码位于:Opencv 3.0\opencv\sources\modules\imgproc\src\featureselect.cpp中,为了节省篇幅,我删除其一些辅助性的代码和检测,大概就是如下所示:

void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
                              int maxCorners, double qualityLevel, double minDistance,
                              InputArray _mask, int blockSize,
                              bool useHarrisDetector, double harrisK )
{
    Mat image = _image.getMat(), eig, tmp;
    if( useHarrisDetector )
        cornerHarris( image, eig, blockSize, 3, harrisK );
    else
        cornerMinEigenVal( image, eig, blockSize, 3 );
    double maxVal = 0;
    minMaxLoc( eig, 0, &maxVal, 0, 0, _mask );
    threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO );
    dilate( eig, tmp, Mat());
    Size imgsize = image.size();
    std::vector<const float*> tmpCorners;
    // collect list of pointers to features - put them into temporary image
    Mat mask = _mask.getMat();
    for( int y = 1; y < imgsize.height - 1; y++ )
    {
        const float* eig_data = (const float*)eig.ptr(y);
        const float* tmp_data = (const float*)tmp.ptr(y);
        const uchar* mask_data = mask.data ? mask.ptr(y) : 0;
        for( int x = 1; x < imgsize.width - 1; x++ )
        {
            float val = eig_data[x];
            if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )
                tmpCorners.push_back(eig_data + x);
        }
    }
    std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() );
    std::vector<Point2f> corners;
    size_t i, j, total = tmpCorners.size(), ncorners = 0;
    if (minDistance >= 1)
    {
         // Partition the image into larger grids
    }
    else
    {
       
    }
    Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
}

  先调用cornerHarris或者cornerMinEigenVal函数,得到初步的特征数据,后面的就是进行筛选,minMaxLoc

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值