色域转换验证
图像有损压缩需先转换色域,避免色位或色域错乱。适合计算机显示器的为YCrCb或YCbCr,jpg采用的是这一标准,H264色域YUV也是采用的YCbCr标准。YCrCb具有色域宽,转换损失小的特点。这里采用的是RGB888格式,转换为YCrCb,再转换为RGB888格式,或YCrCb转换为RGB888格式。通过相互转换,验证理解算式。
1. 源文件
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- float Od299 = 0.299; float Od587 = 0.587; float Od114 = 0.114; float Od4187 = 0.4187; float Od0813 = 0.0813; float NOd1687 = -0.1687; float Od3313 = 0.3313; float Od5 = 0.5; float fv128 = 128; float Id402 = 1.402; float Id772 = 1.772; float Od34414 = 0.34414; float Od71414 = 0.71414; void __fastcall TForm1::SpeedButton1Click(TObject *Sender)//分解 { float fR,fG,fB,fY,fCr,fCb; // 输入RGB fR = (float)Edit1->Text.ToInt(); fG = (float)Edit2->Text.ToInt(); fB = (float)Edit3->Text.ToInt(); // 分解 fY = Od299 * fR + Od587 * fG + Od114 * fB; // Y = (0.299 * R) + (0.587 * G) + (0.114 * B) fCb = NOd1687 * fR - Od3313 * fG + Od5 * fB + fv128;// Cb = (-0.1687 * R) - (0.3313 * G) + (0.5 * B) + 128 fCr = Od5 * fR - Od4187 * fG - Od0813 * fB + fv128; // Cr = (0.5 * R) - (0.4187 * G) - (0.0813 * B) + 128 // 显示 Edit4->Text = IntToStr((int)fY); Edit5->Text = IntToStr((int)fCr); Edit6->Text = IntToStr((int)fCb); } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButton2Click(TObject *Sender)//合成 { float fR,fG,fB,fY,fCr,fCb; // 输入Y,Cr,Cb fY = (float)Edit4->Text.ToInt(); fCr = (float)Edit5->Text.ToInt(); fCb = (float)Edit6->Text.ToInt(); // 合成 fR = fY + (Id402 * (fCr - fv128)); // R = Y + (1.402 * (Cr - 128)) fG = fY - (Od34414 * (fCb - fv128)) - (Od71414 * (fCr - fv128)); // G = Y - (0.34414 * (Cb - 128)) - (0.71414 * (Cr - 128)) fB = fY + (Id772 * (fCb - fv128)); // B = Y + (1.772 * (Cb - 128)) // 显示 Edit7->Text = FormatFloat("0", fR); Edit8->Text = FormatFloat("0", fG); Edit9->Text = FormatFloat("0", fB); } //---------------------------------------------------------------------------
2. 完整压缩验证文件
(暂未找到存储压缩文件的地方)
3. 程序窗口
4. 使用
RGB输入0-255数值,YCrCb分解RGB输入的数值,RGB合成YCrCb分解的数值。没有抗错处理,输入不得超出0-255数值。
5. 算术控制
此验证是为后续汇编SSE打基础,有意控制浮点截断,使之能够快速浮点处理。采取以下措施:
1. 不留浮点尾数
2. RGB转换为YCrCb截断尾数
3. YCrCb转换为RGB四舍五入尾数
4. 调整源代码可以达到自己要的结果趋向
6. 结论
1. 所有转换不超过255,不需要防止超出处理
2. 还原RGB出现负数,需要防止负数处理
源程序在Win10操作系统C++Builder6编译通过。
注:
1. 采用“伪”数值是为避免直接输入漏洞,比如编译器默认双精度浮点,实际使用单精度浮点,直接输入结果是错误的。
2. 如果商业使用,必须重新验证,验证每个数值的正确性。
3. “伪”数值的大写英文“O"代表数值”0",大写英文“N"代表负值”-",大写英文“I"代表数值”1",小写英文“d"代表浮点数值的”.",其他数值不变。在浏览器C++源代码大写英文“O"和数值”0"很相近,不要弄错。
4. 采用 “伪”数值是为书写和阅读数学公式方便,也可以是无关变量名。