#想要双边滤波处理图像的效果,结果图片黑屏了!
AI说有以下问题
1.
函数命名与实际功能不符:函数名为gaussian,但实际上并没有实现高斯滤波的完整逻辑。此外,代码中注释提到了双边滤波,但实际上并没有正确实现双边滤波算法。
2.
边界处理逻辑错误:在处理图像边界时,代码使用了不正确的逻辑来处理坐标映射。这可能导致数组越界访问或错误的像素值访问。
3.
高斯核计算逻辑不完整:高斯核的计算没有考虑到像素值的实际位置和权重分配。此外,高斯核的归一化处理也不正确。
4.
细节增强部分未使用:注释中的细节增强部分被注释掉了,如果需要该功能,应该取消注释并进行相应修改。
代码如下:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
typedef unsigned char U8;
typedef unsigned short U16;
typedef unsigned int U32;
#pragma pack(1)
typedef struct
{
//bmp header
U16 bfType; // B M
U32 bfSize; //文件大小
U16 bfReserved1;
U16 bfReserved2;
U32 bfOffBits; //文件头偏移量
//DIB header
U32 biSize; //DIB头大小
U32 biWidth; //文件宽度
U32 biHeight; //文件高度
U16 biPlanes;
U16 biBitCount; //每个相素点的位数
U32 biCompression;
U32 biSizeImage; //图文件大小
U32 biXPelsPerMeter;
U32 biYPelsPerMeter;
U32 biClrUsed;
U32 biClrImportant;
} BMP_HEADER;
#pragma pack()
double gaussian(int x,double sigma)
{
double a = 1.0 / (sigma * sqrt(2 * M_PI));
double e = exp(-0.5 * pow(x, 2) / pow(sigma, 2));
return a * e;
}
int main(int argc, char **argv)
{
int fd;
int i,j,k;
int width,height,bpp;
int stride;
char fName0[256],fName[256],sTmp[100];
BMP_HEADER header;
U8 I[900*600],B[900*600];
//I是每个点的像素值,B是处理后的
U8 D[900*600];
U8 clrPal[256*4];//存储颜色信息
int sigma =1;
if(argc==1)
{
printf("File name of the image to be processed: \n");
scanf("%s", fName0);
//strcpy(fName0,"mountain.bmp");
}
else if(argc==2)
strcpy(fName0,argv[1]);
else
perror("Please provide only the original image name or give none.");
strcpy(fName,"");
strncat(fName,fName0,strlen(fName0)-4);
sprintf(sTmp,"_filterMean.bmp",sigma);
strcat(fName,sTmp);
fd = open(fName0, O_RDONLY | O_BINARY);
if(-1 == fd)
perror("open bmp file fail");
read(fd, &header, sizeof(BMP_HEADER));
lseek(fd, header.bfOffBits, SEEK_SET);
read(fd, I, header.biSizeImage);
close(fd);
width = header.biWidth;
height = header.biHeight;
stride = header.biSizeImage/height;
bpp = header.biBitCount;
if(bpp!=8)
return 0;
fd = open(fName, O_WRONLY | O_CREAT | O_BINARY);
if(fd < 0 )
perror("open x.bmp fail");
write(fd, &header, sizeof(BMP_HEADER));
for(i=0; i<256; i++)
{
clrPal[4*i] = clrPal[4*i+1] = clrPal[4*i+2] = i;
clrPal[4*i+3] = 0;
}
write(fd, clrPal, 256*4);
double pi = acos(-1);
int a=3;//表示增强强度
double W[21][21];
//// parameters for bilateral filtering
double cs,disS,cr,disR;
double sigmaR = 25.5;
cs = 1/(sigma*sqrt(2*pi));
cr = 1/(sigmaR*sqrt(2*pi));
// 初始化高斯核数组(空间域权重)
int x, y; //当前像素在图像中的坐标
int u, v; //滤波窗口内像素在图像中的坐标
double sum = 0.0;
// 计算双边权
for (int i = -2 * sigma; i <= 2 * sigma; i++)
for (int j = -2 * sigma; j <= 2 * sigma; j++) {
disS = sqrt(i * i + j * j);
disR = abs(I[(i + 2 * sigma) * stride + (j + 2 * sigma) ] - I[(2 * sigma) * stride + 2 * sigma]);
if (disS > sigma * 2)
W[i + 2 * sigma][j + 2 * sigma] = 0;
else {
W[i + 2 * sigma][j + 2 * sigma] = gaussian(disS, sigma) * gaussian(disR, sigmaR);
sum += W[i + 2 * sigma][j + 2 * sigma];
}
}
// 归一化
for (int i = 0; i < 4 * sigma + 1; i++)
for (int j = 0; j < 4 * sigma + 1; j++)
{
W[i][j] /= sum;
}
for (x = 0; x < height; x++)
for (y = 0; y < width; y++)
{
double sum = 0.0;
for (int i = -2 * sigma; i <= 2 * sigma; i++)
{
u = x + i;
if (u < 0)
u = -u;
else if (u >= height)
u = height * 2 - u - 2; //处理边界情况
for (int j = -2 * sigma; j <= 2 * sigma; j++) {
v = y + j;
if (v < 0)
v = -v;
else if (v >= width)
v = width * 2 - v - 2; //处理边界情况
sum += W[i][j] * I[u * stride + v];
}
}
if (sum < 0) sum = 0;
else if (sum > 255) sum = 255;
B[x * stride + y] = (U8)(sum + 0.5); //将结果储存到输出图像
}
//细节增强
/*double val;
for(x0=0; x0<height; x0++)
for(y0=0; y0<width; y0++)
{
val=(I[x0*stride+y0]*a)-(B[x0*stride+y0]*(a-1));
if(val<0) val = 0;
else if(val>255) val = 255;
D[x0*stride+y0] = (U8)(val+0.5);
}
*/
write(fd, B, header.biSizeImage);
close(fd);
}