• ベストアンサー

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

  • ureo
  • お礼率91% (31/34)

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

  • ベストアンサー
  • _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

  • 画像処理について・・・・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・・・・・・・・; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } ソースコードをやっているのですが、後、・・・・・・・・・の所を入力して完成なんですが、苦戦してます。 処理の内容としましては、 1、入力画像Lenna.rawを読み込んで、 2、平均値フィルタをかけ、 3、Lenna_out.rawに書き出す(保存する)したいんですが、公式みたいなのを入れればいいのでしょうか? すみませんが、お願いします。

  • 平均値フィルタについて・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・ ; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } 自分でプログラムを作って練習しているのですが、このソースコードで入力画像を読み込んで、平均値フィルタをかけ、Lenna_out.rawに書き出そうとしているのですが、・・・・・・の箇所には公式を当てはめていけばいいんでしょうか?? すみませんがよろしくお願いします。。。。。。

  • 空Enterの扱い方

    3つの整数を入力し、最大値を出力するプログラムを作りました。 最大値をさがすステップに入る前に、 「最大値を出力しますか?(y/n)」と聞いてy+Enterで実行するようになっています。この部分を、 y+Enter もしくは 空Enter で実行するにはどのように変更すればよいのでしょうか?大変お手数ですが、教えてください。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> int main(){ int i,max,max_no,a[3]; char YN[2]; printf("整数を3つ入力してください。\n"); for(i=0;i<3;i++){ printf("%d番目の整数: ",i+1); scanf("%d",&a[i]); } printf("最大値を出力しますか?(y/n):"); scanf("%s",YN); if(YN[0]=='y'){ printf("最大値をさがします。\n"); } else{ exit(0); } max_no=0; max=a[max_no]; for(i=1;i<3;i++){ if(a[i]>max){ max=a[i]; max_no=i; } } printf("最大値は %d 番目のデータ %d です。\n",max_no+1,max); return 0; }

  • C言語のプログラミングについて教えてください

    課題で下記に示すのようなデータをファイル名を入力してのそのデータを読み込みyの最大値とそのときのxの値を表示するプログラムを作成しろと言われたのですが、僕はプログラミングが初心者でむしろ苦手でホント困ってます。だれか助けてください、お願いします! データ    x  y 0.12132 3.45355 0.12353  3.415451 . . . . . . のようにxとyの行列となっていて、その数は2000個を超えています。 自分なりにやってみたのですがデータをすべて読み込まないし、まずどのようにして、yの最大値をだし、なおかつそのxの値を表示させるのもわかんなくてホント困っています。 本末転倒になりますが、プログラムを書いていただけるとほんと助かります。よろしくお願いいたします。 ちなみにこれが自分で考えたプログラムです。とりあえず、yの値がでかいのでyの最大値だけだすつもりでやってみたけど駄目でした。 #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fin; char *list[256]; char buf[1024]; char filename1[80]; printf("入力ファイル名"); gets(filename1); fin=fopen(filename1,"r"); if (fin ==NULL) { printf("%sをオープンできません\n",filename1); exit(1); } while (fgets(buf, 1024, fin) !=NULL) { printf("%s",buf); } static float max; int x; fscanf(fin,"%f",&x); if(x>max){ max=x; printf("yの最大値=%f\n",max); } fclose(fin); }

  • csvファイルの読み込み

    fscanf関数を用いて、csvファイルの内容を構造体のそれぞれのメンバに読み込んで表示させようとしているのですが、4列目以降が上手く読み込めません。初歩的な質問で申し訳ありませんがどなたか教えてください。 ****************************ソース************************************************ #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME "view_001_McdlData.csv" #define FILE_SIZE 819200 struct Data{ int DataNo; int FrameNo; int SampleNo; char Digital; double voltage; double trigger; double C; double D; }; int main(int argc, char *argv[]) { FILE* fp,*fo, *fi; // ファイルポインタ用 int n, i, file_size; double time,vel[FILE_SIZE]; struct Data *dat; char buff[SIZE]; if ((fp = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; //データの読み込み while((fscanf(fp, "%d,%d,%d,%s,%lf,%lf,%lf,%lf",&dat[i].DataNo,&dat[i].FrameNo,&dat[i].SampleNo,&dat[i].Digital,&dat[i].voltage,&dat[i].trigger,&dat[i].C,&dat[i].D)) !=EOF ){ printf("%d %d %d %s %lf %lf %lf %lf\n",dat[i].DataNo,dat[i].FrameNo,dat[i].SampleNo,dat[i].Digital,dat[i].voltage,dat[i].trigger,dat[i].C,dat[i].D); i++; } fclose(fp); return 0; } ***********************************csvファイルの内容************************************ 0,1,0,0x3F,2.270000,0.000000,-1.000000,-1.000000 1,1,1,0x3F,2.260000,0.010000,-1.000000,-1.000000 2,1,2,0x3F,2.260000,0.010000,-1.000000,-1.000000 3,1,3,0x3F,2.260000,0.010000,-1.000000,-1.000000 4,1,4,0x3F,2.260000,0.010000,-1.000000,-1.000000 5,1,5,0x3F,2.260000,0.000000,-1.000000,-1.000000 ***************************************************************************************************

  • CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後

    CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。 プログラム ************************************************** #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME_00 "f_00_01.CSV" struct Data{ double value; double ave; }; int main(int argc, char *argv[]) { FILE* fp,*fo; // ファイルポインタ用 int n, i, file_size; struct Data *dat; if ((fp = fopen(FILE_NAME_00,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; for(i=0;i<file_size;i++){ fscanf(fp,"%lf",&dat[i].value); printf("%lf\n",dat[i].value); i++; } fclose(fp); printf("\n"); free(dat); return 0; } *************************************************** f_00_01.CSV *************************************************** 2.313725 2.312810 2.314031 2.316167 2.315557 2.313725 . . . . . ***********************************************

  • cygwinを使ってcsvファイルを読み込み、出力させようとしています

    cygwinを使ってcsvファイルを読み込み、出力させようとしています。 とりあえず、読み込みのみのプログラムを作成し、 実行させてみたのですが(run ファイル名.csv と入力) 「Error: could not start C:\cygwin\home\ユーザー名ファイル名.csv」 と出力され、読み込みができず、困っています。 プログラム初心者です。 恐縮ですがご回答よろしくお願いします。 以下に、読み込みプログラムとcsvファイルを記載します。 (プログラムは拾い物です。) <プログラム> #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("comand error nyuuryoku keishiki\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("can not open file[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("data error[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("error(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("error(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("error(3)\n"); break; } if(*wp != '\0'){ printf("error(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); } <csvファイル> 1,2,3 11,12,13 21,22,23

  • どうやってフローチャートを書きますか

    #include<stdio.h>   void main()   {   FILE*fp;   char buf[128];   char *rc;   char fname[20];   do{   printf("file name>>>");   scanf("%s",fname);   fp=fopen(fname,"r");   if=(fp==NULL) printf("File Open Err¥n");   }while(fp==NULL);   rc=fgets(buf,128,fp);   while(rc!=NULL){    printf("%s",buf);    rc=fgets(buf,123,fp);    }    fclose(fp);    }

  • ファイル分割について

    今本をみながら練習中なのですが、ファイル分割がうまくいきません。以下のような3つのプログラムをかいたのですが実行できません。 (一つ目:myfunc.h) int max(int x,int y); (二つ目:myfunc.c) int max(int x,int y){ if(x > y) return x; else return y;} (三つ目:sample.c) #include <stdio.h> #include "myfunc.h" int main(void){ int x,y,c; printf("1番目の整数\n"); scanf("%d",&x); printf("2番目の整数\n"); scanf("%d",&y); c = max(x,y); printf("最大値は%d\n",c); return 0;} すべてコンパイルしてsample.cを実行してもだめでした。ご指導お願いします><

  • 変数の表示

    プログラミングで、 y=2x+1はx座標1,y座標3を通る直線です。 と表示したいんです。 #include<stdio.h> main() { printf("y=2x+1はx座標1,y座標3を通る直線です。"); } と書いてみたのですが、これでは文章がそのまま表示されるだけです。このとき、1と3を変数で表したいのですがどうしたらいいのでしょうか・・・intとかcharを使うのでしょうか?文字と数字が両方入っているので、混乱してわかりません。お願いします。

専門家に質問してみよう