色域转换验证

    图像有损压缩需先转换色域,避免色位或色域错乱。适合计算机显示器的为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. 采用 “伪”数值是为书写和阅读数学公式方便,也可以是无关变量名。

 

posted @ 2019-04-13 13:38  hbg200  阅读(873)  评论(0编辑  收藏  举报