2016-06-26 4 views
-1

ここに私の問題があります:このプログラムでは、私は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

+0

最初に[お問い合わせ]ページをお読みください。 –

+0

デバッガを使用して問題を特定する絶好の機会です。それは楽しい! :-) – alk

+1

コードを再構成することで、画像処理部品を簡単に無効にでき、少なくとも画像の生データを正しく読み書きするかどうかをテストできるようになります。 – alk

答えて

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; 
}; 

あなたのパディングが

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変数を保存する必要がありますので、あなたのピクセルマップの読みが、あるべき

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

として残留バイトである必要があります出力ファイルには、

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

N.B.あなたのコードには他にもいくつかの落とし穴があります。

関連する問題