CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Miniatura obrazu w Timage

Miniatura obrazu w Timage

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Miniatura obrazu w Timage

Nowy postprzez kubawodzu » piątek, 13 lipca 2012, 14:33

Witam
Na wstępie chciałem bardzo podziękować Cyfrowemu Baronowi za wszystkie tutki. Świetna robota bardzo dużo się dowiedziałem i były mi niezwykle pomocne.

Mój program ma za zadanie wczytać zdjęcie i za pomocą filtrów wyznaczyć krawędzie a następnie usuwać szum z obiektów.

mam jednak pytanie. zakładając że mój Timage ma rozmiar 300X450 wczytuje do niego zdjęcie np 3072X2304 to zdjęcie automatycznie zmienia się do proporcji z Timage.(po zapisie obraz ma 300X450)

w jaki sposób zrobić aby rozmiar zdjęcia pozostał taki jak na początku a Timage służyło tylko jako miniatura poglądowa?
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Mironas » piątek, 13 lipca 2012, 15:02

Rozmiar fotki wczytanej do TImage nie jest zmieniany.
W jaki sposób wczytujesz i zapisujesz obraz do/z TImage?
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » piątek, 13 lipca 2012, 15:13

wczytywanie z czego mam problem z konwersja do jpg.
Kod: Zaznacz cały
void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
if(OpenPictureDialog1->Execute())
{
  Obraz->Picture->LoadFromFile(OpenPictureDialog1->FileName);
  try
  {
   BMP->LoadFromFile(OpenPictureDialog1->FileName);
   BMP->PixelFormat = pf32bit;
  }
  catch(...)
  {
   TJPEGImage *jpg = new TJPEGImage();
   jpg->LoadFromFile(OpenPictureDialog1->FileName);

   BMP->Width = jpg->Width;
   BMP->Height = jpg->Height;

   BMP->Canvas->Draw(0, 0, jpg);
   BMP->PixelFormat = pf32bit;
   jpg->Free();
  }
}

}


przy wczytywaniu również było to samo
Kod: Zaznacz cały
if(OpenPictureDialog1->Execute())
{
  Obraz->Picture->LoadFromFile(OpenPictureDialog1->FileName);


zapis ma jako "zapisz" albo "zapisz jako:"

Kod: Zaznacz cały
void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
{
  if (CurrentFile != EmptyStr){
    Wynik->Picture->SaveToFile(CurrentFile);
  }
  else{
   SpeedButton4Click(Sender);
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton4Click(TObject *Sender)
{
 
SavePictureDialog1->Execute();
    CurrentFile = SavePictureDialog1->FileName;
    SpeedButton3Click(Sender);
}
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Mironas » piątek, 13 lipca 2012, 15:29

Zapis obrazu robisz z 'Wynik->...'
A nie podałeś jak przepisujesz grafikę do 'Wynik'. Jeśli procujesz na bitmapie BMP, a miniaturę wyświetlasz w 'TImage* Wynik' to zapis do pliku rób z BMP.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » piątek, 13 lipca 2012, 15:47

BMP w moim przypadku jest tylko do dodawania szumu na Obraz(Image1)
na obraz wynik składa się parę procedur.
wiem gdzie może ewentualnie być problem bo po Twoim zapewnieniu ze wczytany obraz w Image1 musi być poprawnego rozmiaru to zapisałem Obraz(Image1) i faktycznie się zgadza.

o to kod dotyczący przeróbki Obrazu na Wynik
KOD cpp:     UKRYJ  
void __fastcall TForm1::FiltryLiniowe(TObject *Sender)
{
int redsume, greensume, bluesume;
int margines = ((Size-1)/2);
TColor color;
red = (unsigned char**)malloc(Form1->Obraz->Width * sizeof(char*));
green = (unsigned char**)malloc(Form1->Obraz->Width * sizeof(char*));
blue = (unsigned char**)malloc(Form1->Obraz->Width * sizeof(char*));
for (int i=0; i<Form1->Obraz->Width; i++)
    {
       red[i] = (unsigned char*)malloc(Form1->Obraz->Height);
       green[i] = (unsigned char*)malloc(Form1->Obraz->Height);
       blue[i] = (unsigned char*)malloc(Form1->Obraz->Height);
       for (int j=0; j<Form1->Obraz->Height; j++)
          {
             color = Form1->Obraz->Canvas->Pixels[i][j];
             red[i][j] = (color & 0xFF);
             green[i][j] = ((color >> 8) & 0xFF);
             blue[i][j] = ((color >> 16) & 0xFF);
          }
    }

for (int i=margines; i<Obraz->Width-margines; i++)
    for (int j=margines; j<Obraz->Height-margines; j++)
        {
            redsume = 0;
            greensume = 0;
            bluesume = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        redsume += Filter[k*Size+l]*red[i+k-margines][j+l-margines];
                        greensume += Filter[k*Size+l]*green[i+k-margines][j+l-margines];
                        bluesume += Filter[k*Size+l]*blue[i+k-margines][j+l-margines];
                    }
            redsume /= Norm;
            greensume /= Norm;
            bluesume /= Norm;

            if (redsume > 255) redsume = 255;
            else if (redsume < 0) redsume = 0;
            if (greensume > 255) greensume = 255;
            else if (greensume < 0) greensume = 0;
            if (bluesume > 255) bluesume = 255;
            else if (bluesume < 0) bluesume = 0;

            Wynik->Canvas->Pixels[i][j] = (TColor)redsume + (greensume << 8) + (bluesume << 16);
        }

}


Czy pobieranie Form1->Obraz->Width i Form1->Obraz->Height odnosi się do wymiarów okiena Timage?
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Mironas » piątek, 13 lipca 2012, 16:18

Przypuszczam że zamiast:
Obraz->Width, Obraz->Height, Obraz->Canvas
Wynik->Width, Wynik->Height, Wynik->Canvas

powinieneś dać:
Obraz->Picture->Bitmap->Width, Obraz->Picture->Bitmap->Height, Picture->Bitmap->Obraz->Canvas
Wynik->Picture->Bitmap->Width, Wynik->Picture->Bitmap->Height, Wynik->Picture->Bitmap->Canvas

Ponieważ teraz przepisujesz miniaturę a nie faktyczną zawartość.
Ale uwaga! jak będziesz takie operacje robił na dużym pliku to strasznie długo to będzie trwało. Spróbuj wykorzystać ScanLine[x] lub jeśli to nie problem to sprawniejszą bibliotekę graficzną. Ja do takich rzeczy używam Gdiplus - jest dużo szybsze.

Za ten post autor Mironas otrzymał podziękowanie od:
kubawodzu
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Miniatura obrazu w Timage

Nowy postprzez Cyfrowy Baron » piątek, 13 lipca 2012, 17:35

mpsoft ma rację.

Image->Width odnosi się do wymiaru obiektu Image a nie do grafiki wczytanej do Image.
Image->Picture->Bitmap->Width odnosi się do bitmapy wczytanej do Image, ale tylko wtedy gdy w Image znajduje się grafika w formacie BMP, a nie np. JPEG, PNG, itp. Nowsze wersje środowiska obsługują te formaty w Image. Jeżeli w Image nie ma bitmapy to otrzymasz wynik równy 0.

Zamiast do bitmapy możesz odwoływać się do typu TPicture czyli Image->Picture->Width, lub do TGraphic Image->Picture->Graphic->Width.

Jeżeli potrzebujesz pobrać z Image grafikę w formacie innym niż bitmapa to odwołuj się do Graphic.



mpsoft napisał(a):Ja do takich rzeczy używam Gdiplus - jest dużo szybsze.


GDI+ nie jest szybsze od standardowego GDI, gdyż nie korzysta ze wsparcia sprzętowego. To czy operacja na GDI będzie szybka zależy od algorytmu.

Ja do usuwania szumu, czyli de-facto do rozmywania obrazu używam np. takiego kodu:

KOD cpp:     UKRYJ  
#include <math.h>

void __fastcall TblurForm::BlurImage(TImage *Image)
{
 int flt[] = {p1, p1, p1, p1, p2, p1, p1, p1, p1}; /* p1, p2 zmienne typu int wartość ustawiana w moim programie w opcjach, zakres wartości 0-255 */
 int XX[3];

 BYTE   *ptr, *ptru, *ptrd, *ptr1;

 Graphics::TBitmap   *Bitmap    = new   Graphics::TBitmap();
 Graphics::TBitmap   *tmpBitmap = new   Graphics::TBitmap();

 Bitmap->Assign((TPersistent*)Image->Picture->Graphic); /* prosta i szybka konwersja dowolnego formatu graficznego wczytanego do Image na Bitmapę, bez konieczności odrysowywania */

 Bitmap->PixelFormat = pf24bit;

 tmpBitmap->Assign((TPersistent*)Image->Picture->Graphic);
 tmpBitmap->PixelFormat = pf24bit;

 for(int y = 1; y < tmpBitmap->Height - 1; y++)
 {
  ptr  = (BYTE *) Bitmap->ScanLine[y];
  ptr1 = (BYTE *) tmpBitmap->ScanLine[y];
  ptru = (BYTE *) tmpBitmap->ScanLine[y-1];
  ptrd = (BYTE *) tmpBitmap->ScanLine[y+1];

  for(int x = 3; x < (tmpBitmap->Width - 1) * 3; x += 3)
  {
   XX[0] = 0; XX[1] = 0; XX[2] = 0;

   for (int i1 = -1; i1 <= 1; i1++)
    for(int j1 = 0; j1 < 3; j1++)
     XX[j1] += ptr1[x + 3 * i1 + j1] * flt[4 + i1];
   
   for(int i2 = -1; i2 <= 1; i2++)
    for(int j2 = 0; j2 < 3; j2++)
     XX[j2] += ptru[x + 3 * i2 + j2] * flt[1 + i2];
   
   for(int i3 =- 1; i3 <= 1; i3++)
    for(int j3 = 0; j3 < 3; j3++)
     XX[j3] += ptrd[x + 3 * i3 + j3] * flt[7 + i3];
   
   for(int i4 = 0; i4 < 3; i4++)
   {
    XX[i4] = XX[i4] / Div; /* Div zmienna typu int wartość ustawiana w opcjach zakres 0-255 */
    XX[i4] = Math::Max(XX[i4], 0);
    XX[i4] = Math::Min(XX[i4], 255);
    ptr[x + i4] = XX[i4];
   }
  }
 }

 Image->Picture->Graphic = Bitmap;
 delete tmpBitmap;
 delete Bitmap;
}


Jest dość szybki nawet przy dużych obrazach. Działanie filtra dla grafiki o wymiarach HD, czyli 1920x1080 trwa niecałą sekundę, ale to w dużej mierze zależy też od karty graficznej, gdyż GDI korzysta ze wsparcia sprzętowego.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » sobota, 14 lipca 2012, 14:54

okej poprawiłem odniesienia do zdjecia a nie do Timage ale wyskakuje mi błąd "Project raised exception class EAccessViolation with message "Access violation at address 004022F4 in module 'Project.exe" Read of adress 00000000"
z tego co wiem to informuje mnie że odwołuje sie do adresu gdzie nic nie ma. ale nie rozumiem teraz dlaczego. plik graficzny to oczywiście bmp.

sygnalizuje mi tą pętle w tym kodzie:
KOD cpp:     UKRYJ  
                    {
                       redsume += Filter[k*Size+l]*red[i+k-margines][j+l-margines];
                        greensume += Filter[k*Size+l]*green[i+k-margines][j+l-margines];
                        bluesume += Filter[k*Size+l]*blue[i+k-margines][j+l-margines];
                    }
KOD cpp:     UKRYJ  
for (int i=margines; i<Obraz->Picture->Bitmap->Width-margines; i++)
    for (int j=margines; j<Obraz->Picture->Bitmap->Height-margines; j++)
        {
            redsume = 0;
            greensume = 0;
            bluesume = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                       redsume += Filter[k*Size+l]*red[i+k-margines][j+l-margines];
                        greensume += Filter[k*Size+l]*green[i+k-margines][j+l-margines];
                        bluesume += Filter[k*Size+l]*blue[i+k-margines][j+l-margines];
                    }
            redsume /= Norm;
            greensume /= Norm;
            bluesume /= Norm;

            if (redsume > 255) redsume = 255;
            else if (redsume < 0) redsume = 0;
            if (greensume > 255) greensume = 255;
            else if (greensume < 0) greensume = 0;
            if (bluesume > 255) bluesume = 255;
            else if (bluesume < 0) bluesume = 0;

            Wynik->Picture->Bitmap->Canvas->Pixels[i][j] = (TColor)redsume + (greensume << 8) + (bluesume << 16);
        }

}
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Cyfrowy Baron » sobota, 14 lipca 2012, 15:35

W przedstawionym kodzie nie dostrzegam błędu. Może tkwić gdziekolwiek skoro kompilator nie wskazuje linii z błędem. Nie wszystko jednak w zaprezentowanym przez Ciebie kodzie jest jasne. Jaką wartość ma zmienna Size?

Sprawdziłeś przed uruchomieniem pętli, czy Obraz->Picture->Bitmap->Width zwraca wartość większą od 0? Możesz to zrobić tak:

KOD cpp:     UKRYJ  
Caption =Obraz->Picture->Bitmap->Width;
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Miniatura obrazu w Timage

Nowy postprzez Cyfrowy Baron » sobota, 14 lipca 2012, 16:14

Dopiero teraz to zauważyłem! Ty pobierasz wymiary grafiki z obiektu Obraz, a wyniki zapisujesz w obiekcie Wynik. Czy grafiki w obydwu tych obiektach mają ten sam wymiar, czy też może w obiekcie Wynik nie ma wogóle żadnego obrazu?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » sobota, 14 lipca 2012, 16:21

tak wartość wysokości i szerokości odpowiadają wymiarom zdjęcia, które jest wczytane.
Size to rozmiar macierzy filtra. wszystkie dane filtrowe zawarte są w bibliotece. Najgorsze jest to że też nie widzę błędu a jednak coś dziwnego mi się dzieje i nie wiem dlaczego.
cały kod programu wygląda tak:
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma link "CSPIN"
#include "Filtry.h"
#include <cstdlib>
#include <ctime>
#include <jpeg.hpp>
TForm1 *Form1;
int *Filter;
unsigned char **red, **green, **blue;
int Norm;
int Size;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    BMP = new Graphics::TBitmap();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
if(OpenPictureDialog1->Execute())
{
  Obraz->Picture->LoadFromFile(OpenPictureDialog1->FileName);
  try
  {
   BMP->LoadFromFile(OpenPictureDialog1->FileName);
   BMP->PixelFormat = pf32bit;
  }
  catch(...)
  {
   TJPEGImage *jpg = new TJPEGImage();
   jpg->LoadFromFile(OpenPictureDialog1->FileName);

   BMP->Width = jpg->Width;
   BMP->Height = jpg->Height;

   BMP->Canvas->Draw(0, 0, jpg);
   BMP->PixelFormat = pf32bit;
   jpg->Free();
  }
}

}
//---------------------------------------------------------------------------



void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
{
  if (CurrentFile != EmptyStr){
    Wynik->Picture->SaveToFile(CurrentFile);
  }
  else{
   SpeedButton4Click(Sender);
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton4Click(TObject *Sender)
{
 
SavePictureDialog1->Execute();
    CurrentFile = SavePictureDialog1->FileName;
    SpeedButton3Click(Sender);


}
//---------------------------------------------------------------------------




void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
Obraz->Picture->Bitmap->LoadFromResourceName((int)HInstance, "NOWY");
Wynik->Picture->Bitmap->LoadFromResourceName((int)HInstance, "NOWY");
}
//---------------------------------------------------------------------------


void __fastcall TForm1::SpeedButton6Click(TObject *Sender)
{
  SendMessage(Form1->Handle, WM_NEXTDLGCTL, 0, 0);     
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton5Click(TObject *Sender)
{
SendMessage(Form1->Handle, WM_NEXTDLGCTL, 1, 0);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Zakocz1Click(TObject *Sender)
{
    Close();
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FiltryLiniowe(TObject *Sender)
{
int redsume, greensume, bluesume;
int margines = ((Size-1)/2);
TColor color;
red = (unsigned char**)malloc(Obraz->Picture->Bitmap->Width * sizeof(char*));
green = (unsigned char**)malloc(Obraz->Picture->Bitmap->Width * sizeof(char*));
blue = (unsigned char**)malloc(Obraz->Picture->Bitmap->Width * sizeof(char*));
for (int i=0; i<Form1->Obraz->Width; i++)
    {
       red[i] = (unsigned char*)malloc(Obraz->Picture->Bitmap->Height);
       green[i] = (unsigned char*)malloc(Obraz->Picture->Bitmap->Height);
       blue[i] = (unsigned char*)malloc(Obraz->Picture->Bitmap->Height);
       for (int j=0; j<Form1->Obraz->Height; j++)
          {
             color = Obraz->Picture->Bitmap->Canvas->Pixels[i][j];
             red[i][j] = (color & 0xFF);
             green[i][j] = ((color >> 8) & 0xFF);
             blue[i][j] = ((color >> 16) & 0xFF);
          }
    }
Label3->Caption=Obraz->Picture->Bitmap->Width;
//filtr dla obrazu kolorowego
for (int i=margines; i<Obraz->Picture->Bitmap->Width-margines; i++)
    for (int j=margines; j<Obraz->Picture->Bitmap->Height-margines; j++)
        {
            redsume = 0;
            greensume = 0;
            bluesume = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        redsume += Filter[k*Size+l]*red[i+k-margines][j+l-margines];
                        greensume += Filter[k*Size+l]*green[i+k-margines][j+l-margines];
                        bluesume += Filter[k*Size+l]*blue[i+k-margines][j+l-margines];
                    }
            redsume /= Norm;
            greensume /= Norm;
            bluesume /= Norm;

            if (redsume > 255) redsume = 255;
            else if (redsume < 0) redsume = 0;
            if (greensume > 255) greensume = 255;
            else if (greensume < 0) greensume = 0;
            if (bluesume > 255) bluesume = 255;
            else if (bluesume < 0) bluesume = 0;

            Wynik->Picture->Bitmap->Canvas->Pixels[i][j] = (TColor)redsume + (greensume << 8) + (bluesume << 16);
        }

}

void __fastcall TForm1::MinFiltr(TObject *Sender)
{
int redmin, greenmin, bluemin;
Size = 3;
int margines = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margines; i<Obraz->Width-margines; i++)
    for (int j=margines; j<Obraz->Height-margines; j++)
        {
            redmin = 255;
            greenmin = 255;
            bluemin = 255;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        if (redmin > red[i+k-margines][j+l-margines]) redmin = red[i+k-margines][j+l-margines];
                        if (greenmin > green[i+k-margines][j+l-margines]) greenmin = green[i+k-margines][j+l-margines];
                        if (bluemin > blue[i+k-margines][j+l-margines]) bluemin = blue[i+k-margines][j+l-margines];
                    }
            Wynik->Canvas->Pixels[i][j] = (TColor)redmin + (greenmin << 8) + (bluemin << 16);
        }

}

void __fastcall TForm1::MaxFiltr(TObject *Sender)
{
int redmax, greenmax, bluemax;
Size = 3;
int margines = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margines; i<Obraz->Width-margines; i++)
    for (int j=margines; j<Obraz->Height-margines; j++)
        {
            redmax = 0;
            greenmax = 0;
            bluemax = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        if (redmax < red[i+k-margines][j+l-margines]) redmax = red[i+k-margines][j+l-margines];
                        if (greenmax < green[i+k-margines][j+l-margines]) greenmax = green[i+k-margines][j+l-margines];
                        if (bluemax < blue[i+k-margines][j+l-margines]) bluemax = blue[i+k-margines][j+l-margines];
                    }
            Wynik->Canvas->Pixels[i][j] = (TColor)redmax + (greenmax << 8) + (bluemax << 16);
        }

}

//dla algorytmu Hoar'e - obliczanie mediany
int partition(int *c, int a, int b)
{
int e,tmp;
a=a;
b=b;
e=c[a];        //elemennt dzielacy
while (a<b)
        {
        while ((a<b) && (c[b]>=e)) b--;
        while ((a<b) && (c[a]<e)) a++;
        if (a<b)
                {
                tmp=c[a];
                c[a]=c[b];
                c[b]=tmp;
                }
        }
return a;
}

//algorytmu Hoar'e - obliczanie mediany
int med(int *c, int size)
{
//algorytm Hoare'a
int i = 0;
int j = size - 1;
int w = j / 2;
int k;
while (i!=j)
   {
        k=partition(c,i,j);
        k=k-i+1;
        if (k>=w)
                j=i+k-1;
        if (k<w)
           {
                w-=k;
                i+=k;
           }
   }
return c[i];
}

void __fastcall TForm1::MedFiltr(TObject *Sender)
{
int redval[9], greenval[9], blueval[9], m;
Size = 3;
int margines = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margines; i<Obraz->Width-margines; i++)
    for (int j=margines; j<Obraz->Height-margines; j++)
        {
            m = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        redval[m] = red[i+k-margines][j+l-margines];
                        greenval[m] = green[i+k-margines][j+l-margines];
                        blueval[m] = blue[i+k-margines][j+l-margines];
                        m++;
                    }
            Wynik->Canvas->Pixels[i][j] = (TColor)med(redval,9) + (med(greenval,9) << 8) + (med(blueval,9) << 16);
        }

}

void __fastcall TForm1::KuwaharaFiltr(TObject *Sender)
{
double redm[4], greenm[4], bluem[4];  //wartosci srednie
double reds[4], greens[4], blues[4];  //wariancje
int m, mred, mgreen, mblue;
Size = 5;
int margines = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margines; i<Obraz->Width-margines; i++)
    for (int j=margines; j<Obraz->Height-margines; j++)
    {
         //policz srednie
         for (int k=0; k<4; k++)
         {
            redm[k] = 0;
            greenm[k] = 0;
            bluem[k] = 0;
         }
         for (int k=0; k<3; k++)
             for (int l=0; l<3; l++)
             {
                  redm[0] += red[i+k-margines][j+l-margines] / 9.0;
                  redm[1] += red[i+k][j+l-margines] / 9.0;
                  redm[2] += red[i+k-margines][j+l] / 9.0;
                  redm[3] += red[i+k][j+l] / 9.0;

                  greenm[0] += green[i+k-margines][j+l-margines] / 9.0;
                  greenm[1] += green[i+k][j+l-margines] / 9.0;
                  greenm[2] += green[i+k-margines][j+l] / 9.0;
                  greenm[3] += green[i+k][j+l] / 9.0;

                  bluem[0] += blue[i+k-margines][j+l-margines] / 9.0;
                  bluem[1] += blue[i+k][j+l-margines] / 9.0;
                  bluem[2] += blue[i+k-margines][j+l] / 9.0;
                  bluem[3] += blue[i+k][j+l] / 9.0;
             }

         //policz wariancje
         for (int k=0; k<4; k++)
         {
            reds[k] = 0;
            greens[k] = 0;
            blues[k] = 0;
         }
         for (int k=0; k<3; k++)
             for (int l=0; l<3; l++)
             {
                  reds[0] += (red[i+k-margines][j+l-margines] - redm[0]) * (red[i+k-margines][j+l-margines] - redm[0]);
                  reds[1] += (red[i+k][j+l-margines] - redm[1]) * (red[i+k][j+l-margines] - redm[1]);
                  reds[2] += (red[i+k-margines][j+l] - redm[2]) * (red[i+k-margines][j+l] - redm[2]);
                  reds[3] += (red[i+k][j+l] - redm[3]) * (red[i+k][j+l] - redm[3]);

                  greens[0] += (green[i+k-margines][j+l-margines] - greenm[0]) * (green[i+k-margines][j+l-margines] - greenm[0]);
                  greens[1] += (green[i+k][j+l-margines] - greenm[1]) * (green[i+k][j+l-margines] - greenm[1]);
                  greens[2] += (green[i+k-margines][j+l] - greenm[2]) * (green[i+k-margines][j+l] - greenm[2]);
                  greens[3] += (green[i+k][j+l] - greenm[3]) * (green[i+k][j+l] - greenm[3]);

                  blues[0] += (blue[i+k-margines][j+l-margines] - bluem[0]) * (blue[i+k-margines][j+l-margines] - bluem[0]);
                  blues[1] += (blue[i+k][j+l-margines] - bluem[1]) * (blue[i+k][j+l-margines] - bluem[1]);
                  blues[2] += (blue[i+k-margines][j+l] - bluem[2]) * (blue[i+k-margines][j+l] - bluem[2]);
                  blues[3] += (blue[i+k][j+l] - bluem[3]) * (blue[i+k][j+l] - bluem[3]);
             }

         //znajdz najmniejsza wariancje
         mred=0;
         for (int k=1; k<4; k++)
            if (reds[k] < reds[mred])
               mred = k;

         mgreen=0;
         for (int k=1; k<4; k++)
            if (greens[k] < greens[mgreen])
               mgreen = k;

         mblue=0;
         for (int k=1; k<4; k++)
            if (blues[k] < blues[mblue])
               mblue = k;

         Wynik->Canvas->Pixels[i][j] = (TColor)(int)redm[mred] + ((int)greenm[mgreen] << 8) + ((int)bluem[mblue] << 16);
   }

}
//---------------------------------------------------------------------------
//zaladowanie wybranego filtru
void AktywacjaFiltra(int *NewFilter, int size)
{
Form1->StringGrid1->RowCount = size;
Form1->StringGrid1->ColCount = size;
Filter = NewFilter;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
            Form1->StringGrid1->Cells[j][i] = IntToStr(Filter[i+size*j]);

Norm = 0;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
        Norm += Filter[i+size*j];
if (Norm == 0) Norm = 1;
Form1->Label1->Caption = "1/" + IntToStr(Norm) + " *";
Form1->Label1->Visible = TRUE;
Form1->StringGrid1->Visible = TRUE;
Form1->Button3->OnClick = Form1->FiltryLiniowe;
Size = size;
}
//zaladowanie wybranego filtru
void AktywacjaFiltra1(int *NewFilter, int size)
{
Form1->StringGrid1->RowCount = size;
Form1->StringGrid1->ColCount = size;
Filter = NewFilter;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
            Form1->StringGrid1->Cells[j][i] = IntToStr(Filter[i+size*j]);

Norm = 0;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
        Norm += Filter[i+size*j];
if (Norm == 0) Norm = 1;
Form1->Label1->Caption = "1/" + IntToStr(Norm) + " *";
Form1->Label1->Visible = TRUE;
Form1->StringGrid1->Visible = TRUE;
Form1->Button5->OnClick = Form1->FiltryLiniowe;
Size = size;
}
void __fastcall TForm1::ComboBox2Change(TObject *Sender)
{
    switch (ComboBox2->ItemIndex) {
        case 0: AktywacjaFiltra(PIONOWY, PIONOWY_SIZE); break;
        case 1: AktywacjaFiltra(POZIOMY, POZIOMY_SIZE); break;
        case 2: AktywacjaFiltra(UKOSNY1, UKOSNY1_SIZE); break;
        case 3: AktywacjaFiltra(UKOSNY2, UKOSNY2_SIZE); break;
        case 4: AktywacjaFiltra(GRADIENT_E, GRADIENT_E_SIZE); break;
        case 5: AktywacjaFiltra(GRADIENT_SE, GRADIENT_SE_SIZE); break;
        case 6: AktywacjaFiltra(GRADIENT_S, GRADIENT_S_SIZE); break;
        case 7: AktywacjaFiltra(GRADIENT_SW, GRADIENT_SW_SIZE); break;
        case 8: AktywacjaFiltra(GRADIENT_W, GRADIENT_W_SIZE); break;
        case 9: AktywacjaFiltra(GRADIENT_NW, GRADIENT_NW_SIZE); break;
        case 10: AktywacjaFiltra(GRADIENT_N, GRADIENT_N_SIZE); break;
        case 11: AktywacjaFiltra(GRADIENT_NE, GRADIENT_NE_SIZE); break;
        case 12: AktywacjaFiltra(LAPL1, LAPL1_SIZE); break;
        case 13: AktywacjaFiltra(LAPL2, LAPL2_SIZE); break;
        case 14: AktywacjaFiltra(LAPL3, LAPL3_SIZE); break;
        case 15: AktywacjaFiltra(LAPL_SKOSNY, LAPL_SKOSNY_SIZE); break;
        case 16: AktywacjaFiltra(LAPL_POZIOMY, LAPL_POZIOMY_SIZE); break;
        case 17: AktywacjaFiltra(LAPL_PIONOWY, LAPL_PIONOWY_SIZE); break;
        case 18: AktywacjaFiltra(SOBEL_POZIOMY, SOBEL_POZIOMY_SIZE); break;
        case 19: AktywacjaFiltra(SOBEL_PIONOWY, SOBEL_PIONOWY_SIZE); break;
        case 20: AktywacjaFiltra(PREWITT_POZIOMY, PREWITT_POZIOMY_SIZE); break;
        case 21: AktywacjaFiltra(PREWITT_PIONOWY, PREWITT_PIONOWY_SIZE); break;
        }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//tfgfdg
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ComboBox3Change(TObject *Sender)
{
     switch (ComboBox3->ItemIndex){
        case 0:  AktywacjaFiltra1(USREDNIAJACY, USREDNIAJACY_SIZE); break;
        case 1:  AktywacjaFiltra1(KWADRATOWY, KWADRATOWY_SIZE); break;
        case 2:  AktywacjaFiltra1(KOLOWY, KOLOWY_SIZE); break;
        case 3:  AktywacjaFiltra1(LP1, LP1_SIZE); break;
        case 4:  AktywacjaFiltra1(LP2, LP2_SIZE); break;
        case 5:  AktywacjaFiltra1(LP3, LP3_SIZE); break;
        case 6:  AktywacjaFiltra1(PIRAMIDALNY, PIRAMIDALNY_SIZE); break;
        case 7:  AktywacjaFiltra1(STOZKOWY, STOZKOWY_SIZE); break;
        case 8:  AktywacjaFiltra1(GAUSS1, GAUSS1_SIZE); break;
        case 9:  AktywacjaFiltra1(GAUSS2, GAUSS2_SIZE); break;
        case 10: AktywacjaFiltra1(GAUSS3, GAUSS3_SIZE); break;
        case 11: AktywacjaFiltra1(GAUSS4, GAUSS4_SIZE); break;
        case 12: AktywacjaFiltra1(GAUSS5, GAUSS5_SIZE); break;
        case 13: AktywacjaFiltra1(USUN_SREDNIA, USUN_SREDNIA_SIZE); break;
        case 14: AktywacjaFiltra1(HP1, HP1_SIZE); break;
        case 15: AktywacjaFiltra1(HP2, HP2_SIZE); break;
        case 16: AktywacjaFiltra1(HP3, HP3_SIZE); break;
        case 17: AktywacjaFiltra1(UWYPUKLAJACY_E, UWYPUKLAJACY_E_SIZE); break;
        case 18: AktywacjaFiltra1(UWYPUKLAJACY_SE, UWYPUKLAJACY_SE_SIZE); break;
        case 19: AktywacjaFiltra1(UWYPUKLAJACY_S, UWYPUKLAJACY_S_SIZE); break;
        case 20: AktywacjaFiltra1(UWYPUKLAJACY_SW, UWYPUKLAJACY_SW_SIZE); break;
        case 21: AktywacjaFiltra1(UWYPUKLAJACY_W, UWYPUKLAJACY_W_SIZE); break;
        case 22: AktywacjaFiltra1(UWYPUKLAJACY_NW, UWYPUKLAJACY_NW_SIZE); break;
        case 23: AktywacjaFiltra1(UWYPUKLAJACY_N, UWYPUKLAJACY_N_SIZE); break;
        case 24: AktywacjaFiltra1(UWYPUKLAJACY_NE, UWYPUKLAJACY_NE_SIZE); break;
        case 25: Form1->Button5->OnClick = MedFiltr;
                 Form1->Label1->Visible = FALSE;
                 Form1->StringGrid1->Visible = FALSE;
                 break;
        case 26: Form1->Button5->OnClick = MinFiltr;
                 Form1->Label1->Visible = FALSE;
                 Form1->StringGrid1->Visible = FALSE;
                 break;
        case 27: Form1->Button5->OnClick = MaxFiltr;
                 Form1->Label1->Visible = FALSE;
                 Form1->StringGrid1->Visible = FALSE;
                 break;
        case 28: Form1->Button5->OnClick = KuwaharaFiltr;
                 Form1->Label1->Visible = FALSE;
                 Form1->StringGrid1->Visible = FALSE;
                 break;
        }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::SzumGaus(TObject *Sender)
{
/* Generate a new random seed from system time - do this once in your constructor */
srand(time(0));

/* Setup constants */
const static int q = 15;
const static int c1 = (1 << q) - 1;
const static int c2 = ((int)(c1 / 3)) + 1;
const static int c3 = 1 / c1;
int losowa1, losowa2, losowa3;

TMemoryStream *Ms = new TMemoryStream;
Ms->Position = 0;
BMP->SaveToStream(Ms);
Ms->Position = 0;
Obraz->Picture->Bitmap->LoadFromStream(Ms);
delete Ms;
/* the white noise */
//int noise = 0;

for (int i = 0; i < TrackBar1->Position; i++)
{
    losowa1=(rand()%255)+0;
    losowa2=(rand()%Form1->Obraz->Picture->Bitmap->Width)+0;
    losowa3=(rand()%Form1->Obraz->Picture->Bitmap->Height)+0;
    Obraz->Canvas->Pixels[losowa2][losowa3] = (TColor)(2 * ((losowa1 * c2) + (losowa1 * c2) << 8 + (losowa1 * c2) << 16) - 3 * (c2 - 1)) * c3;
  //Obraz->Canvas->Pixels[random1][random2] =noise;//(TColor)med(redval,9) + (med(greenval,9) << 8) + (med(blueval,9) << 16);
}  //wynik->Canvas->Pixels[i][j] = (TColor)(int)redm[mred] + ((int)greenm[mgreen] << 8) + ((int)bluem[mblue] << 16);
   //Wynik->Canvas->Pixels[i][j] = (TColor)redmax + (greenmax << 8) + (bluemax << 16);
}

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


void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{

// ustaw opis liczbowy

if( TrackBar1->Position>0 )
{
if( TrackBar1->Position%10>4 || TrackBar1->Position%10==0)
Label2->Caption = IntToStr(TrackBar1->Position)+" %";
else
Label2->Caption =IntToStr(TrackBar1->Position)+" %";
}
else
Label2->Caption = "0%";

}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
switch (ComboBox1->ItemIndex){
        case 0:Form1->Button1->OnClick = SzumGaus; break;
        }

}
//---------------------------------------------------------------------------


ale tak naprawdę tylko wcześniej podany kawałek kodu może wpływać na tą pętle.

Początkowo w Wynik jest pusty. Dopiero po wybraniu filtra (buton3 lub 5) algorytm przetwarza nam Obraz i otrzymujemy wynik w Timage Wynik
wcześniej nic nie deklaruje w Wynik.
PS. kod ma parę opcji zrobionych tak tylko aby były narazie do dopracowania później. narazie koncentruje się tylko na tym aby poprawnie działa a potem picowanie.
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Cyfrowy Baron » sobota, 14 lipca 2012, 18:56

kubawodzu napisał(a):wcześniej nic nie deklaruje w Wynik.


I tu tkwi błąd, który wynika z nieznajomości TCanvas. Otóż płótno Canvas nie ma wymiarów, tak ja nie posiada własnej powierzchni. TCanvas to tylko zestaw narzędzi. Jeżeli nie wczytałeś nic do obiektu Wynik, to rozmiar płótna Bitmap->Canvas tego obiektu jest równy wymiarowi obiektu Wynik. Błąd bierze się stąd, że obiekt Obraz jest większy od obiektu Wynik i pętla próbuje zapisywać piksele poza obszarem roboczym obiektu Wynik, gdy jak już wspomniałem Wynik->Picture->Bitmap->Canvas->Width jest równe Wynik->Width, Height oczywiście tak samo.
Dodatkowo jeśli w Wynik->Picture->Bitmap nie ma bitmapy to nie da się tam zapisać pikseli, gdyż obiekt jest pusty. Zanim więc cokolwiek zapiszesz w Wynik->Picture->Bitmap to najpierw musisz tam przekopiować bitmapę z Obraz->Picture->Bitmap.

KOD cpp:     UKRYJ  
Wynik->Picture->Bitmap = Obraz->Picture->Bitmap;


W Wynik musi być jakaś bitmapa, jeżeli odwołujesz się do bitmapy i musi mieć wymiary bitmapy źródłowej.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
kubawodzu
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » niedziela, 15 lipca 2012, 15:15

Dzięki wielkie za pomoc. Działa tak jak powinno. Wstyd się przyznać ale to do mojej pracy magisterskiej. Znam wmiarę dobrze matlaba, C# czy jave ale postanowiłem że napisze ten projekt w C++ ponieważ nie znam tego języka najlepiej a jest to doskonała szansa aby się poduczyć, dodatkowo środowisko Borland jest dla mnie całkowicie nowe stąd moja oczywiste wpadki. Dziękuję Wam za pomoc a szczególnie Cyfrowemu.
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez kubawodzu » poniedziałek, 16 lipca 2012, 21:14

tak by nie śmiecić na forum czy są w borlandzie wbudowane opcji Cofnij/Przywróć aby się niepotrzebnie w kodzie babrać?
Avatar użytkownika
kubawodzu
Bladawiec
Bladawiec
 
Posty: 28
Dołączył(a): piątek, 13 lipca 2012, 14:14
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Winda 7 pro 64
Kompilator: Borland C++ 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Miniatura obrazu w Timage

Nowy postprzez Cyfrowy Baron » wtorek, 17 lipca 2012, 04:53

W niektórych standardowych obiektach API jak np. TMemo, TEdit itp.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości