• 締切済み

YUV動画像を1ピクセルごとにずらしていく方法がわかりません・・・

動画像を1フレーム毎に1ピクセルずつ右にずらし右にはみでたピクセルは左の欠けた部分にそのまま補完するプログラムを作りたいのですが途中からわかりません;; ピクセルどどうやって右のやつを左にもっていくのかがさっぱりで・・・どなたかお願いします。 #include <stdio.h> #include <stdlib.h> #define x_size 352 #define y_size 288 #define FN 200 typedef struct { unsigned char Y[x_size*y_size]; unsigned char U[x_size*y_size/4]; unsigned char V[x_size*y_size/4]; } FRAME; int main(void) { FILE *fpr; FILE *fpw; char file_name1[100]="zikken2.yuv"; char file_name2[100]="./out.yuv"; int i, frame_num,j; FRAME *ref; if((fpr = fopen(file_name1, "rb")) == NULL){ fprintf(stderr, "Can't open %s in read mode\n", file_name1); exit(-1); } if((fpw = fopen(file_name2, "wb")) == NULL){ fprintf(stderr, "Can't open %s in write mode\n", file_name2); exit(-1); } ref = (FRAME *)malloc(sizeof(FRAME)); /* read from file */ for(frame_num=0; frame_num<FN; frame_num++){ for(i = 0; i<x_size*y_size; i++){ ref->Y[i] = getc(fpr); } for(i = 0; i<x_size*y_size/4; i++){ ref->U[i] = getc(fpr); } for(i = 0; i<x_size*y_size/4; i++){ ref->V[i] = getc(fpr); } /* write to file */ fwrite(ref,1,sizeof(FRAME),fpw); } fclose(fpr); fclose(fpw); free(ref); return 0; }

みんなの回答

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.2

こんにちは。 今の状態ですと、単なるファイルコピーですね。 まずは、現在面単位で処理しているところを、行と列に分ける事を考えてみられてはどうでしょうか。 移動するのはそれからですね。 それで、移動するためには次の点をクリアにする必要がありますが、いかがでしょうか。 ・プレーンごとのデータフォーマットはどうなっているか  (352ピクセルが288ライン綺麗に並んでいる?) ・1ピクセル移動するとなると、YとUVの間にズレが生じるが、どうするか。   案1 UとVを真面目に計算しなおす。   案2 2ピクセルずつ移動する。   案3 色差プレーンはズレても目をつぶる。     (Y 2ピクセルごとにUVは1ピクセル移動する)  といった作戦が必要かと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

データのフォーマットはどのようになっているのでしょうか? つまり, その画像ファイル中にそれぞれのピクセルの情報がどのように入っているのでしょうか?

関連する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に書き出そうとしているのですが、・・・・・・の箇所には公式を当てはめていけばいいんでしょうか?? すみませんがよろしくお願いします。。。。。。

  • 行毎の黒のドット(ピクセル)数を教えていただけませんか?

    開発環境Microsoft Visual Studio .NET 2003 2値画像を読み込んだ時、各行毎の黒のピクセル(ドット)数を表示する プログラムを組もうとしているのですがわかりません。 画像読み込みまではできたのですがその後のプログラムがわかりません 誰か組んでいただけないでしょうか? #include <stdio.h> #include <process.h> #define Y_SIZE 3648 // 処理できる最大画像 #define X_SIZE 3648 #define HIGH 255 // 画像の最大強度値 #define LOW 0 // 画像の最小強度値 #define LEVEL 256 // 画像の強度レベル値 // BMPファイルのフォーマットに従って用意した変数 typedef unsigned short WORD; typedef unsigned long DWORD; WORD bfType; DWORD bfSize; WORD bfReserved1, bfReserved2; DWORD bfOffBits; DWORD biSize, biWidth, biHeight; WORD biPlanes, biBitCount; DWORD biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant; unsigned char image_in[Y_SIZE][X_SIZE][3]; // 入力カラー画像配列 unsigned char image_out[Y_SIZE][X_SIZE][3]; //出力カラー画像配列 unsigned char image_bw[Y_SIZE][X_SIZE]; //濃淡画像配列 unsigned char data_rgb[Y_SIZE][X_SIZE][3]; // RGB画像配列 //******************************************** // 24Bitビットマップファイル読み込み * //******************************************** void readBMP( char *filename, // BMPファイル名 unsigned char image[Y_SIZE][X_SIZE][3] // 24ビットRGB画像配列 ) { FILE *fp; int i, j, k; // ファイルオープン if ((fp = fopen(filename, "rb"))==NULL) { printf("readBmp: Open error!\n"); exit(1); } printf("input file : %s\n", filename); // ヘッダー情報読み込む fread(&bfType, sizeof(bfType), 1, fp); fread(&bfSize, sizeof(bfSize), 1, fp); fread(&bfReserved1, sizeof(bfReserved1), 1, fp); fread(&bfReserved2, sizeof(bfReserved2), 1, fp); fread(&bfOffBits, sizeof(bfOffBits), 1, fp); fread(&biSize, sizeof(biSize), 1, fp); fread(&biWidth, sizeof(biWidth), 1, fp); fread(&biHeight, sizeof(biHeight), 1, fp); fread(&biPlanes, sizeof(biPlanes), 1, fp); fread(&biBitCount, sizeof(biBitCount), 1, fp); fread(&biCompression, sizeof(biCompression), 1, fp); fread(&biSizeImage, sizeof(biSizeImage), 1, fp); fread(&biXPelsPerMeter, sizeof(biXPelsPerMeter), 1, fp); fread(&biYPelsPerMeter, sizeof(biYPelsPerMeter), 1, fp); fread(&biClrUsed, sizeof(biClrUsed), 1, fp); fread(&biClrImportant, sizeof(biClrImportant), 1, fp); // RGB画像データ読み込む for (i=0; i<(int)biHeight; i++) for (j=0; j<(int)biWidth; j++) { for (k=0; k<3; k++) { //fread(&image[i][j][2-k], 1, 1, fp); fread(&image[biHeight-i][j][2-k], 1, 1, fp); } } fclose(fp); } //********************************************** // RGBカラー画像を256諧調白黒濃淡画像へ変換 * //********************************************** void BMPto256BW( unsigned char image[Y_SIZE][X_SIZE][3], unsigned char image_bw[Y_SIZE][X_SIZE] ) { int y, x, a; for (y=0; y<(int)biHeight; y++) for (x=0; x<(int)biWidth; x++) { a = (int)(0.3*image[y][x][0] + 0.59*image[y][x][1] + 0.11*image[y][x][2]); if (a<LOW) a = LOW; if (a>HIGH) a = HIGH; image_bw[y][x] = a; } } //***************************************** //各行の黒色判定 //***************************************** //**************************************** // 白黒濃淡画像配列のコピー * //**************************************** void imageCopyBW( unsigned char image1[Y_SIZE][X_SIZE], unsigned char image2[Y_SIZE][X_SIZE] ) { int x, y; for (y=0; y<(int)biHeight; y++) for (x=0; x<(int)biWidth; x++) image2[y][x] = image1[y][x]; } void main(void) { char input[100], output[100]; int intensity; printf("入力画像ファイル名(*.bmp):"); scanf("%s", input); readBMP(input, image_in); // 画像の入力,RGB24ビットカラーBMP画像を配列に格納 //一列各行の黒色の数出力 }

  • YUV⇔RGB変換がうまくいきません。

    24bppRaw(R,G,Bの順番)を以下の式でYUVに変換します。 layer[i+j]がRでlayer[i+j+1]がGでlayer[i+j+2]がBです。 Y=(unsigned char)(0.257*layer[i+j]+0.504*layer[i+j+1]+0.098*layer[i+j+2]+16); U=(unsigned char)(-0.148*layer[i+j]-0.291*layer[i+j+1]+0.439*layer[i+j+2]+128); V=(unsigned char)(0.439*layer[i+j]-0.368*layer[i+j+1]-0.071*layer[i+j+2]+128); そのあとにYUVをRGBのrawに以下の式で変換します。 Y=layer[i+j]; U=layer[i+j+1]-128; V=layer[i+j+2]-128; R=(unsigned char)(1.164*(Y-16)+1.596*V); B=(unsigned char)(1.164*(Y-16)+2.018*U); G=(unsigned char)(1.164*(Y-16)-0.391*U-0.813*V); しかし元のRGBにはならず画像がおかしくなります。 もちろんオーバーフロー、アンダーフローなどは丸めています。 どのような式を用いれば、RGB⇔YUV 相互変換ができるのが ご教授ください。もう半年くらい随分迷っています。 ダイレクトに式だけ提示いただけるだけで結構なので よろしくおねがいいたしますm(___)m 参考HP http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html http://www.sm.rim.or.jp/~shishido/yuv.html

  • RGB→YUV変換のプログラム

    RGB→YUV変換を行っているのですが、 うまくいきません。 以下であっているのでしょうか? //RGB > YUV変換 void RGBtoYUV(char *filename,int width,int height) { FILE *fpt,*fpt_output; unsigned char *Input,*head; unsigned char Y=0,U=0,V=0; int i,j,b_flag=1; int modification=0; modification=width%4; //ファイルのオープン fopen_s(&fpt,filename,"rb"); if(fpt==NULL) { char DebugStr[256]; wsprintf(DebugStr,"%sが存在しません",filename); MessageBox(NULL,DebugStr,"File Error",MB_OK); } else { fopen_s(&fpt_output,"YUV.bmp","wb"); //ヘッダ情報の書き込み head=(unsigned char*)malloc(54); fread(head,sizeof(unsigned char),54,fpt); fwrite(head,sizeof(unsigned char),54,fpt_output); free(head); Input=(unsigned char*)malloc(3*width*height*sizeof(unsigned char)); //メモリに展開 for(i=0;i<height;i++) { fread(&Input[i*(3*width)],sizeof(unsigned char),3*width,fpt); fseek(fpt,modification,SEEK_CUR); } fclose(fpt);//Inputファイルのクローズ for(i=0;i<3*width*height;i+=3*width) { for(j=0;j<3*width;j+=3) { Y=(unsigned char)(0.299*Input[i+j+2]+0.587*Input[i+j+1]+0.114*Input[i+j]); U=(unsigned char)(-0.169*Input[i+j+2]-0.3316*Input[i+j+1]+0.500*Input[i+j]); V=(unsigned char)(0.500*Input[i+j+2]-0.4186*Input[i+j+1]-0.0813*Input[i+j]); //Y if(Y<0) { Input[i+j]=0x00; } else if(Y>255) { Input[i+j]=0xff; } else { Input[i+j]=Y; } //U if(U<0) { Input[i+j+1]=0x00; } else if(U>255) { Input[i+j+1]=0xff; } else { Input[i+j+1]=U; } //V if(V<0) { Input[i+j+2]=0x00; } else if(V>255) { Input[i+j+2]=0xff; } else { Input[i+j+2]=V; } } }//i fseek(fpt_output,54,SEEK_SET); for(i=0;i<height;i++) { fwrite(&Input[3*width*i],sizeof(unsigned char),3*width,fpt_output); //修正値の代入 for(j=0;j<modification;j++) { fwrite("\x000",sizeof(unsigned char),1,fpt_output); } } fclose(fpt_output); free(Input); } } 又 YUV→RGBにすると元の画像に戻らずに困っています。 プログラムに対するご指摘お願いします。 このプログラムはWindowGUIで幅と高さとファイル名を入力して 走らせるプログラムです。24bpp BMPが対象です。

  • らべリnグについての質問です

    数字が書かれた画像を2値化し、ラベリングして数字だけを抜き出して出力したいのですが、どうも上手くいきません。 色々試しても見たのですが、数字だけを取り出すことはできませんでした。 以下のプログラムのどこを直せば、ラベリングされた画像を抜き出すことができるのでしょうか? 一週間やってもできませんでした… 何方か教えて下さると大変助かります #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define Y_SIZE 512 //縦の最大画素数 #define X_SIZE 512 //横の最大画素数 #define HIGH 255 //最大階調値 #define LOW 0 //最小階調値 #define Level 256 #define FileName 256 #define MaxBufferSize 640 #define L_BASE 100 #define Black 1 #define White 2 unsigned char image[Y_SIZE][X_SIZE]; //入力画像用配列 unsigned char label_image[Y_SIZE][X_SIZE]; unsigned char image_h[Y_SIZE][X_SIZE]; int x_size, y_size; int Label=200; long hist[256]; void set(unsigned char image[Y_SIZE][X_SIZE], int xs, int ys, int label); void save(unsigned char output_img[Y_SIZE][X_SIZE],int output_ysize,int output_xsize); void load(void) { 入力画像 } void hist1(unsigned char image_in[Y_SIZE][X_SIZE], int x, int y, long hist[256]) { ヒストグラム処理 } void hist2(long hist[256], unsigned char image_h[Y_SIZE][X_SIZE]) { ヒストグラムを画像化 } void thr(unsigned char image_in[Y_SIZE][X_SIZE], unsigned char image_out[Y_SIZE][X_SIZE], int thresh, int type) { 閾値処理 閾値180 タイプ白 } 画像のラベリング処理 int labeling(unsigned char image_in[Y_SIZE][X_SIZE], unsigned char image_label[Y_SIZE][X_SIZE]) { int i, j, label; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) image_label[i][j] = image_in[i][j]; label = L_BASE; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) { if (image_label[i][j] == HIGH) { if (label >= HIGH) return -1; set(image_label, j, i, label); label++; }} return label - L_BASE; } 連結している画素すべてにラベル付け void set(unsigned char image[Y_SIZE][X_SIZE], int xs, int ys, int label) { int i, j, cnt, im, ip, jm, jp; image[ys][xs] = label; while(1) { cnt = 0; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) if (image[i][j] == label) { im = i-1; ip = i+1; jm = j-1; jp = j+1; if (im < 0) im = 0; if (ip >= Y_SIZE) ip = Y_SIZE-1; if (jm < 0) jm = 0; if (jp >= X_SIZE) jp = X_SIZE-1; if (image[i ][jp] == HIGH) { image[i ][jp] = label; cnt++; } if (image[im][jp] == HIGH) { image[im][jp] = label; cnt++; } if (image[im][j ] == HIGH) { image[im][j ] = label; cnt++; } if (image[im][jm] == HIGH) { image[im][jm] = label; cnt++; } if (image[i ][jm] == HIGH) { image[i ][jm] = label; cnt++; } if (image[ip][jm] == HIGH) { image[ip][jm] = label; cnt++; } if (image[ip][j ] == HIGH) { image[ip][j ] = label; cnt++; } if (image[ip][jp] == HIGH) { image[ip][jp] = label; cnt++; } } if (cnt == 0) break; } save(image,ys,xs); } //ラベリング画像の出力 void save(unsigned char output_img[Y_SIZE][X_SIZE],int output_ysize,int output_xsize) { char f_name[FileName]; FILE *fp; int i, j,n; printf("Output File (*.pgm) : "); scanf("%s",f_name); fp = fopen(f_name, "wb"); fputs( "P5\n", fp ); fputs( "# Created by Image Processing\n", fp ); fprintf( fp, "%d %d\n", output_xsize, output_ysize ); fprintf( fp, "%d\n", HIGH); 画像データの出力 for (i=0; i<output_ysize; i++) for (j=0; j<output_xsize; j++) fputc(output_img[i][j], fp); fclose(fp); } int main(void){ int thresh=180, type=White; 入力画像 load(); ヒストグラム処理 hist1(image, x_size, y_size, hist); ヒストグラム画像化 hist2(hist,image_h); 閾値処理 thr(image, image_h, thresh, type); labeling(image_h, label_image); return 0; }

  • Ç言語でファイルサイズを変更するプログラム

    Ç言語初心者です。visualstudio2010を使用しています。 ファイルサイズ100MBのtest.binをバイナリモードで開き、10GBになるまで0を追加するプログラムを組みたいと思います。 ファイルを読み込んで出力するようには組めたのですが、この手法だとファイルサイズが大きいと時間がかかってしまいます。 現在のソースは以下の様になっているのですが、どうしたらもっと早く終わらせることが出来るでしょうか? また、int型でファイルサイズを取得していますが、ファイルサイズがもっと大きくなったときにint型では足りなくなってしまうのもどうすればいいのか困っています。 ※元ファイルサイズ(test.bin)は例としています。今後?GBサイズになると思います。変更後のファイルサイズは今後10GBくらいまでで考えています。 #include <stdio.h> #include <string.h> #include "stdafx.h" #define KIRO (1024) #define MEGA (KIRO*1024) #define GIGA (MEGA*1024) #define SIZE (100) int main(void) { FILE *fp,*fpw; unsigned char c; unsigned char zero = 0; int i = 0; int filesize; // 元ファイルをバイナリモードで開く fp = fopen( "test.bin", "rb" ); if( fp == NULL ) { printf( "test.binが開けません" ); return 1; } fseek( fp, 0, SEEK_END ); filesize = ftell( fp ); fseek( fp, 0, SEEK_SET ); // 書込み先をバイナリモードで開く fpw = fopen( "test_W.bin", "wb" ); if( fp == NULL ) { printf( "test_W.binが開けません" ); return 1; } while(1) { i++; // 指定サイズになったら終了 if(i > MEGA * SIZE) break; // ファイルサイズまで読み書き if(filesize < i){ // 残りを0で代入 fwrite(&zero, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ }else{ // ファイルの内容を1文字ずつ読み書き fread( &c, sizeof(unsigned char), 1, fp ); /* 1文字ずつ読み込み */ fwrite(&c, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ } printf( "%d番目\n", i ); } printf( "\n" ); fclose(fp); fclose(fpw); return 0; }

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

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

  • 3次元配列でのポインタ

    唐突ですみません。 サイズが640*480の画像を180枚読み込むプログラムをポインタを使って作成しようと考えています。 以下で示すプログラムは画像を読み込むための作成したものですが、エラーが出てしまい実行することができません。 間違えている箇所があればご指摘お願いします。 また、そのほかに効率の良いやり方などがありましたらご教授願います。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define xsize 640 #define ysize 480 #define round 180 #include "Input.h" void Input_task(unsigned char ***In); void main() {   static unsigned char ***In;   int i,j;   In=(unsigned char***)malloc(sizeof(unsigned char)*round);   for(i=0;i<round;i++)   {     In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);     for(j=0;j<ysize;j++)     {       In[i][j]=(unsigned char*)malloc(sizeof(unsigned char)*xsize);     }   }   Input_task(In); } Input.hの中身 void Input_task(unsigned char ***In) {   char filename[30];   int i,j,k;   FILE *fp;   for(i=0;i<round;i++)   {     sprintf(filename,"b20_%04d.raw",i);     fp=fopen(filename,"rb");    for(j=0;j<ysize;j++)     {       for(k=0;k<xsize;k++)       {         *(*(*(In+i)+j)+k)=(unsigned char)getc(fp);       }     }    fclose(fp);   } }

専門家に質問してみよう