高斯模糊不适用于位图

时间:2016-06-26 14:55:14

标签: c bitmap blur gaussian

这是我的问题:使用这个程序我加载8位BMP图片并用高斯函数模糊它,但是根据结果判断我在某个地方犯了一个错误。任何提示?:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAX 25

struct FileHeader{
    short signature;
    int filesize;
    short reserved1;
    short reserved;
    int offset;
};

struct MapHeader{
    int headersize;
    int width;
    int height;
    short plane;
    short bits;
};

void load_file_bmp(struct FileHeader *fheader, struct MapHeader *mheader, char *input_name)
{
FILE *fp1;
fp1 =fopen(input_name,"rb");

if(fp1)
{
    fread(&fheader->signature,2,1,fp1);
    fread(&fheader->filesize,4,1,fp1);
    fread(&fheader->reserved1,2,1,fp1);
    fread(&fheader->reserved2,2,1,fp1);
    fread(&fheader->offset,4,1,fp1);
    fread(&mheader->headersize,4,1,fp1);
    fread(&mheader->width,4,1,fp1);
    fread(&mheader->height,4,1,fp1);
    fread(&mheader->plane,2,1,fp1);
    fread(&mheader->bits,2,1,fp1);

    printf("Signature: %X\n",fheader->signature);
    printf("File Size: %d bajtow\n",fheader->filesize);
    printf("Reserved1: %d\n",fheader->reserved1);
    printf("Reserved2: %d\n",fheader->reserved2);
    printf("Offset: %d\n",fheader->offset);
    printf("Header Map Size: %d\n",mheader->headersize);
    printf("Width : %d\n",mheader->width);
    printf("Height: %d\n",mheader->height);
    printf("Plane amount: %d\n",mheader->plane);
    printf("Bit/pixel: %d\n",mheader->bits);
}
else
{
    printf("File open error");
    exit(1);
}
fclose(fp1);
}

void save_file_bmp(struct FileHeader *fheader, struct MapHeader *mheader, char *input_name, char *output_name, int radius)
{
FILE *fp1, *fp2;
fp1 =fopen(input_name,"rb");
fp2 =fopen(output_name,"wb");

long int i, j, padding, rs;
unsigned long long const int dimensions =mheader->height*mheader->width;
long double mask[dimensions], map[dimensions];
rs = radius*2.57;

//Padding
padding =(mheader->width*3)/4 *4;
//Pixelmap reading
if(fp1)
{
    fseek(fp1, fheader->offset, SEEK_SET);
    for(i =0; i<mheader->height; i++, fseek(fp1, padding, SEEK_CUR))
    {
        for(j =0; j<mheader->width; j++)
        {
            map[i*mheader->height+j]=fgetc(fp1);
        }
    }
}
else
{
    printf("File open error while creating pixelmap");
    exit(1);
}
if(fp2)
{
    long int ix, iy, x, y, tmp, minx, maxx, miny, maxy;
    long double normalization, normalization_value, n_normalization, dsq ,wght;

    fseek(fp1, 0, SEEK_END);
    tmp = ftell(fp1);

    fseek(fp1, 0, SEEK_SET);
    for(i =0; i <tmp; i++)
    {
        fputc(fgetc(fp1), fp2);
    }

    fseek(fp2, fheader->offset, SEEK_SET);

    for(i=0; i<mheader->height; i++)
    {
        for(j=0; j<mheader->width; j++)
        {
            normalization_value =0, n_normalization =0;
            for(iy =i-rs; iy<=i+rs; iy++)
            {
                for(ix =j-rs; ix<=j+rs; ix++)
                {
                    //x
                    if(0<ix)
                    {
                        maxx =ix;
                    }
                    else
                    {
                        maxx =0;
                    }
                    if((mheader->width-1)<maxx)
                    {
                        minx =mheader->width-1;
                    }
                    else
                    {
                        minx =maxx;
                    }
                    //y
                    if(0<iy)
                    {
                        maxy =iy;
                    }
                    else
                    {
                        maxy =0;
                    }
                    if((mheader->height-1)<maxy)
                    {
                        miny =mheader->height-1;
                    }
                    else
                    {
                        miny =maxy;
                    }
                    x =minx;
                    y =miny;
                    dsq =(ix-j)*(ix-j)+(iy-i)*(iy-i);
                    wght =exp(-dsq/(2*radius*radius))/(M_PI*2*radius*radius);
                    normalization_value +=map[y*mheader->width+x]*wght;
                    n_normalization +=wght;
                }
            }
            normalization =normalization_value/n_normalization;
            mask[i*mheader->width+j] =normalization;
        }
    }
    for(i =0; i<mheader->height; i++, fseek(fp2, padding, SEEK_CUR))
    {
        for(j =0; j<mheader->width; j++)
        {
            map[i*mheader->width+j]=mask[i*mheader->width+j];
            fputc(map[i],fp2);
            fputc(map[i],fp2);
            fputc(map[i],fp2);
        }
    }
}
else
{
    printf("Save file open error");
    exit(1);
}
fclose(fp1);
fclose(fp2);
}

int main()
{
struct FileHeader fheader;
struct MapHeader mheader;
int radius=20;
char load_name[MAX], *lname=load_name, save_name[MAX], *sname =save_name;
printf("Enter input file name: ");
gets(lname);
printf("Enter output file name: ");
gets(sname);
//printf("Enter radius value: ");
//gets(radius);


load_file_bmp(&fheader, &mheader, lname);

save_file_bmp(&fheader, &mheader, lname, sname,radius);

return 0;
}

BEFORE_BLUR

AFTER_BLUR

1 个答案:

答案 0 :(得分:0)

您的许多结构成员变量应为unsigned。请参阅BMP文档。

struct FileHeader
{
    unsigned short signature;
    unsigned int filesize;
    unsigned short reserved1;
    unsigned short reserved2;
    unsigned int offset;
};

struct MapHeader
{
    unsigned int headersize;
    int width;
    int height;
    unsigned short plane;
    unsigned short bits;
};

你的填充应该是剩余字节

 padding =((mheader->width*3+3)/4 )*4-mheader->width*3; /* minus the number of read bytes */

您的像素地图读数应为

map[i*mheader->width+j]=fgetc(fp1); /* Read Blue value */
fseek(fp1, 2, SEEK_CUR); /* skip the Green and Red values assuming same values as Blue */

您的结果位于mask变量中,因此您应将mask变量存储在输出文件中

int pixelvalue = mask[i*mheader->width+j]; /* from mask variable */
fputc(pixelvalue,fp2);
fputc(pixelvalue,fp2);
fputc(pixelvalue,fp2);

N.B。您的代码中还有许多其他陷阱。