2016年12月28日 星期三

02360635 鄭瑞銘 Homework 6

YUV色彩調整

這功能的操作主要是先產生一個可以設定YUV色彩值的畫布(實際上只選擇UV值,Y值預設128),然後根據RGBYUV的色彩值轉換公式來製作此功能,不過在執行YUV色彩調整時,還需要多一個動作去取得每一個圖片像素的Y(RGB值轉Y)

RGBYUV色彩轉換公式,這裡使用整數型態的轉換方法:





根據YUV色彩調整所新增的變數宣告:

BYTE *bPictureImageYUVRow;  //產生畫布所使用的變數,
int iR,iG,iB;
int iY,iU,iV;
int iC,iD,iE;

以及新增的TImage元件命名為imgUV,用來產生選取YUV色彩值的畫布。



產生YUV色彩值畫布的程式碼我把它放在開啟圖片的函式裏頭,X軸代表U值、Y軸代表V值,如下:

//YUV色彩值畫布,Y = 128
imgUV->Picture->Bitmap->Height = 256;
imgUV->Picture->Bitmap->Width = 256;
imgUV->Picture->Bitmap->PixelFormat = pf24bit;
for (i = 0; i < 256; i++)
{
    bPictureImageYUVRow = (Byte*)imgUV->Picture->Bitmap->ScanLine[i];
    for ( j = 0; j < 256; j++)
    {
    iY = 128;
    iU = j;
    iV = i;

    iC = iY - 16;
    iD = iU - 128;
    iE = iV - 128;

    iR = ( (298 * iC          + 409*iE + 128) >> 8 );
    //防止溢位
    if ( iR > 255 )
        iR = 255;
    else if ( iR < 0 )
        iR = 0;

    iG = ( (298*iC - 100*iD - 208*iE + 128) >> 8 );
    //防止溢位
    if ( iG > 255 )
        iG = 255;
    else if ( iG < 0 )
        iG = 0;

    iB = ( (298*iC + 516*iD          + 128) >> 8 );
    //防止溢位
    if ( iB > 255 )
        iB = 255;
    else if ( iB < 0 )
        iB = 0;

    bPictureImageYUVRow[ 3 * j + 2 ] = iR;
    bPictureImageYUVRow[ 3 * j + 1 ] = iG;
    bPictureImageYUVRow[ 3 * j + 0 ] = iB;
    }
}
imgUV->Refresh();



執行YUV色彩調整的函式根據imgUV發生Mouse Down事件時啟用,程式如下:

void __fastcall TForm1::imgUVMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
iU = X;
iV = Y;

for (i = 0; i < iImageHeight; i++)
{
    bPictureImageShowRow = (Byte*)imgShow->Picture->Bitmap->ScanLine[i];
    bPictureImageOriginRow = (Byte*)imgOrigin->Picture->Bitmap->ScanLine[i];
    for ( j =0; j < iImageWidth; j++)
    {
        bPictureImageShowRow[ 3 * j + 0] = bPictureImageOriginRow[ 3 * j + 0 ];
        bPictureImageShowRow[ 3 * j + 1] = bPictureImageOriginRow[ 3 * j + 1 ];
        bPictureImageShowRow[ 3 * j + 2] = bPictureImageOriginRow[ 3 * j + 2 ];

        iY = ( ( 66 * int( bPictureImageShowRow[3*j+2] )
           + 129 * int( bPictureImageShowRow[3*j+1] )
           +  25 * int( bPictureImageShowRow[3*j+0] ) + 128 ) >>8 ) + 16;

        iC = iY - 16;
        iD = iU - 128;
        iE = iV - 128;

        iR = ( (298*iC          + 409*iE + 128) >> 8 );
        //防止溢位
        if ( iR > 255 )
            iR = 255;
        else if ( iR < 0 )
            iR = 0;

        iG = ( (298*iC - 100*iD - 208*iE + 128) >> 8 );
        //防止溢位
        if ( iG > 255 )
            iG = 255;
        else if ( iG < 0 )
            iG = 0;

        iB = ( (298*iC + 516*iD          + 128) >> 8 );
        //防止溢位
        if ( iB > 255 )
            iB = 255;
        else if ( iB < 0 )
            iB = 0;


        bPictureImageShowRow[3*j+0] = iB;
        bPictureImageShowRow[3*j+1] = iG;
        bPictureImageShowRow[3*j+2] = iR;
    }
}
imgShow->Refresh();

}


部分運行畫面:







可以的話之後想在YUV畫布上產生一個十字記號,用來標示自己剛剛點選的UV值是哪一個。

沒有留言:

張貼留言