欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv学习笔记二十五:Harris角点检测

程序员文章站 2022-06-11 17:13:10
...

haaris角点检测在一个或者是两个相机进行标定的时候常常用到,Opencv和matlab中都有现成的命令和程序。

角点的位置就是图像中在x和y方向变化都很大的那个交点处。为了找到那些角点需要进行以下步骤的计算。

opencv学习笔记二十五:Harris角点检测

 一、获取输入图像image的x和y方向的边缘图像。

      方法是,用x和y方向的一阶滤波算子dx和dy(或者是二阶滤波算子dx和dy)对图像进行滤波。

      其中x方向的一阶滤波算子一般取为dx=[-1,0,1];x方向的二阶滤波算子一般取为dx=[--2,1,0,1,2];

             y方向的一阶滤波算子一般取为dy=[-1;0;1];y方向的二阶滤波算子一般取为dy=[--2;1;0;1;2];

       滤波函数用filter2(),边缘图像Ix=filter2(dx,image);Iy=filter2(dy,image);其中dx,dy为滤波算子,image为要进行滤波的图像.

二、计算角点量。

初始化角点量,并进行离散高斯滤波。

opencv学习笔记二十五:Harris角点检测

(M为图像中像素点的黑塞矩阵)

并用高斯算子对M进行二维离散滤波,高斯算子如下:

opencv学习笔记二十五:Harris角点检测

 

高斯算子通过gauss=fspecial('gaussian',[5 5],2)设置[5 5]为算子窗口大小,2为算子的:

gauss =

    0.0232    0.0338    0.0383    0.0338    0.0232
    0.0338    0.0492    0.0558    0.0492    0.0338
    0.0383    0.0558    0.0632    0.0558    0.0383
    0.0338    0.0492    0.0558    0.0492    0.0338
    0.0232    0.0338    0.0383    0.0338    0.0232

滤波是对图像每个像素点对应的M中各个元素进行滤波:


Ix2=filter2(gauss,Ix2);
Iy2=filter2(gauss,Iy2);
Ixy=filter2(gauss,Ixy);

然后计算各个像素点的角点量R,R为正值是,检测到的是角点,R为负时检测到的是边,R很小时检测到的是平坦区域:

opencv学习笔记二十五:Harris角点检测

或者

opencv学习笔记二十五:Harris角点检测

其中k取0.04~0.06常用

三、获取全局最大角点量值,设置阈值,并求局部最大角点量值也即进行非最大值抑制。

Rmax= max(R(i,j))

阈值thresh=th*Rmax,th取值越大角点越少,th越小角点越多。

非最大值抑制的方法是,取窗口内最大值,窗口可取3x3大小。

四、在图片上画出角点位置。当R(i,j)大于阈值且是局部最大值时就认为是角点处。

以上摘自该篇博客:https://blog.csdn.net/x_r_su/article/details/52680712

API函数:

cornerHarris(InputArray src,OutputArray dst, int blockSize, int ksize, double k, intborderType=BORDER_DEFAULT )

参数解释:

  • 第一个参数,InputArray类型的src,源图像且需为单通道8位或者浮点型图像。
  • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的blockSize,表示邻域的大小,对于每一个像素(x,y)在blockSize*blockSize 邻域内,计算2x2梯度的协方差矩阵。
  • 第四个参数,int类型的ksize,表示Sobel()算子的模板大小。
  • 第五个参数,double类型的k,Harris参数,常取0.04~0.06。
  • 第六个参数,int类型的borderType,图像像素的边界模式,注意它有默认值BORDER_DEFAULT。
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int thresh = 80;
Mat src, dst,norm_dst,gray_img,abs_dst,out1,out2;
void callback(int, void*);
int main(int arc, char** argv)
{	
	src = imread("1.jpg");
	namedWindow("input",CV_WINDOW_AUTOSIZE);
	imshow("input", src);
    cvtColor(src, gray_img, CV_BGR2GRAY);

	namedWindow("output", CV_WINDOW_AUTOSIZE);
	createTrackbar("threshold", "output", &thresh, 255, callback);
	callback(0, 0);
	waitKey(0);
	return 0;
}
void callback(int, void*) {
	dst = Mat::zeros(gray_img.size(), CV_32FC1);
	out1 = Mat::zeros(gray_img.size(), CV_32FC1);

	cornerHarris(gray_img, dst, 2, 3, 0.04);
	normalize(dst, norm_dst, 0, 255, NORM_MINMAX, CV_32FC1,Mat());
	convertScaleAbs(norm_dst, abs_dst);//?

	Mat result_img = src.clone();
	for (int i = 0; i < result_img.rows; i++) {
		for (int j = 0; j < result_img.cols; j++) {
			uchar value = abs_dst.at<uchar>(i, j);
			if (value > thresh) {
				circle(result_img, Point(j, i),1,Scalar(0,255,0),2);
			}
		}
	}
	imshow("output", result_img);
}

运行结果如下:

opencv学习笔记二十五:Harris角点检测

opencv学习笔记二十五:Harris角点检测opencv学习笔记二十五:Harris角点检测

相关标签: harris角点检测