• ベストアンサー

C言語でクロマキー合成をする方法

input.bmpとbackground.bmpとoutput.bmpを作りで好きな絵を用意して、input.bmpというビットマップファイル(色数は24ビット)とbackground.bmpというファイルを開き,クロマキー合成をし,ビットマップファイルoutput.bmpに出力させる。 上記の物をC言語でするにはどうすればいいのでしょうか? 下記のものは自分でやったのですがやり方が分かりません。どなたか知恵を貸してください。 (ほとんど間違っていると思いますが・・・) #include<stdio.h> int main() { FILE *fp; int i; char data[2]; short s; fp1=fopen("input.bmp","rb"); fp2=fopen("background.bmp","rb"); fp3=fopen("output.bmp","wb") int k; for(k=0;k<10000;k++){ fputc(0,fp); fputc(0,fp); fputc(0,fp); } fclose(fp); fread(&data[0],1,2,fp1); fread(&data[0],1,2,fp2); fwrite(&data[0],1,2,fp3); int fs; fread(&fs,f1); fread(&fs,f2); fwrite(&fs,f3); fp=fopen("aka.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(0,fp); fputc(0,fp); fputc(70,fp); } fclose(fp); fp=fopen("midori.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(0,fp); fputc(150,fp); fputc(0,fp); } fclose(fp); fp=fopen("ao.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(255,fp); fputc(0,fp); fputc(0,fp); } fclose(fp); return(0); }

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

  • ベストアンサー
  • usatan2
  • ベストアンサー率37% (163/436)
回答No.3

No2です。 応答がないので、追加回答です。 >下記のものは自分でやったのですがやり方が分かりません。どなたか知恵を貸してください。 1画素あたりの色データを定義して、 1画素のデータを読み込む関数 bool getRGB(color24 *c, FILE *fp)、 書き出す関数 void putRGB(color24 c, FILE *fp)、 クロマキー処理として背景画像を使うかどうかを判断する関数 bool transparency(color24 c), を作ればいいのでは? 具体的には、以下にプログラムの骨子を書きましたので参考にしてください。 このプログラムの肝は、最後の関数transparency()です。 単純には24ビットのすべての色について、背景画像を使うのか使わないのかを書いたテーブルを用意して判断するのが完璧ですが、24ビットの表、つまり16,000,000色分の表を用意する必要があり現実的ではありません。ここは質問者さんの腕の見せ所ですが、単純に、RGBの各成分の値の大小で判断すると、思ったような結果が得られませんよ(経験者談)。 もし回答者が作るとしたら、24ビットの色を256色程度に分類して、  背景画像を使う色--値:0  背景画像は使わない色--値:1  どちらともいえない色--値:より詳細なレベルの表の番号 といったテーブルをつくり、多段階で判断すると思います。 /* 24bit カラーの型を定義 */ struct color24 { BYTE r,g,b; } forground, background; void main() { FILE *fpfg,*fpbg,*fpout; /* ファイルをオープンして */ fpfg = fopen("input.bmp","rb"); fpbg = fopen("background.bmp","rb"); fpout= fopen("output.bmp","wb") /* 画素が正常に読み込める間、つまりすべての画素についてクロマキー処理をして */ while( getRGB(&forground,fpfg) && getRGB(&background,fpbg) ) {   if(transparency(forground)) putRGB(background,fpout);   else putRGB(forground, fpout); } /* ファイルをクローズしてプログラムを終了する */ fclose(fpfg); fclose(fpbg); fclose(fpout); }

bad-pc
質問者

お礼

ご回答ありがとうございました。参考にさせてもらいますね。

その他の回答 (2)

  • usatan2
  • ベストアンサー率37% (163/436)
回答No.2

回答になってなくてすいません。 コメントがないので、よくわかりませんので、コメントをつけてくださいね。 で早速ですが、8行目でfp1 に代入されてますが、fp1の型が定義されてませんので、ここでエラーになると思います。 #include<stdio.h> int main() { FILE *fp; int i; char data[2]; short s; fp1=fopen("input.bmp","rb"); fp2=fopen("background.bmp","rb"); fp3=fopen("output.bmp","wb") さらに次のブロックの部分も意味不明です。何をなさろうとしているのですか? コメント書きましょうよ。 変数fpは定義されてますが、値が代入されていないので、どこに書き出されるのか不明ですよね。 30000回0を、どこに書き出すつもりなのでしょう? int k; for(k=0;k<10000;k++){ fputc(0,fp); fputc(0,fp); fputc(0,fp); } fclose(fp); 以下同様、コメントをかかれていないと、何をなさろうとしているのか、少なくとも私には理解できませんし、他の回答者さんもわからないと思いますよ。

  • Kaone
  • ベストアンサー率60% (33/55)
回答No.1

そのビットマップは、24ビットの連続した色情報ファイルと思っていいのですか? もしWindows標準の24ビット画像ファイルだとすると、根本的に間違ってると思いますが・・・

bad-pc
質問者

お礼

24ビットの連続した色情報ファイルです。

関連するQ&A

  • プログラミングの課題です。

    input.bmpというビットマップファイル(色数は24ビット)とbackground.bmpというファイルを開き,クロマキー合成をし,ビットマップファイルoutput.bmpに出力させる。ただしimput.bmpが、青:100以上 緑:150以下 赤:70以下なら背景とみなしてよい。 #include <stdio.h> int main() { FILE *fp1,*fp2,*fp3; char pixeldata[54]; int width,height; int i,j; fp1=fopen("input.bmp","rb"); if(fp1==NULL) return(1); //fp1のヘッダー情報の読み込み fp2=fopen("background.bmp","rb"); if(fp2==NULL) return(1); //fp2のヘッダー情報の読み込み fp3=fopen("output.bmp","wb"); if(fp3==NULL) return(1); //fp3のヘッダー情報の書き込み fread(pixeldata,1,54,fp1); fread(pixeldata,1,54,fp2); fwrite(pixeldata,1,54,fp3); printf("input.bmpの縦は何ピクセルですか?"); scanf("%d",&height); printf("input.bmpの横は何ピクセルですか?"); scanf("%d",&width); for(i=0;i<height*width*3;i++){ //画素情報の読み込み(画像サイズ分繰返し) fgetc(fp1); //1画素分のRGBの情報をfp1から読み込み fgetc(fp2); //1画素分のRGBの情報をfp2から読み込み if(){ //fp1から読み込んだ画素が青い fputc(,fp3); //fp3へfp2で読み込んだ1画素分の情報を書き込み } else{//fp1から読み込んだ画素が青くない fputc(,fp3); //fp3へfp1で読み込んだ1画素分の情報を書き込み } } fclose(fp1);fclose(fp2);fclose(fp3); return(0); } みたいな感じで作りましたが、後半がどうやったらいいかわかりません。 どうしたらいいかアドバイスや解説お願いします。

  • c言語による画像処理について

    いつもお世話になってます。 c言語を使った画像処理を学び始めました。 入力画像の白(RGB値255,255,255)以外の画像を黒(RGB値0,0,0) に変換するプログラムを作成したいと思っているのですが、 入力画像の大きさによっては正常に命令を実行してくれないことがあるので、 改善点をご教示いただきたいと考え投稿させていただきました。ソースプログラムは #include<stdio.h> #define nx 100 //画像の幅 #define ny 100 //画像の高さ int main(void) { FILE *fp,*fp2; int i,j; unsigned char header[54]; unsigned char screen[nx][ny][3]; /* ファイルから読む */ fp=fopen("input.bmp","rb"); //ビットマップ形式 ,24ビットカラー fread(header,1,54,fp); // ヘッダ(54バイト)を飛ばす */ fread(screen,1,nx*ny*3,fp); // 残りはデータ(最下行から順に入る) //(255,255,255)以外なら黒(0,0,0)に for(j=0;j<ny;j++) for(i=0;i<nx;i++) if(screen[j][i][0]!=255||screen[j][i][1]!=255||screen[j][i][2]!=255){ screen[j][i][0]=0; screen[j][i][1]=0; screen[j][i][2]=0; } fclose(fp); /* ファイルに書く */ fp=fopen("output.bmp","wb"); fwrite(header,1,54,fp); /* ヘッダ */ fwrite(screen,1,nx*ny*3,fp); /* データ */ fclose(fp); return 0; } となっています。ここで、画像の高さ、幅を100以下にすると正常に変換できなくなります。 どなたか原因がお分かりでしたらお知らせ願えないでしょうか?

  • C言語のfor文について

    C言語のfor文について C言語初心者です。質問させていただきます。 output.datというバイナリファイルに値を書き込みたい(100~149)のですが、どうもうまくいきません。 値が半分だけ正常に入って、あとの半分はおかしな値が入ります。 どなたか分かる方教えていただけないでしょうか。 ソース(一部分)↓ int main(){ int i,j; char output[456]; //ファイルに値を入れる for(i=0,j=100;i<456,j<556;i++,j++){ output[i]=j; } //バイナリ書き込みモードでファイルをオープン if((fp = fopen("output.dat","wb")) == NULL) { printf("<output.dat> file open error\n"); exit(1); } //値をファイルに書き込む fwrite(output,456,1,fp); fclose(fp); exit(0); }

  • プログラム(C)

    #include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・   ・ }; struct BMPINFOHEADER { ・   ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。

  • C言語 ファイルポインタ

    度々同じプログラムで質問させてもらっています。 #include <stdio.h> #include <time.h> #include <math.h> #define N 10 void filewrite(int i,int a[]); void main(void){ int min,s,t,i,j,k,a[N]; srand((unsigned int)time(NULL)); for(i=0;i<N;i++) a[i]=rand()%10+1; for(j=0;j<i-1;j++){ min=a[j]; s=j; for(k=j+1;k<i;k++){ if(a[k]<min){ min=a[k]; s=k; } } t=a[j];a[j]=a[s];a[s]=t; filewrite(i,a); } } void filewrite(int i,int a[]){ int s; FILE *fp; fp = fopen("selection.txt","w"); if(fp == NULL)return; for(s=0;s<i;s++){ fprintf(fp,"%d,",a[s]); } fprintf(fp,"\n"); fclose(fp); } 途中経過もテキストファイルで出力したいのですが、このプログラムを実行すると最後の結果しか出力されません。 アドバイスをよろしくお願いします。

  • C言語のプログラムをエクセルに書き込む方法

    C言語のプログラムをエクセルに書き込みたいのですが、自分が理解していないのか、上手にできません。 前、質問(No.421727)して、教えてもらったのですがソートプログラムの実行結果もおかしい感じです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 void filewrite(int j,int i,int a[]); void main(void){ int min,s,t,i,j,k,a[N]; srand((unsigned int)time(NULL)); for(i=0;i<N;i++) a[i]=rand()%1000+1; for(j=0;j<i-1;j++){ min=a[j]; s=j; for(k=j+1;k<i;k++){ if(a[k]<min){ min=a[k]; s=k; } } t=a[j];a[j]=a[s];a[s]=t; if(j%100 == 99){ for(s=0;s<i;s++) printf("%d\t",a[s]); } filewrite(j,i,a); } } void filewrite(int j,int i,int a[]) { int s; FILE *fp; char name[15]; printf("\nfilename="); scanf("%s",name); if((fp=fopen(name,"w"))==NULL){ printf("\nCan't open the sourse file\n"); exit(1); } if(j%100 == 99){ for(s=0;s<i;s++) fprintf(fp,"%d\n",a[s]); fclose(fp); } } よろしくお願いします。

  • visual c で、ビットマップを読み込む方法

    1120.bmpというファイルをvisual c++で読み込みたいのですが、初心者のため、いまいち方法が分かりません。 ネット上にビットマップの読み込みについて、 1 BITMAPFILEHEADERを読み込む(ビットマップで無い場合はじく) 2 BITMAPINFOHEADERを読み込む(16,256で無い場合ははじく) 3 BITMAPINFOHEADER構造体とRGBQUAD構造体の配列からなるBITMAPINFO構造体の領域を動的に確保する 4 CreateDIBSectionを使って、ビットマップビット列の領域を確保する 5 実際に描画する 6 プログラムが終了したときや、上書き読み込みをする場合は確保した領域を開放する と書いてあったのですが、3から先がたぶん分からない状態で、3のところまでも合っているか分かりません。 もしも、分かる方いらっっしゃったらお願い致します。 今、以下のところまでファイルの記述が終わっています。 #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp; int bfType; int bfSize; int bfReserved1; int bfReserved2; int bfOffBits; int biSize; int biWidth; int biHeight; int biPlanes; int biBitCount; int biCompression; int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; int rgbBlue; int rgbGreen; int rgbRed; int rgbReserved; fp = fopen("1120.bmp", "rb"); if(fp == NULL) printf("ファイルオープンに失敗しました。\n"); //BITMAPFILEHEADER構造体 fread(&bfType, 14, 1, fp); fread(&bfSize, 4, 1, fp); fread(&bfReserved1, 2, 1, fp); fread(&bfReserved2, 2, 1, fp); fread(&bfOffBits, 4, 1, fp); //BITMAPINFOHEADER構造体 fread(&biSize, 4, 1, fp); fread(&biWidth, 4, 1, fp); fread(&biHeight, 4, 1, fp); fread(&biPlanes, 2, 1, fp); fread(&biBitCount, 2, 1, fp); fread(&biCompression, 4, 1, fp); fread(&biSizeImage, 4, 1, fp); fread(&biXPelsPerMeter, 4, 1, fp); fread(&biYPelsPerMeter, 4, 1, fp); fread(&biClrUsed, 4, 1, fp); fread(&biClrImportant, 4, 1, fp); fclose(fp); return 1; }

  • C言語→C#に変換

    C言語→C#に変換 C言語からC#に変換したいのですが、わからないところがあります。 コマンドライン引数からファイル名とキーワードを入力して、キーワードがある行をアウトプットファイルに書き込むという処理です。 C言語のソースは、 main(int argc,char *argv[]){ FILE *fp; FILE *fpp; int i; char KEYWORD[256]; char buf[256]; //(1)アウトプットファイルのオープン fpp=fopen("output.txt","w"); for(i=1;i<argc-1;i++){ if(strcmp(argv[i],"-a")==0){ //(2)入力ファイルのオープン if((fp=fopen(argv[i],"r"))==NULL){ printf("open error!\n"); exit(1); } } //(3)キーワードの代入 if(strcmp(argv[i],"-b")==0){ strcpy(KEYWORD,argv[i]); } } //(4)一行読み込む while(fgets(buf,sizeof(buf),fp)!=NULL){ //(5)キーワードの条件で文字列抽出 if(strstr(buf,KEYWORD)!=NULL){ //(6)アウトプットファイルに出力 fprintf(fpp,"%s",buf); } } //ファイルクローズ fclose(fp); fclose(fpp); } です。 (3)キーワードの代入と、(5)文字列抽出の部分がネットなどで調べてもよくわかりません。 分かる方いらっしゃいましたら教えていただけると幸いです。 宜しくお願いします。 .

  • C言語について

    以下のプログラムについてです test.txtから単語を読み込んでその異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stddef.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="test.txt"; char *fn2="total word.txt"; const char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x=0, c, l, t=0,k=0; char word3[LMAX][NMAX]; char word1[NMAX]; char word2[NMAX]; char *tp; char *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); return -1; } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); return -1; } for(c=0;c<LMAX;c++){ if(fgets(word3[c],NMAX,fp)==NULL)break; p++; } for(c=0;c<p;c++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(word3[c][x]); } tp=word1; while((tp2=strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`'){ t=1; } tp2++; } free(tp); strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & l)){ word2[l]='\0'; } if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(fp2); return 0; } void all_words(FILE* fp2){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); return; } for(;;){ if(fgets(word3, NMAX,fp2)==NULL){ break; } n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int c, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp; char *yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); free(m); return; } for(c=0,xp=m; c<n;c++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); c=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; c++; } else{ c=1; } } printf("KIDN OF WORD:%d\n",n-y); free(m); fclose(fp2); } このプログラムについてメモリリークになってしまうのですが 確保していないメモリー領域に代入しているのが原因らしいのですが 具体的にどこを直せば良いのでしょうか? よろしくお願いします

  • C言語について

    以下のプログラムについてです test.txtというファイルから文字を読み込み、異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="test.txt"; char *fn2="total word.txt"; int main(void){ int p=0, x, count, l,k, t=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,"\n !?()*-;:.,_\"[]"))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & l)) word2[l]='\0'; if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(fp2); return 0; } void all_words(FILE* fp2){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ sprintf(xp+strlen(xp)-1," (%d)",count); count=1; } }    printf("KIDN OF WORD:%d\n",n-y); free(m); fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます。 どうしたら良いでしょうか?

専門家に質問してみよう