高斯函数的结果不准确
Inaccurate result from gaussian function
我有这个高斯函数。这没有产生预期的结果。由于这个原因,图像无法正确模糊。在下面的代码中,我采用了内核大小(5)和 sigma 值(1),这与我在 link 下面。如果有人能指出问题,那将非常有帮助。
这是一个网站的 link Gaussian kernle link
public class KernelDemo {
public double[][] Calculate(int lenght, double weight) {
double[][] Kernel = new double[lenght][lenght];
double sumTotal = 0;
int kernelRadius = lenght / 2;
double distance = 0;
double calculatedEuler = 1.0 / (2.0 * Math.PI * Math.pow(weight, 2));
for (int filterY = -kernelRadius; filterY <= kernelRadius; filterY++) {
for (int filterX = -kernelRadius; filterX <= kernelRadius; filterX++) {
distance = ((filterX * filterX) + (filterY * filterY)) / (2 * (weight * weight));
Kernel[filterY + kernelRadius][filterX + kernelRadius] = calculatedEuler * Math.exp(-distance);
sumTotal += Kernel[filterY + kernelRadius][filterX + kernelRadius];
}
}
for (int y = 0; y < lenght; y++) {
for (int x = 0; x < lenght; x++) {
Kernel[y][x] = Kernel[y][x] * (1.0 / sumTotal);
}
}
return Kernel;
}
public static void main(String args[]) {
KernelDemo kd = new KernelDemo();
double terms[][];
terms = kd.Calculate(5,1);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.print(terms[i][j]);
}
System.out.println();
}
}
}
这就是我处理生成二维高斯分布核的方法。 Kernel
class 只是一个 double[][]
包装来执行某些规定(例如平方数组 5x5 7x7,并且还确保长度为奇数)
public static Kernel generateBlurKernel(int length, double std){
Kernel out = new Kernel(length);
int center = length/2;
for(int i=0;i<length;i++){
for(int j=0;j<length;j++){
int x = Math.abs(j-center);
int y = Math.abs(i-center);
out.setValueAt(j, i, ((1d/(2*Math.PI*std*std))*Math.pow(Math.E, -((x*x)+(y*y))/(2*std*std))));
}
}
out.normalize();
return out;
}
如果你想要,这也是我的 Kernel
class:
public class Kernel {
private final double[][] matrix;
public Kernel(int sidelength){
if((sidelength&1)==0)throw new IllegalArgumentException();
matrix = new double[sidelength][sidelength];
}
public double getValueAt(int x, int y){
return matrix[x][y];
}
public void setValueAt(int x, int y, double value){
matrix[x][y] = value;
}
public double sum(){
double sum = 0.0d;
for(double[] da:matrix){
for(double d:da){
sum+=d;
}
}
return sum;
}
public double[][] getFullKernal(){
return matrix;
}
public int getSideLegth(){
return matrix.length;
}
public void normalize(){
double normalizedConstant = 1d/sum();
for(int i=0;i<matrix.length;i++){
for(int j=0;j<matrix.length;j++){
matrix[i][j] = matrix[i][j]*normalizedConstant;
}
}
}
}
我有这个高斯函数。这没有产生预期的结果。由于这个原因,图像无法正确模糊。在下面的代码中,我采用了内核大小(5)和 sigma 值(1),这与我在 link 下面。如果有人能指出问题,那将非常有帮助。
这是一个网站的 link Gaussian kernle link
public class KernelDemo {
public double[][] Calculate(int lenght, double weight) {
double[][] Kernel = new double[lenght][lenght];
double sumTotal = 0;
int kernelRadius = lenght / 2;
double distance = 0;
double calculatedEuler = 1.0 / (2.0 * Math.PI * Math.pow(weight, 2));
for (int filterY = -kernelRadius; filterY <= kernelRadius; filterY++) {
for (int filterX = -kernelRadius; filterX <= kernelRadius; filterX++) {
distance = ((filterX * filterX) + (filterY * filterY)) / (2 * (weight * weight));
Kernel[filterY + kernelRadius][filterX + kernelRadius] = calculatedEuler * Math.exp(-distance);
sumTotal += Kernel[filterY + kernelRadius][filterX + kernelRadius];
}
}
for (int y = 0; y < lenght; y++) {
for (int x = 0; x < lenght; x++) {
Kernel[y][x] = Kernel[y][x] * (1.0 / sumTotal);
}
}
return Kernel;
}
public static void main(String args[]) {
KernelDemo kd = new KernelDemo();
double terms[][];
terms = kd.Calculate(5,1);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.print(terms[i][j]);
}
System.out.println();
}
}
}
这就是我处理生成二维高斯分布核的方法。 Kernel
class 只是一个 double[][]
包装来执行某些规定(例如平方数组 5x5 7x7,并且还确保长度为奇数)
public static Kernel generateBlurKernel(int length, double std){
Kernel out = new Kernel(length);
int center = length/2;
for(int i=0;i<length;i++){
for(int j=0;j<length;j++){
int x = Math.abs(j-center);
int y = Math.abs(i-center);
out.setValueAt(j, i, ((1d/(2*Math.PI*std*std))*Math.pow(Math.E, -((x*x)+(y*y))/(2*std*std))));
}
}
out.normalize();
return out;
}
如果你想要,这也是我的 Kernel
class:
public class Kernel {
private final double[][] matrix;
public Kernel(int sidelength){
if((sidelength&1)==0)throw new IllegalArgumentException();
matrix = new double[sidelength][sidelength];
}
public double getValueAt(int x, int y){
return matrix[x][y];
}
public void setValueAt(int x, int y, double value){
matrix[x][y] = value;
}
public double sum(){
double sum = 0.0d;
for(double[] da:matrix){
for(double d:da){
sum+=d;
}
}
return sum;
}
public double[][] getFullKernal(){
return matrix;
}
public int getSideLegth(){
return matrix.length;
}
public void normalize(){
double normalizedConstant = 1d/sum();
for(int i=0;i<matrix.length;i++){
for(int j=0;j<matrix.length;j++){
matrix[i][j] = matrix[i][j]*normalizedConstant;
}
}
}
}