我正在尝试实现高斯模糊,我根据维基百科生成了高斯滤波器:
void FilterCreation(double GKernel[][5])
{
// intialising standard deviation to 1.0
double sigma = 1.0;
double r, s = 2.0 * sigma * sigma;
// sum is for normalization
double sum = 0.0;
// generating 5x5 kernel
for (int x = -2; x <= 2; x++) {
for (int y = -2; y <= 2; y++) {
r = sqrt(x * x + y * y);
GKernel[x + 2][y + 2] = (exp(-(r * r) / s)) / (M_PI * s);
sum += GKernel[x + 2][y + 2];
}
}
// normalising the Kernel
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
GKernel[i][j] /= sum;
}
如果我正确理解了如何以高斯模糊对图像进行卷积,那么我将获取像素并获取周围的像素,将每个像素乘以内核值并将其求和。例如:
kernel matrix
1 2 3 1 2 3 4 5
4 5 6 6 7 8 9 10
7 8 9 11 12 13 14 15
如果我选择矩阵中的值为7
的像素(它的索引为(1,1)),则卷积看起来像:
new_matrix(1,1) = ( 1 * 1 ) + ( 2 * 2 ) + ( 3 * 3 )
( 4 * 6 ) + ( 5 * 7 ) + ( 6 * 8 )
( 7 * 11 ) + ( 8 * 12 ) + ( 9 * 13 )
,并针对我可以使用的每个像素(因此我不能从第一行或最后一行/列中提取像素)执行此操作:
void CreateGaussFilter(int kernalHeight, int kernalWidth, double kernalArray[5][5]){
Mat image = imread("konik.jpg");
Mat filter(image.size(),CV_8UC1);
int rows=image.rows;
int cols=image.cols;
int verticleImageBound=(kernalHeight-1)/2;
int horizontalImageBound=(kernalWidth-1)/2;
for(int row=0+verticleImageBound;row<rows-verticleImageBound;row++){
for(int col=0+horizontalImageBound;col<cols-horizontalImageBound;col++){
float value=0.0;
for(int kRow=0;kRow<kernalHeight;kRow++){
for(int kCol=0;kCol<kernalWidth;kCol++){
float pixel=image.at<uchar>(kRow+row-verticleImageBound,kCol+col-horizontalImageBound)*kernalArray[kRow][kCol];
value+=pixel;
}
}
filter.at<uchar>(row,col)=cvRound(value);
}
}
imwrite("myFilter.jpg",filter);
}
现在,我使用的图像是:
结果图像为:
正如您所看到的,它缩小了图像,我省略了前两行和后两列,但是仍然不应该有这种区别……我是否误解了如何进行卷积?还是我的代码中有任何错误?我没有发现任何错误。
感谢帮助