
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が対象です。

No.1ベストアンサー
- 回答日時:
Y,U,Vの計算の仕方がまずいです。
unsigned charですと0~255の範囲の値しか取りませんので、
Y,U,Vが0~255の範囲外の場合オーバーフローが発生し正しい数値ではなくなるので、
shortやintなどの範囲の大きい変数に入れて計算し、丸め処理等を行う必要があります。
あとその計算式の場合Yの範囲は0~255ですが、U,Vの範囲は-128~127です。
今の処理だと、U,Vが0~255の範囲に丸められてしまいます。
あと、U,Vはsigned charの範囲(-128~127)なので、signed charとして処理してやるとかしないと、おかしくなると思います。
アドバイスありがとうございました。
web上を探して1つだけプログラムソースが見つかったのですが
それでもうまくいかなくて質問しました。
ご指摘ありがとうございました。
YUVのUVは範囲が-128~127だというのは初耳でした。
そうすると、画像処理ソフトではうまくさばけないんでしょうかね。
生で-100とか入れても?画像って表示されるのかな。
実験してみます。
いままでRGBで0~255しか扱ったことがなかったです。
画像処理ソフトもその値のピクセルを表示しているのかと
思っていました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列をnビットシフトする
-
3桁区切(コンマ)記号をつけ...
-
double型の値をchar配列に変換...
-
【C言語】テキストファイル内の...
-
CStringをwchar_tに変換したい
-
Microsoft OfficeをDDEで操作
-
fgetsなどのときのstdinのバッ...
-
バイナリファイルをコピーする...
-
制御の方法
-
const unsigned char *Ptn
-
ランダムな英文字の文字列作成
-
RGB→YUV変換のプログラム
-
文字列ポインタを結合
-
C言語のfor文です。 繰り返しの...
-
C言語 バイナリファイルをfloa...
-
int型のchar型への代入について
-
入力された文字列から整数だけ...
-
javaでunsignedは使えないので...
-
for文 アスタリスクで形を作る
-
文字を16進変換
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体の各メンバにfor文からア...
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
C言語のfor文です。 繰り返しの...
-
CStringをwchar_tに変換したい
-
間接参照のレベルが異なっています
-
c++ 文字列を入力して、一文字...
-
C言語の入力した文字を反転させ...
-
charからLPTSTRへの変換方法
-
ネットワークにつながっている...
-
'const char *' 型は 'char *' ...
-
テキストデータをそのままバイ...
-
c言語でユーザ関数を利用して入...
-
atoi( ) の反対をやりたい
-
間接操作のレベルとは
-
-'0'の意味について
-
double型の値をchar配列に変換...
-
Linuxでフォルダ内全ファイル名...
-
配列をnビットシフトする
-
型変換
おすすめ情報