• ベストアンサー

bmpファイルの解析

Cプログラムでbmpファイルを読み込み 最大輝度(仮にbrightnessとします)とその座標(仮にx,yとします)を吐き出させるプログラムを作りたいのですが、うまくいきません。 アドバイスしていただければ助かります。 宜しくお願いします。 以下に作成したソースを載せています。 #include<stdlib.h> #include<stdio.h> #include<string.h>/*strcat関数で必要*/ unsigned char brightness; int x_size,y_size,/*imageの横画像数、縦画素数*/ x,y,/*ループ変数*/ max_brightness=0,/*最大輝度*/ max_x,/*最大輝度時のx座標*/ max_y;/*最大輝度時のy座標*/ int main(int argc,char* argv[]) { FILE *fp; char buffer[60000]; char file_name[256]; printf("ファイル名入力="); gets(file_name); strcat(file_name,".bmp"); fp = fopen(file_name, "r"); for(y=0; y<y_size; y++){ for(x=0; x<x_size; x++){ brightness=getc(fp); if(brightness>max_brightness) max_brightness=brightness; max_y=y; max_x=x; } } printf("最大輝度=%d\n",max_brightness); printf("(x,y)=(%d,%d)\n",max_x,max_y); if ( ! fp ) { printf("ファイルが開けません\n"); return 1; } fclose(fp); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • _himajin_
  • ベストアンサー率65% (128/195)
回答No.3

1つ再確認を…求めたいのは輝度(Luminance:YUVのY)でしょうか、それとも明度(Brightness:HSVのV)でしょうか? YUV:http://ja.wikipedia.org/wiki/%E8%89%B2%E7%A9%BA%E9%96%93#YCbCr_.2F_YPbPr HSV:http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93 輝度なら前述の式で良いですが、明度だとRGB3要素のうち最大のものを取ります。 とりあえず輝度という前提で… 表示部分が正しくない(データ型自体も間違っているかも?)です。 fprintf(fp,"%d,%d,%d\n",j,i,bright[j][i]); となっていて、整数表示になっています。brightも整数として定義しているのでしょうか? この式で出てくる値は 0.0 ~ 1.0 の小数なので、doubleかfloatとしてください。書式指定子は %f 等を使ってください。 0.0~1.0をそのまま整数に入れてしまうと、1.0以外は全部0になってしまいます。 または、精度は犠牲になりますが輝度の値に * 100 等して整数化しても良いです。 また、bmp_line_dataをfreeしすぎています。mallocの回数と同じだけfreeしてください。 この場合、1回だけで良いです。2回以上freeすると最悪クラッシュします。

ureo
質問者

お礼

求めたいのは輝度です。 輝度の計算上小数点以下も使うことは分かっていましたが 整数部分のみでも画像は再構成するだろうと思ってました。 やはりきちんと合わせておく必要があるのですね。 ご指摘のデータ型とbrigth[][]の箱の数を適当な値にしていたのですが、具体的な幅と高さに直すことで解決しました。 アドバイス本当にありがとうございました! とても助かりました!

その他の回答 (2)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

Windowsなら fp = fopen(file_name, "rb"); にした方がいいですよ

ureo
質問者

お礼

ご指摘ありがとうございます。 訂正いたしました。

  • _himajin_
  • ベストアンサー率65% (128/195)
回答No.1

x_size, y_size がグローバル変数として定義されてるだけで値を入れてないので、0 のままです。(グローバル変数は初期値0です) ループを1度も回らずに抜けちゃってるはずです。 それと、bmpがWindowsでよく用いられているbmpのことなら、先頭にヘッダが付いているのでそこを画像データとしてみないようにする必要があります。 http://ja.wikipedia.org/wiki/Windows_bitmap # MSDNとかにも詳しい資料があるはずです また、グレイスケールデータでないなら輝度はRGBの値から計算してやる必要があります。 計算式は 輝度 = 0.299 * R + 0.587 * G + 0.114 * B が一般的のようです。 もっと桁数の多いものや略したものもありますが必要に応じて決めてください。

ureo
質問者

お礼

ご回答ありがとうございます。 RGBから輝度に変化して、x,y座標(ソースではi,j) での輝度をテキストファイルに保存して画像を再構成してみたのですが もとのbitmapをまったく反映していません。 何が原因か分かれば教えて頂きたいと思います。 bitmapの読み込みには http://hooktail.org/computer/index.php?plugin=attach&refer=Bitmap%A5%D5%A5%A1%A5%A4%A5%EB%A4%F2%C6%FE%BD%D0%CE%CF%A4%B7%A4%C6%A4%DF%A4%EB&openfile=bitmap.c を参考にして作りました。 テキストファイルに保存する部分のソースを下記に載せています。 for(i=0; i<height; i++){ fread(bmp_line_data, 1, real_width, fp); for(j=0; j<width; j++){ img->data[(height-i-1)*width + j].b = bmp_line_data[j*3]; img->data[(height-i-1)*width + j].g = bmp_line_data[j*3 + 1]; img->data[(height-i-1)*width + j].r = bmp_line_data[j*3 + 2]; bright[j][i]= 0.299 * bmp_line_data[j*3 + 2] + 0.587 * bmp_line_data[j*3 + 1] + 0.114 * bmp_line_data[j*3]; } } fp =fopen("test.txt","w"); if(fp == NULL){ fprintf(stderr, "Error: file could not read.\n"); return NULL; } for(i=0; i<height; i++){ for(j=0; j<width; j++){ fprintf(fp,"%d,%d,%d\n",j,i,bright[j][i]); free(bmp_line_data); } } fclose(fp);

関連するQ&A

専門家に質問してみよう