#高斯滤波对图像处理有一些错误不知道怎么解决!
问了AI说我有以下问题:
- 高斯核计算:虽然代码中尝试计算高斯核的权重,但计算方式不正确。高斯核的计算应该基于二维高斯函数,并且需要对每个像素点应用正确的权重。当前的实现没有正确计算高斯核的权重分布。
- 图像处理逻辑:在应用高斯核进行滤波时,代码逻辑存在错误。特别是对像素值的处理和归一化因子的计算需要修正。
- 边界处理:代码没有正确处理图像边界的情况,可能会导致数组越界访问。
- 未实现归一化:虽然代码中有归一化因子的计算,但实际上并没有进行归一化处理,这会影响滤波效果。
代码如下:
#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()
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 clrPal[256*4];//存储颜色信息
// parameters for filtering
int sigma = 1;
double pi = acos(-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);
// parameters for mean filtering
int n = 4*sigma + 1;
double W[21][21],w;
//weights for Guass filtering
double c,dis;
c = 1/(sigma*sqrt(2*pi));
for(i=-2*sigma; i<=2*sigma; i++)
for(j=-2*sigma; j<=2*sigma; j++)
{
//// 窗口中心的坐标p=(0,0)
//// 窗口内其它像素的坐标q=(i,j)
dis = sqrt(i*i+j*j);
if(dis>sigma*2)
W[i+2*sigma][j+2*sigma] = 0;
else
W[i+2*sigma][j+2*sigma] = c * exp(-dis*dis/2/sigma/sigma);
}
//Guass filtering
int cx=0,cy=0;
double sum = 0.0;
double normalization = 0.0;
// 对每个像素应用高斯核
for (int x = 0; x < height; ++x)
{
for (int y = 0; y < width; ++y)
{
double pixel_value = 0.0;
for (int i =-2*sigma; i <=2*sigma; ++i)
{
for (int j = -2*sigma; j <= 2*sigma; ++j)
{
cx = x + i;
cy = y + j;
if (cx >= 0 && cy >= 0 && cx < width && cy < height)
{
pixel_value += W[i+2*sigma][j+2*sigma] * I[cx * width + cy];
normalization += W[i+2*sigma][j+2*sigma];
}
}
}
if (normalization > 0) {
B[cx * width + cy] = pixel_value / normalization;
} else {
B[cx * width + cy] = I[cx * width + cy]; // 如果归一化因子为0,则保持原像素值不变
}
normalization = 0.0; // 重置归一化因子
}
}
//细节增强
/*
double val;
int x0,y0;
U8 D[900*600];
int a=3;//表示增强强度
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);
}
最后面还有细节增强的我注释掉了,也不确定是不是对的?