一、理论
1.1 角点、边缘、团块
- 边缘(edge)
- 团块(flat)
- 角点(corner)
1.2 Harris算法思想
思想是用小窗口在图像上平移,如果窗口内像素:
- 沿任意方向变化不明显(flat)
- 沿某一方向变化不明显(edge)
- 沿任意方向明显变化(corner)
1.3 Harris算法实现
-
移动区域前后对应位置差的平方
其中 W为权重,x,y为移动方向,u,v为在x,y上的偏移量
-
一阶泰勒展开
-
将2代入1,化简
-
将M代入
其中:
-
n阶实对称矩阵A必有n个线性不相关特征向量,则M可以转换为
二次项函数本质上就是一个椭圆函数。椭圆的扁率和尺寸是由M(x,y)的特征值λ1、λ2决定的,椭贺的方向是由M(x,y)的特征矢量决定的,如下图所示,椭圆方程为:
[Δx,Δy]M(x,y)[ΔxΔy]=1
- 因此有三种情况
图像中的直线。一个特征值大,另一个特征值小,λ1≫λ2或λ2≫λ1。自相关函数值在某一方向上大,在其他方向上小。
图像中的平面。两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。
图像中的角点。两个特征值都大,且近似相等,自相关函数在所有方向都增大。
- 即以下公式
R 约等于 0 平坦区
R 大于 0 角点
R 小于 0 边缘
二、 效果
2.1 原图
2.2 Harris 不做极大值抑制
绿色为边缘,红色为角点
2.3 Harris 极大值抑制
三、代码
// 1. 读取原图
var imgO = CvInvoke.Imread("WB.png");
var imgO1 = imgO.ToImage<Bgr, byte>();
CvInvoke.Imshow("imgO",imgO);
// 2. 灰度
var imgGray = CvInvoke.Imread("WB.png", 0);
CvInvoke.Imshow("imgGray", imgGray);
// 3. harris
Mat harrisResponse = new Mat();
CvInvoke.CornerHarris(imgGray,harrisResponse,2,3,0.04);
// 4. 求取最大值,最小值
double minValue=0, maxValue=0;
Point minLoc = new Point();
Point MaxLoc = new Point();
CvInvoke.MinMaxLoc(harrisResponse,ref minValue,ref maxValue,ref minLoc,ref MaxLoc);
// 5. 极大值抑制
Matrix<float> matrix = new Matrix<float>(imgGray.Size);
harrisResponse.CopyTo(matrix);
for (int i = 0; i < matrix.Rows; i++) {
for (int j = 0; j < matrix.Cols; j++) {
if (matrix[i, j] > maxValue*0.001) {
imgO1[i,j] = new Bgr(0,0,255);
}
if (matrix[i, j] < minValue*0.1)
{
imgO1[i, j] = new Bgr(0, 255, 0);
}
}
}
CvInvoke.Imshow("imgO1", imgO1);
CvInvoke.WaitKey(0);