Я пытаюсь реализовать функцию гауссовского размытия изображения nxn с гауссовым ядром определенного радиуса rs = ((int) 2.75 * sigma + 0.5).«Разрыв» гауссовского размытия вокруг краев изображения
for (x=0;x<n;x++){
for (y=0;y<n;y++){
sum=0.0,wsum=0.0;
//Position correction at the edges
if(x-rs<0){
ix=0;
}
else ix=rs;
if(y-rs<0){
iy=0;
}
else iy=rs;
if (x+rs>n-1){
jx=n-1-x;
}
else jx=rs;
if (y+rs>n-1){
jy=n-1-y;
}
else jy=rs;
//Kernel mean value correction at the edges
if (x-rs < 0){
meanx=x+((int)rs/2);
}
else meanx=x;
if(y-rs<0){
meany=y+((int)rs/2);
}
else meany=y;
if (x+rs>n-1){
meanx=x-((int)rs/2);
}
else meanx=x;
if (y+rs>n-1){
meany=y-((int)rs/2);
}
else meany=y;
for (i=x-ix;i<=x+jx;i++){
for (j=y-iy;j<=y+jy;j++){
weight=1/(2*M_PI*sigma*sigma)*exp(-((meanx-i)*(meanx-i)+(meany-j)*(meany-j))/(2*sigma*sigma));
sum+=pic1.intenzity[i][j]*weight;
wsum+=weight;
}
}
pic2->intenzity[x][y]=((int)sum/wsum+0.5);
fprintf(fw,"%d\n",pic2->intenzity[x][y]);
}
Когда я не использую коррекции среднего значения по краям результат выглядит следующим образом:
и когда я попытался смещая среднее значение ядра создает разрыв также на нижнем и правом краю изображения:
with shifting the mean value to rs/2
я должен был сделать этот край позиционированием n, потому что сумма будет переполняться. Теперь кажется, что гауссова свертка внезапно прыгает по какой-то причине, когда она находится в положении rs от верхнего и левого краев как для x, так и для y. Я бы хотел, чтобы он вел себя так же, как в «интерьере» изображения, или, возможно, заставлял интенсивности исчезать до 0, когда позиция приближается к краю.
Я мог бы увеличить изображение с помощью rs, но это вызовет проблемы с положением края.
Спасибо за любую помощь :) проницательную
Я не вижу ничего плохого в ваших расчетах, но это может быть ошибка округления. Вы переходите на целое число на каждом шагу, вы получите лучшие результаты, если вы сохранили все данные как плавающие или двойные, чтобы выполнить вычисления, а затем в конце раунда до ближайшего int. У вас есть огромная погрешность, как вы конвертируете в int каждый раз. –
Я попытался сохранить sum/wghtsum в отдельную матрицу float, а затем снова записать ее в пиксели в int, но сделал то же самое. – Martin
Я имел в виду кастинг на 'int', который вы делаете почти на каждом шагу. Убедитесь, что все ваши переменные типа double, и удалите каждый экземпляр '(int)', это усекает десятичное число, когда оно может содержать важные данные, особенно потому, что вы выполняете несколько вычислений. Вы можете быть в значительной степени. –