一、概述
案例:使用cornerHarris实现角点检测,并调节其参数看看不同参数下的不同效果
技术:Qt+C+++OpenCV
角点检测函数介绍:
cornerHarris(src,dst,blockSize,ksize,k,BORDER_DEFAULT)
1.src:必须是单通道8位或者32位浮点图像
2.dst:存储角点结果图像,它的格式是CV_32FC1,图像大小和原图大小一致
3.blockSize:扫描窗口的大小,ps:此值越大检测到的结果越多
4.ksize:Sobel算子的大小,四邻域、八邻域等,此值越大检测结果越多
5.k:此值是个经验值一般只用0.04,其取值区间是0.04~0.06之间
实现角点检测的步骤:
1.载入图像
2.将图像转为灰度图,因为cornerHarris的输入只能是8位或者32位的灰度图像
3.执行角点检测,并将检测到的结果输出到dst中
4.将检测到的值归一化到0~255之间,因为输出图像dst检测到的值是浮点数
5.将归一化后的图像像素值取绝对值,因为归一化后的图像有可能是负数
6.标定阀值,并循环输出图像,如果像素大于阀值就说明是角点(绘制出来),小于就直接舍弃
实验结果(同等条件下):
1.blockSize越大检测到的角点就越多
2.k的值越大检测到的角点越多
3.ksize的值越大检测到的角点越多
4.thresh阀值越大可用角点越少,越大可用角点也就越多
其中前三个值大道一定程度的时候全屏幕都是角点,非常不准确,需要根据实际的图像情况实时的调节自己的参数。
二、代码示例
src = imread(filePath); if(src.empty()){ cout << "图片不能为空"<<endl; return; } // imshow("src",src); cvtColor(src,gray,COLOR_BGR2GRAY); // imshow("gray",gray); Mat dst,norm_dst, normScaleDst; cornerHarris(gray,dst,blockSize,ksize,k,BORDER_DEFAULT);//dst输出参数一般32位浮点 //将dst数据归一化到0~255之间 normalize(dst,norm_dst,0,255,NORM_MINMAX, CV_32FC1, Mat()); // imshow("normalize",norm_dst); //取绝对值 convertScaleAbs(norm_dst,normScaleDst); resultImg = src.clone(); for (int row = 0; row < resultImg.rows; row++) { uchar * currentRow = normScaleDst.ptr(row); for (int col = 0; col < resultImg.cols; col++) { int value = (int)*currentRow; if(value>thresh){ circle(resultImg,Point(col,row),2,Scalar(0,0,255),2,LINE_8,0); } currentRow++;//用指针速度快 } }
三、示例图片(图片上的红色小圆就是绘制出来的角点)