为什么写这个,因为面试官问到了,但是由于我好长时间没看这一块了,忘了具体的原理了(没错,我就是健忘),现在回学校了,有时间再把这个基础概念来理解一下。
harris2D
讲这一块知识的 有很多 博客:https://blog.youkuaiyun.com/qq_41598072/article/details/83651629
这里关于实对称矩阵M 有个重要的参数 梯度(水平和竖直)
Mat dx, dy;
Sobel(src, dx, CV_32F, 1, 0, kSize, scale, 0);
Sobel(src, dy, CV_32F, 0, 1, kSize, scale, 0);
// 求解水平与竖直梯度
for (i = 0; i < size.height; i++){
float *covData = (float*)(cov.data + i*cov.step);
const float *dxData = (const float*)(dx.data + i*dx.step);
const float *dyData = (const float*)(dy.data + i*dy.step);
for (j = 0; j < size.width; j++)
{
float dx_ = dxData[j];
float dy_ = dyData[j];
covData[3 * j] = dx_*dx_;
covData[3 * j + 1] = dx_*dy_;
covData[3 * j + 2] = dy_*dy_;
}
}
由此可以计算得到 特征值。
在计算角点响应函数:
代码计算:
for (i = 0; i < size.height; i++)
{
// 获取图像矩阵指针
float *resultData = (float*)(result.data + i*result.step);
const float *covData = (const float*)(cov.data + i*cov.step);
for (j = 0; j < size.width; j++)
{
// 焦点响应生成
float a = covData[3 * j];
float b = covData[3 * j + 1];
float c = covData[3 * j + 2];
resultData[j] = a*c - b*b - k*(a + c)*(a + c);
}
}
最后设置阈值选择角点:
for (int j = 0; j < result.rows; j++)
{
for (int i = 0; i < result.cols; i++)
{
if ((int)(result.at<uchar>(j, i)) > 150)
{
circle(srcImage, Point(i, j), 5, Scalar(0), 2, 8, 0);
}
}
}
harris3d
这一块要结合pcl的源码来分析,其实原理是非常的类似的:
二维的梯度,在三维可以替代成 rgbd \ 雷达强度 \ 以及曲面函数的形式。
首先也是梯度(pcl 这里是法线)的计算,代码如下:
for (std::vector<int>::const_iterator iIt = neighbors.begin(); iIt != neighbors.end(); ++iIt)
{
if (pcl_isfinite (normals_->points[*iIt].normal_x))
{
coefficients[0] += normals_->points[*iIt].normal_x * normals_->points[*iIt].normal_x;
coefficients[1] += normals_->points[*iIt].normal_x * normals_->points[*iIt].normal_y;
coefficients[2] += normals_->points[*iIt].normal_x * normals_->points[*iIt].normal_z;
coefficients[5] += normals_->points[*iIt].normal_y * normals_->points[*iIt].normal_y;
coefficients[6] += normals_->points[*iIt].normal_y * normals_->points[*iIt].normal_z;
coefficients[7] += normals_->points[*iIt].normal_z * normals_->points[*iIt].normal_z;
++count;
}
}
响应函数的计算:
float trace = covar [0] + covar [5] + covar [7];
if (trace != 0)
{
float det = covar [0] * covar [5] * covar [7] + 2.0f * covar [1] * covar [2] * covar [6]
- covar [2] * covar [2] * covar [5]
- covar [1] * covar [1] * covar [7]
- covar [6] * covar [6] * covar [0];
output [pIdx].intensity = 0.04f + det - 0.04f * trace * trace;
}
当然pcl 中有很多的响应函数。我没有一个个的看