algorytm.org

Implementacja w C/C++



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Model YUV - Implementacja w C/C++
Ocena użytkownikóww: *****  / 1
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 27 listopada 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

YUV - C++/Unit1.cpp:
// Model YUV
// www.algorytm.org
// (c)2007 by Tomasz Lubinski

//---------------------------------------------------------------------------

#include <vcl.h>
#include "math.h"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}

void YUV2RGB(double y, double u, double v, double &r, double &g, double &b)
{
   r = 1*y + 0*u + 1.13983*v;
   g = 1*y -0.39465*u + -0.58060*v;
   b = 1*y + 2.03211*u + 0*v;
   if (r>1) r =1;
   if (g>1) g =1;
   if (b>1) b =1;
   if (r<0) r =0;
   if (g<0) g =0;
   if (b<0) b =0;
}

void RGB2YUV(double &y, double &u, double &v, double r, double g, double b)
{
   y = 0.299*r + 0.587*g + 0.114*b;
   u = 0.493*(b - y);
   v = 0.877*(r - y);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   double r,g,b,y,u,v;
   int step, width, shift_x, shift_y;
   int side, side_sign;

   Model->Canvas->Brush->Color = clWhite;
   Model->Canvas->Rectangle(0, 0, Model->Width, Model->Height);

   width = StrToInt(Width->Text);

   shift_x = Model->Width / 2 - width / 1.5;
   shift_y = width * 1.5 + 50;

   if (black->Checked)
   {
      side = 0;
      side_sign = -1;
   }
   else
   {
      side = 1;
      side_sign = 1;
   }

   for (int i=0; i<width; i++)
   {
      for (int j=0; j<width; j++)
      {
         y = side;
         u = (0.436 - (0.872/width)*i)*side_sign;
         v = (0.615 - (1.23/width)*j)*side_sign;
         YUV2RGB(y, u, v, r, g, b);
         if (i==0 || j==0 ||  j == width -1)
         {
           g = 0;
           b= 0;
           r = 0;
         }
         Model->Canvas->Pixels[i+shift_x][shift_y-j] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }

   for (int i=0; i<width; i++)
   {
      for (int j=0; j<width/2; j++)
      {
         y = (side - j/(width/2.0))*side_sign;
         u = (0.436 - (0.872/width)*i)*side_sign;
         v = (-0.615)*side_sign;
         YUV2RGB(y, u, v, r, g, b);
         if (i==0 || i == width-1 || j == width/2 -1)
         {
           b= 0;
           g = 0;
           r = 0;
         }
         Model->Canvas->Pixels[i+j+shift_x][shift_y-j-width] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }

   for (int i=0; i<width/2; i++)
   {
      for (int j=0; j<width; j++)
      {
         y = (side - i/(width/2.0))*side_sign;
         u = (-0.436)*side_sign;
         v = (0.615 - (1.23/width)*j)*side_sign;
         YUV2RGB(y, u, v, r, g, b);
         if (i==0 || j==0 || i == width/2-1)
         {
           b= 0;
           g = 0;
           r = 0;
         }
         Model->Canvas->Pixels[i+shift_x+width][shift_y-j-i-1] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
      }
   }

   Model->Canvas->MoveTo(shift_x, shift_y + 20);
   Model->Canvas->LineTo(shift_x + width, shift_y + 20);
   Model->Canvas->LineTo(shift_x + width - 5, shift_y + 15);
   Model->Canvas->MoveTo(shift_x + width, shift_y + 20);
   Model->Canvas->LineTo(shift_x + width - 5, shift_y + 25);
   Model->Canvas->TextOutA(shift_x + 10, shift_y + 7, "U");

   Model->Canvas->MoveTo(shift_x - 20, shift_y);
   Model->Canvas->LineTo(shift_x - 20, shift_y - width);
   Model->Canvas->LineTo(shift_x - 25, shift_y - width + 5);
   Model->Canvas->MoveTo(shift_x - 20, shift_y - width);
   Model->Canvas->LineTo(shift_x - 15, shift_y - width + 5);
   Model->Canvas->TextOutA(shift_x - 15, shift_y - 20, "V");

   Model->Canvas->MoveTo(shift_x + width + 2, shift_y + 18);
   Model->Canvas->LineTo(shift_x + width * 1.5 + 2, shift_y + 18 - width / 2);
   Model->Canvas->LineTo(shift_x + width * 1.5 - 5, shift_y + 18 - width / 2);
   Model->Canvas->MoveTo(shift_x + width * 1.5 + 2, shift_y + 18 - width / 2);
   Model->Canvas->LineTo(shift_x + width * 1.5 + 2, shift_y + 25 - width / 2);
   Model->Canvas->TextOutA(shift_x + width + 10, shift_y - 10, "Y");

   Model->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::YButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::UButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::VButtonClick(TObject *Sender)
{
        ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReDrawProbe(TObject *Sender)
{
   double y, u, v, r, g, b;
   Byte *P;

   y = StrToFloat(Y->Text);
   u = StrToFloat(U->Text);
   v = StrToFloat(V->Text);

   ProbeSmall->Canvas->Brush->Color = clWhite;
   ProbeSmall->Canvas->Rectangle(0, 0, ProbeSmall->Width, ProbeSmall->Height);
   ProbeSmall->Picture->Bitmap->PixelFormat = pf32bit;

   if (YButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         y = 1 - i/255.0;
         YUV2RGB(y, u, v, r, g, b);
         P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i];
         for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++)
         {
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }
   else if (UButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         u = 0.436 - i/292.43;
         YUV2RGB(y, u, v, r, g, b);
         P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i];
         for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++)
         {
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }
   else if (VButton->Checked)
   {
      for (int i=0; i<256; i++)
      {
         v = 0.615 - i/207.31;
         YUV2RGB(y, u, v, r, g, b);
         P = (Byte *)ProbeSmall->Picture->Bitmap->ScanLine[i];
         for (int j=0; j<ProbeSmall->Picture->Bitmap->Width; j++)
         {
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }

   y = StrToFloat(Y->Text);
   u = StrToFloat(U->Text);
   v = StrToFloat(V->Text);

   ProbeLarge->Canvas->Brush->Color = clWhite;
   ProbeLarge->Canvas->Rectangle(0, 0, ProbeLarge->Width, ProbeLarge->Height);
   ProbeLarge->Picture->Bitmap->PixelFormat = pf32bit;

   if (YButton->Checked)
   {
      for (int j=0; j<256; j++)
      {
         P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j];
         for (int i=0; i<256; i++)
         {
            u = i/292.43 - 0.436;
            v = j/207.31 - 0.615;
            YUV2RGB(y, u, v, r, g, b);
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }
   else if (UButton->Checked)
   {
      for (int j=0; j<256; j++)
      {
         P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j];
         for (int i=0; i<256; i++)
         {
            y = i/255.0;
            v = j/207.31 - 0.615;
            YUV2RGB(y, u, v, r, g, b);
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }
   else if (VButton->Checked)
   {
      for (int j=0; j<256; j++)
      {
         P = (Byte *)ProbeLarge->Picture->Bitmap->ScanLine[255-j];
         for (int i=0; i<256; i++)
         {
            y = i/255.0;
            u = j/292.43 - 0.436;
            YUV2RGB(y, u, v, r, g, b);
            *P = (Byte)(b*255);
            P++;
            *P = (Byte)(g*255);
            P++;
            *P = (Byte)(r*255);
            P++;
            P++;
         }
      }
   }

   ReDrawRectangle(Sender);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::ReDrawRectangle(TObject *Sender)
{
   double y, u, v, r, g, b;
   y = StrToFloat(Y->Text);
   u = StrToFloat(U->Text);
   v = StrToFloat(V->Text);

   YUV2RGB(y, u, v, r, g, b);

   Probe->Canvas->Brush->Color = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
   Probe->Canvas->Rectangle(0, 0, Probe->Width, Probe->Height);

   if (YButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, (1-y)*255-3, 13, (1-y)*255+3);
      ProbeLarge->Canvas->Ellipse((u+0.436)*292.43-3, (0.615-v)*207.31-3, (u+0.436)*292.43+3, (0.615-v)*207.31+3);
   }
   else if (UButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, (0.436-u)*292.43-3, 13, (0.436-u)*292.43+3);
      ProbeLarge->Canvas->Ellipse(y*255-3, (0.615-v)*207.31-3, y*255+3, (0.615-v)*207.31+3);
   }
   else if (VButton->Checked)
   {
      ProbeSmall->Canvas->Ellipse(5, (0.615-v)*207.31-3, 13, (0.615-v)*207.31+3);
      ProbeLarge->Canvas->Ellipse(y*255-3, (0.436-u)*292.43-3, y*255+3, (0.436-u)*292.43+3);
   }
}

//---------------------------------------------------------------------------
void __fastcall TForm1::YChange(TObject *Sender)
{
   ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::UChange(TObject *Sender)
{
   ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::VChange(TObject *Sender)
{
   ReDrawProbe(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ProbeLargeMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
   if (YButton->Checked)
   {
      this->U->Text = FloatToStr(X/292.43 - 0.436);
      this->V->Text = FloatToStr(0.615 - Y/207.31);
   }
   else if (UButton->Checked)
   {
      this->Y->Text = FloatToStr(X/255.0);
      this->V->Text = FloatToStr(0.615 - Y/207.31);
   }
   else if (VButton->Checked)
   {
      this->Y->Text = FloatToStr(X/255.0);
      this->U->Text = FloatToStr(0.436 - Y/292.43);
   }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ProbeSmallMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
   if (YButton->Checked)
   {
      this->Y->Text = FloatToStr(1 - Y/255.0);
   }
   else if (UButton->Checked)
   {
      this->U->Text = FloatToStr(0.436 - Y/292.43);
   }
   else if (VButton->Checked)
   {
      this->V->Text = FloatToStr(0.615 - Y/207.31);
   }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormActivate(TObject *Sender)
{
ReDrawProbe(Sender);
Button1Click(Sender);
Layers();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Layers()
{
   double r, g, b, y, u, v;
   TColor color;
   for (int i=0; i<AllLayers->Width; i++)
   {
      for (int j=0; j<AllLayers->Height; j++)
      {
          color = AllLayers->Canvas->Pixels[i][j];
          r = (color & 0xFF) / 255.0;
          g = ((color & 0xFF00) >> 8) / 255.0;
          b = ((color & 0xFF0000) >> 16) / 255.0;
          RGB2YUV(y, u, v, r, g, b);
          YUV2RGB(y, 0, 0, r, g, b);
          LayerY->Canvas->Pixels[i][j] = (TColor)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16);
          YUV2RGB(0, u, 0, r, g, b);
          LayerU->Canvas->Pixels[i][j] = (TColor)((int)(255 - (u+0.416)*306) << 8) + ((int)((u+0.416)*306) << 16);
          YUV2RGB(0, 0, v, r, g, b);
          LayerV->Canvas->Pixels[i][j] = (TColor)((v+0.615)*207) + ((int)(255 - (v+0.615)*207) << 8);
      }
   }
}

//---------------------------------------------------------------------------
Dodaj komentarz