アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

「RGB→YUV変換のプログラム」の質問画像

A 回答 (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として処理してやるとかしないと、おかしくなると思います。
    • good
    • 0
この回答へのお礼

アドバイスありがとうございました。
web上を探して1つだけプログラムソースが見つかったのですが
それでもうまくいかなくて質問しました。
ご指摘ありがとうございました。
YUVのUVは範囲が-128~127だというのは初耳でした。
そうすると、画像処理ソフトではうまくさばけないんでしょうかね。
生で-100とか入れても?画像って表示されるのかな。
実験してみます。
いままでRGBで0~255しか扱ったことがなかったです。
画像処理ソフトもその値のピクセルを表示しているのかと
思っていました。

お礼日時:2009/10/20 23:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!