如何解决C ++中的2D阵列高斯模糊函数有什么问题?
我正在为应该表示图像的2D数组制作一个简单的高斯模糊函数。该函数仅在最后打印出数组值(此处不进行任何实际的图像处理)。我非常确定自己已正确执行了所有操作,但是我得到的值(N = 3,sigma = 1.5)大大低于基于此计算器的预期值:http://dev.theomader.com/gaussian-kernel-calculator/
我遵循以下等式:
void gaussian_filter(int N,double sigma) {
double k[N][N];
for(int i=0; i<N; i++) { //Initialize kernal to 0
for(int j=0; j<N; j++) {
k[i][j] = 0;
}
}
double sum = 0.0; //There is an issue somewhere in this block of code
int change = (N/2);
double r,s = change * sigma * sigma;
for (int x = -change; x <= change; x++) {
for(int y = -change; y <= change; y++) {
r = sqrt(x*x + y*y);
k[x + change][y + change] = (exp(-(r*r)/s))/(M_PI * s);
sum += k[x + change][y + change];
}
}
for(int i = 0; i < N; ++i) { //Normalize
for(int j = 0; j < N; ++j) {
k[i][j] /= sum;
}
}
for(int i = 0; i < N; ++i) { //Print out array
for (int j = 0; j < N; ++j)
cout<<k[i][j]<<"\t";
}
cout<<endl;
}
}
解决方法
为什么s
依赖change
?我认为您应该这样做:
double r,s = 2 * sigma * sigma;
// instead of
// double r,s = change * sigma * sigma;
,
That website以一种非正统的方式计算高斯核:
通过对每个离散核抽头上的连续高斯分布进行数值积分来计算权重。
也就是说,它采样了一个连续的高斯核,该核已与一个1像素宽的均匀(“框”)滤镜卷积。结果高斯比广告更宽。我建议不要使用这种方法。
创建高斯内核的正确方法是仅在给定的整数位置(例如x = [-3,-2,-1,1,2,3]
)采样高斯函数。
请注意,一个3像素的内核不足以表示高斯。采样曲线的尾部非常重要,如果没有它,内核将不具有高斯内核的良好特性。我建议每边最多采样3 sigma,以产生2*ceil(3*sigma)+1
像素。 2 sigma是最基本的最小值,仅在速度比好的结果更重要时才有用。
还要注意,高斯是可分离的,您可以连续应用两个1D内核,而不是一个2D内核。对于9x9内核,您获得sigma = 1.5,这相当于9 + 9 = 18乘法和加法,而2D内核为9x9 = 81。这是一笔可观的节省!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。