Documente Academic
Documente Profesional
Documente Cultură
Tema Proiectului: Aplicatie ce implementeaza diferite transformri geometrice asupra unor imagini
Cuprins:
I.Noiuni Teoretice II. Transformri geometrice II.1. Translaia ..................................................................................... 4 II.2. Zoom IN/Out ...........................................................................5 II.3. Oglindirea .....................................................................................6 II.4. Rotirea ..........................................................................................8 II.5. Negativarea ...................................................................................9 II.6. Histograma Imagine ...................................................................10 II.7. Histograma Linie ........................................................................11 II.8. Gray Scale ..................................................................................13 III. Bibliografie ............................................................................................14
I. Notiuni Teoretice
Imaginile pot suporta mai multe tipuri de transformri.O clasificare a acestor operaii este dat n continuare:
transformri geometrice: translaie, scalare, rotaie, oglindire, forfecare. Aceste
transformri modific poziia, dimensiunea i/sau forma obiectelor, raportate la un sistem de coordonate fix (care nu este afectat de transformare);
transformri ale sistemului de coordonate - obiectele unui ansamblu 2D sau 3D
pot fi considerate fixe n plan sau n spatiu; coordonatele lor se modific n cazul transformrii sistemului de coordonate n care sunt definite, prin translaia, rotaia, oglindirea axelor sau prin scalarea unitii de msur ataate uneia dintre axe;
transformarea de proiecie: o transformare specific fiecrui tip de proiecie, prin care se obine o
dreptunghiular din plan) ntr-o poart de afiare (zona dreptunghiular din ecran);
transformarea de vizualizare 3D: transformare compus din mai multe
transformri elementare, prin care se obin coordonatele n spatiul ecran ale unui obiect tridimensional.
II.1. Translatia
Translaia este transformarea ce deplaseaz toate punctele unui obiect cu un anumit deplasament fa de poziia iniial. Rezultatul obinut prin translatarea punctului P(x,y) este punctul P'(x,y), care verific sistemul: x'=x+Tx i y'=y+Ty unde Tx, Ty sunt deplasamentele pe abscis i ordonat .Forma vectorial a sistemului este: P'=P+T,adic: [x',y'] = [x,y]+[Tx,Ty]. Codul n C++ Builder care implementeaz operaia de translaie este urmtorul: void __fastcall TfrmTranslatie::cmdOKClick(TObject *Sender) { int x_t,y_t ; x_t=x->Text.ToInt(); y_t=x->Text.ToInt(); RGBTRIPLE* pixels; for( int y=0; y<source->Height; y++ ) { pixels = (RGBTRIPLE*)source->ScanLine[y]; for (int x=0; x<source->Width; x++) { dest->Canvas->Pixels[x][y] = source->Canvas->Pixels[x-x_t][y-y_t]; } } //Asigneaza bitmapul destinatie inapoi catre imgImage frmMain->imgImage->Picture->Bitmap = dest; delete dest; delete source; }
La apsarea opiunii Translate din meniul Options apare o fereastr in care trebuie introduse deplasamentele pe axa Ox i Oy. Dup ce ai introdus datele, apsnd pe butonul OK n fereastra principal se va observa cum imaginea a fost translatat cu valorile introduse. Translaia se realizeaz astfel: se parcurge toat[ imaginea i coordonatele fiecrui pixel sunt modificate n funcie de deplasamentul dat de utilizator.
Zoom-ul IN prin metoda multiplicrii pixelilor se realizeaz selectnd opiunea Zoom In din meniul Zoom. Codul n Borland C++ Builder cerealizeaz Zoom IN prin multiplicarea pixelilor este: void __fastcall TfrmMain::mnuZoomInClick(TObject *Sender) { if( imgImage->Picture->Bitmap->Empty ==true ) return; Graphics::TBitmap* source = new Graphics::TBitmap(); Graphics::TBitmap* dest = new Graphics::TBitmap(); source->Assign(imgImage->Picture->Bitmap); source->PixelFormat =imgImage->Picture->Bitmap->PixelFormat; dest->Height = source->Height; dest->Width = source->Width;
dest->PixelFormat = source->PixelFormat; RGBTRIPLE* pixels; TColor color; int i,j,pozX,pozY; float xx,yy; xx=source->Width/2; yy=source->Height/2; pozY =0; for( int y=0; y<source->Height; y++ ) { pozX=0; pixels = (RGBTRIPLE*)source->ScanLine[y]; for (int x=0; x<source->Width; x++) { for (i=0; i<=1; i++) for (j=0; j<2; j++) dest->Canvas->Pixels[pozX+i-xx][pozY+j-yy] = TColor(RGB(pixels[x].rgbtRed,pixels[x].rgbtGreen,pixels[x].rgbtBlue)); pozX = pozX + 2; } pozY = pozY + 2; } imgImage->Picture->Bitmap = dest; delete dest; delete source; zoom=0; } Zoom-ul Out aupra imaginilor se realizeaz prin metoda de reducere a numrlui de pixeli. Se nlocuiesc 4 pixeli vecini din imaginea original cu un singur pixel n imaginea rezultat . Codul de realizare a acestei funcii de Zoom OUT prin metoda reducerii numrului de pixeli este : { Graphics::TBitmap* source = new Graphics::TBitmap(); Graphics::TBitmap* dest = new Graphics::TBitmap(); source->Assign(imgImage->Picture->Bitmap); source->PixelFormat = imgImage->Picture->Bitmap->PixelFormat; dest->Height = source->Height; dest->Width = source->Width; dest->PixelFormat = source->PixelFormat; RGBTRIPLE* pixels;
TColor color; int i,j,pozX,pozY; pozY =0; for( int y=0; y<source->Height; y+=2 ) { pozX=0; pixels = (RGBTRIPLE*)source->ScanLine[y]; for (int x=0; x<source->Width; x+=2) { dest->Canvas->Pixels[pozX][pozY ] = TColor(RGB(pixels[x].rgbtRed,pixels[x].rgbtGreen,pixels[x].rgbtBlue)); pozX = pozX + 1; } pozY = pozY + 1; } imgImage->Picture->Bitmap = dest; delete dest; delete source; } Pentru aplicaia de fa acest yoom Out pentru o imagine se realizeaz selectnd opiunea Zoom Out din meniul Zoom.
b). Zoom IN/OUT realizat prin redimensionarea controlului imagine. Acest tip de Zoom se realizeaz la apsarea apsarea butoanelor + i - . Codul de implementare a zoom-ului const n modificarea dimensiunii controlului imagine la fiecare apasare a butoanelor + i -. void __fastcall TfrmMain::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if( imgImage->Picture->Bitmap->Empty ) return; if( Key == VK_ADD ) { imgImage->Width = imgImage->Width + 50; imgImage->Height = imgImage->Height + 50; imgImage->Stretch = true; } if( Key == VK_SUBTRACT ) { if( imgImage->Width - 50 > 20 && imgImage->Height - 50 > 20 ) { imgImage->Width = imgImage->Width - 50; imgImage->Height = imgImage->Height - 50; imgImage->Stretch = true; } } }
II.3. Oglindirea
Este operatia de transformare a unei imagini originale intr-o imagine finala prin reflectarea fiecarui element ( x1, y1) din imaginea initiala in ( x2, y2 ), fata de o axa indicata de utilizator. Cazuri particulare II.4.1. reflexia fata axa verticala pe abscisa x0 x2= -x1+(2*x0) y2=-y1 II.4.2. reflexia fata axa orizontala de coordonata y0 x2=-x1 y2= -y1+(2*y0) II.4.3. reflexia fata de o axa orientata in orice directie si trecand prin ( x0, y0 ) unde: x2= x1+2**(-sin()) y2= y1+2**(cos()) unde = (x1- x0)* sin()- (y1- y0)* cos() Codul surs pentru obinerea oglindirii este urmtorul: void __fastcall TfrmMain::mnuMirrorClick(TObject *Sender) { if( imgImage->Picture->Bitmap->Empty ==true ) return; Graphics::TBitmap *source = new Graphics::TBitmap; source->Assign( imgImage->Picture->Bitmap ); source->PixelFormat = imgImage->Picture->Bitmap->PixelFormat; // crearea si stabilirea unui bitmap destinatie temporar Graphics::TBitmap *dest = new Graphics::TBitmap; dest->Width = source->Width; dest->Height = source->Height; dest->PixelFormat = source->PixelFormat; RGBTRIPLE* pixels; TColor color; for (int x=0; x<source->Width; x++) { for (int y=0; y<source->Height; y++) 9
{ dest->Canvas->Pixels[source->Width-x][y]=source->Canvas->Pixels[x][y]; } } //Asigneaza bitmapul destinatie inapoi catre imgImage imgImage->Picture->Bitmap = dest; delete dest; delete source; } Pt fiecare pixel dinimagine se modific doar poziia pe Ox,poziia pe Oy rmne aceeai ca si la imaginea iniial. n urma efecturii unui click pe opiunea Mirror din meniul Options se realizeaz oglindirea imaginii.
10
II.4. Rotirea
Rotirea reprezinta deplasarea unui punct de imagine ( pixel ) din pozitia ( x1, y1 ) a imaginii de intrare in pozitia ( x2, y2 ) a imaginii de iesire, rotind in jurul originii O cu cu unghiul . Operatia este definita de relatiile: x2=cos()*(x1- x0)- sin()*(y1- y0)+ x0 y2=sin()*(x1- x0)+ cos()*(y1- y0)+ y0 La fiecare apsare cu mouse-ul pe meniul Rotate se roteste imaginea cu 90 de grade. void __fastcall TfrmMain::mnuRotateClick(TObject *Sender) { if( imgImage->Picture->Bitmap->Empty ==true ) return; Graphics::TBitmap* Source = new Graphics::TBitmap(); Graphics::TBitmap* Dest = new Graphics::TBitmap(); Source->Assign( imgImage->Picture->Bitmap ); Source->PixelFormat = imgImage->Picture->Bitmap->PixelFormat; Dest->Width = Source->Height; Dest->Height = Source->Width; Dest->PixelFormat = Source->PixelFormat; for (int x=0; x<Source->Width; x++ ) for(int y=0; y<Source->Height; y++ ) Dest->Canvas->Pixels[y][Source->Width-1-x] = Source->Canvas->Pixels[x][y]; imgImage->Width = Dest->Width; imgImage->Height = Dest->Height; imgImage->Picture->Bitmap = Dest; delete Dest; delete Source; }
11
12
nivel de gri
Dac histograma este plat, relativ uniform, putem trage concluzia c s-a realizat o bun utilizare a nivelelor de gri disponibile, i deci este de ateptat ca detaliile din imagine s poat fi observate cu uurin. O histogram cu un maxim al nivelelor de gri ntr-o extremitate a intervalului i o lips a acestora n extremitatea opus va semnala un contrast slab i deci n consecin o pierdere a detaliilor din imagine. Lipsa contrastului poate fi intuit i n cazul unei distribuii relativ uniforme pe ntreaga scar de nivele de gri, dar cu un vrf proeminent ntr-o extremitate
13
} Codul de trasare a histogramei liniei unde s-a facut click este urmtorul: void __fastcall TfrmLineHistogram::FormShow(TObject *Sender) { GroupBox1->Visible=True; int histoSursaR[256]; int histoSursaG[256];
14
int histoSursaB[256]; for( int i = 0; i < 256; i++ ) { histoSursaR[i] = 0; histoSursaG[i] = 0; histoSursaB[i] = 0; } //crearea unui bitmap sursa temporar Graphics::TBitmap *source = new Graphics::TBitmap; source->Assign( frmMain->imgImage->Picture->Bitmap ); source->PixelFormat =frmMain->imgImage->Picture->Bitmap->PixelFormat; RGBTRIPLE* pixels; TColor color; //Calcul histograma Linie SURSA pixels = (RGBTRIPLE*)source->ScanLine[frmMain->y_Line]; for (int x=0; x<source->Width; x++) { histoSursaR[ pixels[x].rgbtRed ]++; histoSursaG[ pixels[x].rgbtGreen ]++; histoSursaB[ pixels[x].rgbtBlue ]++; } delete source; //Desenare histograma Chart1->Series[0]->Clear(); Chart1->Series[1]->Clear(); Chart1->Series[2]->Clear(); for( int i=0; i<256; i++ ) { Chart1->Series[0]->AddY( histoSursaR[i], "", clRed ); Chart1->Series[1]->AddY( histoSursaG[i], "", clGreen ); Chart1->Series[2]->AddY( histoSursaB[i], "", clBlue ); } Chart1->Series[0]->Active = true; Chart1->Series[1]->Active = true; Chart1->Series[2]->Active = true; } Variabila global y_Line este folosit pentru a reine coordonata y a punctului unde s-a facut click de mouse, adic se reine coordonata y a liniei pentrucare se doreste trasarea histogramei..
15
16
Bibliografie
http://apollo.eed.usv.ro/~remus/arhive/PID/Curs3/Curs_3.pdf
17