二维高斯函数数学公式如下:
(u1是原点x坐标)
(u2是原点y坐标)
是各个点所占的权重,在图像处理中,一般u1,u2是远点坐标。
例如当sigma=1时,可得权重去下:
[0.36787945, 0.60653067, 0.36787945;
0.60653067, 1, 0.60653067;
0.36787945, 0.60653067, 0.36787945]
这里只是各个点所占权重,还需要将该权重映射到具体像素值上,这里只需要用对应坐标上像素与对应位置上的权重做乘积求和作为原点的当前像素值。
Cpp代码如下:
Mat Gass_Kernel(float sigma)
{
Mat Kernel = Mat(Size(3, 3), CV_32FC1);
float val_sum = 0.f;
for (int i=0;i<3;i++)
for (int j = 0; j < 3; j++)
{
float val = exp(-((i - 3/2)*(i - 3/2) + (j - 3/2)*(j - 3/2)) / (2 * sigma*sigma));
Kernel.at<float>(i, j) = val;
val_sum += val;
}
cout << Kernel << endl;
cout << val_sum << endl;
for (int i = 0; i<3; i++)
for (int j = 0; j < 3; j++)
{
Kernel.at<float>(i, j) = Kernel.at<float>(i, j)/ val_sum;
}
return Kernel;
}
用上述代码计算道德filter_kernel做卷积,提取图像特征。
Mat Conv(Mat &map, Mat & kernel)
{
int new_h =int((map.rows - kernel.rows)/1)+1;
int new_w= int((map.cols - kernel.cols) /1) + 1;
Mat new_mat = Mat(Size(new_h, new_w), map.depth());
for (int i = 1; i < map.rows-1; i++)
{
for (int j = 1; j < map.cols - 1; j++)
{
//卷积计算
float value = 0.f;
for (int k_i=-1 ;k_i<=1 ;k_i++)
for (int k_j = -1; k_j <= 1; k_j++)
{
value += kernel.at<uchar>(k_i + 1, k_j + 1)*map.at<uchar>(i + k_i, j + k_j);
}
new_mat.at<uchar>(i, j) = uchar(value);
}
}
return new_mat;
}