本文主要是介绍【第二部分 图像处理】第3章 Opencv图像处理进阶【6角点检测 B】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
6.2 Shi-Tomasi角点检测
6.2.1 Shi-Tomasi角点检测概述及原理
Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。
参考论文:hi and C. Tomasi. Good Features to Track. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994.(见笔者附件)
6.2.2 Shi-Tomasi角点检测:goodFeaturesToTrack()函数
goodFeaturesToTrack()函数讲解
C++: 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 )
【参数】
第一个参数,image – Input 8-bit or floating-point 32-bit, single-channel image.
第二个参数,eigImage – The parameter is ignored.
第三个参数,tempImage – The parameter is ignored.
第四个参数,corners – Output vector of detected corners.
第五个参数,maxCorners – Maximum number of corners to return. If there are more corners than are found, the strongest of them is returned.
第六个参数,qualityLevel – Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue (see cornerMinEigenVal() ) or the Harris function response (see cornerHarris() ). The corners with the quality measure less than the product are rejected. For example, if the best corner has the quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure less than 15 are rejected.
第七个参数,minDistance – Minimum possible Euclidean distance between the returned corners.
mask – Optional region of interest. If the image is not empty (it needs to have the type CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected.
第八个参数,blockSize – Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See cornerEigenValsAndVecs() .
useHarrisDetector – Parameter indicating whether to use a Harris detector (see cornerHarris()) or cornerMinEigenVal().
第九参数,k – Free parameter of the Harris detector.
goodFeaturesToTrack()函数源代码
/*【goodFeaturesToTrack ( )源代码】***************************************************** @Version:OpenCV 3.0.0(Opnencv2和Opnencv3差别不大,Linux和PC的对应版本源码完全一样,均在对应的安装目录下) * @源码路径:…\opencv\sources\modules\imgproc\src\ featureselect.cpp* @起始行数:265行
********************************************************************************/
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,int maxCorners, double qualityLevel, double minDistance,InputArray _mask, int blockSize,bool useHarrisDetector, double harrisK )
{CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );CV_Assert( _mask.empty() || (_mask.type() == CV_8UC1 && _mask.sameSize(_image)) );CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(),ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,_mask, blockSize, useHarrisDetector, harrisK))Mat image = _image.getMat(), eig, tmp;if (image.empty()){_corners.release();return;}if( useHarrisDetector )cornerHarris( image, eig, blockSize, 3, harrisK );elsecornerMinEigenVal( 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 imageMat 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 gridsint 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.ptr());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;// boundary checkx1 = 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++ ){std::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.ptr());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);
}
6.2.3 Shi-Tomasi角点检测实例
代码参看附件【demo1】。
通过滑动滑动条可以改变角点数量。
参考:
中文
英文
本章参考附件
点击进入
这篇关于【第二部分 图像处理】第3章 Opencv图像处理进阶【6角点检测 B】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!