[opencv]goodFeaturesToTrack函数详细注释
来源:互联网 发布:外汇模拟软件下载 编辑:程序博客网 时间:2024/05/22 10:51
本文全篇转自 http://blog.csdn.net/xdfyoga1/article/details/44175637
OpenCV中的goodFeaturesToTrack函数可以计算Harris角点和shi-tomasi角点,但默认情况下计算的是shi-tomasi角点,函数原型如下:
- void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
- int maxCorners, double qualityLevel, double minDistance,
- InputArray _mask, int blockSize,
- bool useHarrisDetector, double harrisK )
_image:8位或32位浮点型输入图像,单通道
_corners:保存检测出的角点
maxCorners:角点数目最大值,如果实际检测的角点超过此值,则只返回前maxCorners个强角点
qualityLevel:角点的品质因子
minDistance:对于初选出的角点而言,如果在其周围minDistance范围内存在其他更强角点,则将此角点删除
_mask:指定感兴趣区,如不需在整幅图上寻找角点,则用此参数指定ROI
blockSize:计算协方差矩阵时的窗口大小
useHarrisDetector:指示是否使用Harris角点检测,如不指定,则计算shi-tomasi角点
harrisK:Harris角点检测需要的k值
goodFeaturesToTrack函数的定义在imgproc文件的featureselect.cpp中,下面给出了goodFeaturesToTrack函数的详细注释。
- 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(), mask = _mask.getMat();
-
- CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
- CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
-
- Mat 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();
-
- vector<const float*> tmpCorners;
-
-
- 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);
- }
- }
-
-
-
-
- sort( tmpCorners, greaterThanPtr<float>() );
- vector<Point2f> corners;
- size_t i, j, total = tmpCorners.size(), ncorners = 0;
-
-
- if(minDistance >= 1)
- {
-
- int w = image.cols;
- int h = image.rows;
-
- const int cell_size = cvRound(minDistance);
-
-
- const int grid_width = (w + cell_size - 1) / cell_size;
- const int grid_height = (h + cell_size - 1) / cell_size;
-
- std::vector<std::vector<Point2f> > grid(grid_width*grid_height);
-
- minDistance *= minDistance;
-
- for( i = 0; i < total; i++ )
- {
- int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
- int y = (int)(ofs / eig.step);
- int x = (int)((ofs - y*eig.step)/sizeof(float));
-
- bool good = true;
-
- int x_cell = x / cell_size;
- int y_cell = y / cell_size;
-
- int x1 = x_cell - 1;
- int y1 = y_cell - 1;
- int x2 = x_cell + 1;
- int y2 = y_cell + 1;
-
-
- x1 = std::max(0, x1);
- y1 = std::max(0, y1);
- x2 = std::min(grid_width-1, x2);
- y2 = std::min(grid_height-1, y2);
-
-
- for( int yy = y1; yy <= y2; yy++ )
- {
- for( int xx = x1; xx <= x2; xx++ )
- {
- vector <Point2f> &m = grid[yy*grid_width + xx];
-
- if( m.size() )
- {
- for(j = 0; j < m.size(); j++)
- {
- float dx = x - m[j].x;
- float dy = y - m[j].y;
-
- if( dx*dx + dy*dy < minDistance )
- {
- good = false;
- goto break_out;
- }
- }
- }
- }
- }
-
- break_out:
-
- if(good)
- {
-
-
- grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
-
- corners.push_back(Point2f((float)x, (float)y));
- ++ncorners;
-
- if( maxCorners > 0 && (int)ncorners == maxCorners )
- break;
- }
- }
- }
- else
- {
- for( i = 0; i < total; i++ )
- {
- int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
- int y = (int)(ofs / eig.step);
- int x = (int)((ofs - y*eig.step)/sizeof(float));
-
- corners.push_back(Point2f((float)x, (float)y));
- ++ncorners;
- if( maxCorners > 0 && (int)ncorners == maxCorners )
- break;
- }
- }
-
- Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }