CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Rozmycie obrazu metodą Gaussa

Rozmycie obrazu metodą Gaussa

dział ogólny

Rozmycie obrazu metodą Gaussa

Nowy postprzez xredom » piątek, 19 kwietnia 2013, 11:36

Witam próbuje zrobić rozmywanie obrazu metodą Gaussa, no i problem jest taki że wynikowy obraz (Image2) wyświetla mi biały kwadracik mniejszy od bitmapy w Image2 zamiast zastosowanego efektu(https://www.dropbox.com/s/7mg9ww7tufvnw8g/rozmywanie.png ), sam algorytm znalazłem w internecie i w sumie po przepisaniu działa lecz na zasadzie takiej że do (Image1) w Object Inspector -> Picture umieszcza się bitmapę następnie bitmapa w Image2 po zastosowaniu rozmycia zmienia się stosownie do wybranego efektu. Ja próbuję przerobić cały ten algorytm by po wczytaniu obrazu w form1 do Image został on załadowany do form8 Image1(orginał) i Image2(po zmianie) następnie po zastosowaniu efektu rozmycia zmieniony obraz ląduje w Image2 po czym po zastosowaniu zmian form8 się zamyka i obrazek zmieniony wraca do Image w form1.
Kod z formy1 - unit1.cpp:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit8.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
        if(OpenPictureDialog1->Execute())
  {
        Image->Picture->LoadFromFile(OpenPictureDialog1->FileName);
  }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn7Click(TObject *Sender)
{
        Form8->BMP->Assign( Image->Picture->Graphic );
        Form8->BMP->PixelFormat = pf32bit;

        Form8->Image1->Picture->Assign( Form8->BMP );
        Form8->Image2->Picture->Assign( Form8->BMP );
        Form8->ShowModal();
}
//---------------------------------------------------------------------------
 

Kod z form8 - unit8.cpp:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit8.h"
#include "Filters.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm8 *Form8;
int *Filter;
unsigned char **red, **green, **blue, **gray;
int Norm;
int Size;
//---------------------------------------------------------------------------
__fastcall TForm8::TForm8(TComponent* Owner)
        : TForm(Owner)
{
BMP = new Graphics::TBitmap();
}
//---------------------------------------------------------------------------
void __fastcall TForm8::LinearFiltr(TObject *Sender)
{
int rsume, gsume, bsume, graysume;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
        {
            rsume = 0;
            gsume = 0;
            bsume = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        rsume += Filter[k*Size+l]*red[i+k-margin][j+l-margin];
                        gsume += Filter[k*Size+l]*green[i+k-margin][j+l-margin];
                        bsume += Filter[k*Size+l]*blue[i+k-margin][j+l-margin];
                    }
            rsume /= Norm;
            gsume /= Norm;
            bsume /= Norm;

            if (rsume > 255) rsume = 255;
            else if (rsume < 0) rsume = 0;
            if (gsume > 255) gsume = 255;
            else if (gsume < 0) gsume = 0;
            if (bsume > 255) bsume = 255;
            else if (bsume < 0) bsume = 0;

            Image2->Canvas->Pixels[i][j] = (TColor)rsume + (gsume << 8) + (bsume << 16);
        }

}

void __fastcall TForm8::MinFiltr(TObject *Sender)
{
int rmin, gmin, bmin, graymin;
Size = 3;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
        {
            rmin = 255;
            gmin = 255;
            bmin = 255;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        if (rmin > red[i+k-margin][j+l-margin]) rmin = red[i+k-margin][j+l-margin];
                        if (gmin > green[i+k-margin][j+l-margin]) gmin = green[i+k-margin][j+l-margin];
                        if (bmin > blue[i+k-margin][j+l-margin]) bmin = blue[i+k-margin][j+l-margin];
                    }
            Image2->Canvas->Pixels[i][j] = (TColor)rmin + (gmin << 8) + (bmin << 16);
        }

}

void __fastcall TForm8::MaxFiltr(TObject *Sender)
{
int rmax, gmax, bmax, graymax;
Size = 3;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
        {
            rmax = 0;
            gmax = 0;
            bmax = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        if (rmax < red[i+k-margin][j+l-margin]) rmax = red[i+k-margin][j+l-margin];
                        if (gmax < green[i+k-margin][j+l-margin]) gmax = green[i+k-margin][j+l-margin];
                        if (bmax < blue[i+k-margin][j+l-margin]) bmax = blue[i+k-margin][j+l-margin];
                    }
            Image2->Canvas->Pixels[i][j] = (TColor)rmax + (gmax << 8) + (bmax << 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 TForm8::MedFiltr(TObject *Sender)
{
int rval[9], gval[9], bval[9], grayval[9], m;
Size = 3;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
        {
            m = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        rval[m] = red[i+k-margin][j+l-margin];
                        gval[m] = green[i+k-margin][j+l-margin];
                        bval[m] = blue[i+k-margin][j+l-margin];
                        m++;
                    }
            Image2->Canvas->Pixels[i][j] = (TColor)med(rval,9) + (med(gval,9) << 8) + (med(bval,9) << 16);
        }

}

void __fastcall TForm8::KuwaharaFiltr(TObject *Sender)
{
double rm[4], gm[4], bm[4], graym[4];  //wartosci srednie
double rs[4], gs[4], bs[4], grays[4];  //wariancje
int m, mr, mg, mb;
Size = 5;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
    {
         //policz srednie
         for (int k=0; k<4; k++)
         {
            rm[k] = 0;
            gm[k] = 0;
            bm[k] = 0;
         }
         for (int k=0; k<3; k++)
             for (int l=0; l<3; l++)
             {
                  rm[0] += red[i+k-margin][j+l-margin] / 9.0;
                  rm[1] += red[i+k][j+l-margin] / 9.0;
                  rm[2] += red[i+k-margin][j+l] / 9.0;
                  rm[3] += red[i+k][j+l] / 9.0;

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

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

         //policz wariancje
         for (int k=0; k<4; k++)
         {
            rs[k] = 0;
            gs[k] = 0;
            bs[k] = 0;
         }
         for (int k=0; k<3; k++)
             for (int l=0; l<3; l++)
             {
                  rs[0] += (red[i+k-margin][j+l-margin] - rm[0]) * (red[i+k-margin][j+l-margin] - rm[0]);
                  rs[1] += (red[i+k][j+l-margin] - rm[1]) * (red[i+k][j+l-margin] - rm[1]);
                  rs[2] += (red[i+k-margin][j+l] - rm[2]) * (red[i+k-margin][j+l] - rm[2]);
                  rs[3] += (red[i+k][j+l] - rm[3]) * (red[i+k][j+l] - rm[3]);

                  gs[0] += (green[i+k-margin][j+l-margin] - gm[0]) * (green[i+k-margin][j+l-margin] - gm[0]);
                  gs[1] += (green[i+k][j+l-margin] - gm[1]) * (green[i+k][j+l-margin] - gm[1]);
                  gs[2] += (green[i+k-margin][j+l] - gm[2]) * (green[i+k-margin][j+l] - gm[2]);
                  gs[3] += (green[i+k][j+l] - gm[3]) * (green[i+k][j+l] - gm[3]);

                  bs[0] += (blue[i+k-margin][j+l-margin] - bm[0]) * (blue[i+k-margin][j+l-margin] - bm[0]);
                  bs[1] += (blue[i+k][j+l-margin] - bm[1]) * (blue[i+k][j+l-margin] - bm[1]);
                  bs[2] += (blue[i+k-margin][j+l] - bm[2]) * (blue[i+k-margin][j+l] - bm[2]);
                  bs[3] += (blue[i+k][j+l] - bm[3]) * (blue[i+k][j+l] - bm[3]);
             }

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

         mg=0;
         for (int k=1; k<4; k++)
            if (gs[k] < gs[mg])
               mg = k;

         mb=0;
         for (int k=1; k<4; k++)
            if (bs[k] < bs[mb])
               mb = k;

         Image2->Canvas->Pixels[i][j] = (TColor)(int)rm[mr] + ((int)gm[mg] << 8) + ((int)bm[mb] << 16);
   }

}

//zaladowanie wybranego filtru
void UpdateFilter(int *NewFilter, int size)
{
Form8->StringGrid1->RowCount = size;
Form8->StringGrid1->ColCount = size;
Filter = NewFilter;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
            Form8->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;
Form8->Label1->Caption = "1/" + IntToStr(Norm) + " *";
Form8->Label1->Visible = TRUE;
Form8->StringGrid1->Visible = TRUE;
Form8->Button1->OnClick = Form8->LinearFiltr;
Size = size;
}
//---------------------------------------------------------------------------

void __fastcall TForm8::FormCreate(TObject *Sender)
{
       TColor color;
red = (unsigned char**)malloc(Form8->Image1->Width * sizeof(char*));
green = (unsigned char**)malloc(Form8->Image1->Width * sizeof(char*));
blue = (unsigned char**)malloc(Form8->Image1->Width * sizeof(char*));
for (int i=0; i<Form8->Image1->Width; i++)
    {
       red[i] = (unsigned char*)malloc(Form8->Image1->Height);
       green[i] = (unsigned char*)malloc(Form8->Image1->Height);
       blue[i] = (unsigned char*)malloc(Form8->Image1->Height);
       for (int j=0; j<Form8->Image1->Height; j++)
          {
             color = Form8->Image1->Canvas->Pixels[i][j];
             red[i][j] = (color & 0xFF);
             green[i][j] = ((color >> 8) & 0xFF);
             blue[i][j] = ((color >> 16) & 0xFF);
          }
    }

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

void __fastcall TForm8::ComboBox1Change(TObject *Sender)
{
         switch (ComboBox1->ItemIndex) {

        case 0: UpdateFilter(GAUSS1, GAUSS1_SIZE); break;
        case 1: UpdateFilter(GAUSS2, GAUSS2_SIZE); break;
        case 2: UpdateFilter(GAUSS3, GAUSS3_SIZE); break;
        case 3: UpdateFilter(GAUSS4, GAUSS4_SIZE); break;
        case 4: UpdateFilter(GAUSS5, GAUSS5_SIZE); break;

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

Kod z Unit8.h:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#ifndef Unit8H
#define Unit8H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
class TForm8 : public TForm
{
__published:    // IDE-managed Components
        TImage *Image1;
        TBitBtn *BitBtn1;
        TBitBtn *BitBtn2;
        TComboBox *ComboBox1;
        TLabel *Label1;
        TStringGrid *StringGrid1;
        TButton *Button1;
        TImage *Image2;
        TImage *ObrazMono;
        TImage *WynikMono;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall ComboBox1Change(TObject *Sender);
        void __fastcall LinearFiltr(TObject *Sender);
        void __fastcall MaxFiltr(TObject *Sender);
        void __fastcall MinFiltr(TObject *Sender);
        void __fastcall MedFiltr(TObject *Sender);
        void __fastcall KuwaharaFiltr(TObject *Sender);
private:        // User declarations
public:         // User declarations
        __fastcall TForm8(TComponent* Owner);
            Graphics::TBitmap *BMP;
};
//---------------------------------------------------------------------------
extern PACKAGE TForm8 *Form8;
//---------------------------------------------------------------------------
#endif

Kod z Filters.h:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#ifndef FiltersH
#define FiltersH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm9 : public TForm
{
__published:    // IDE-managed Components
private:        // User declarations
public:         // User declarations
        __fastcall TForm9(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm9 *Form9;
    int GAUSS1_SIZE = 3;
    int GAUSS1[9] = {1, 2, 1,
                     2, 4, 2,
                     1, 2, 1};

    int GAUSS2_SIZE = 5;
    int GAUSS2[25] = {1, 1, 2, 1, 1,
                      1, 2, 4, 2, 1,
                      2, 4, 8, 4, 2,
                      1, 2, 4, 2, 1,
                      1, 1, 2, 1, 1};

    int GAUSS3_SIZE = 5;
    int GAUSS3[25] = {0, 1, 2, 1, 0,
                      1, 4, 8, 4, 1,
                      2, 8, 16,8, 2,
                      1, 4, 8, 4, 1,
                      0, 1, 2, 1, 0};

    int GAUSS4_SIZE = 5;
    int GAUSS4[25] = {1, 4, 7, 4, 1,
                      4,16,26,16, 4,
                      7,26,41,26, 7,
                      4,26,16,26, 4,
                      1, 4, 7, 4, 1};

    int GAUSS5_SIZE = 7;
    int GAUSS5[49] = {1, 1, 2, 2, 2, 1, 1,
                      1, 2, 2, 4, 2, 2, 1,
                      2, 2, 4, 8, 4, 2, 2,
                      2, 4, 8,16, 8, 4, 2,
                      2, 2, 4, 8, 4, 2, 2,
                      1, 2, 2, 4, 2, 2, 1,
                      1, 1, 2, 2, 2, 1, 1};
//---------------------------------------------------------------------------
#endif
 

Oprócz tego mam szereg warning'ów lecz program się kompiluje:

[Linker Warning] Public symbol '_GAUSS1_SIZE' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS1' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS2_SIZE' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS2' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS3_SIZE' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS3' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS4_SIZE' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS4' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS5_SIZE' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ
[Linker Warning] Public symbol '_GAUSS5' defined in both module C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\UNIT8.OBJ and C:\USERS\P4X3S\DESKTOP\GAUSSA\TEST - KOPIA\FILTERS.OBJ



Środowisko programowania C++ Bulider 6
Avatar użytkownika
xredom
Bladawiec
Bladawiec
 
Posty: 22
Dołączył(a): niedziela, 14 kwietnia 2013, 20:00
Podziękował : 12
Otrzymał podziękowań: 0
System operacyjny: windows 7
Kompilator: C++ Bulider 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Rozmycie obrazu metodą Gaussa

Nowy postprzez Mironas » piątek, 19 kwietnia 2013, 13:01

Najpierw parę spraw ogólnych.

1. Jeśli tworzysz jakiś obiekt za pomocą operatora new to koniecznie musisz go na koniec usunąć za pomocą delete. Przykład:
KOD cpp:     UKRYJ  
void __fastcall TForm3::FormCreate(TObject *Sender)
{
  BMP = new Graphics::TBitmap();
}
//---------------------------------------------------------------------------
void __fastcall TForm3::FormDestroy(TObject *Sender)
{
  delete BMP;
}
 


2. Dziwnie budujesz niektóre funkcje. Prawdopodobnie idziesz na łatwiznę i jeśli potrzebujesz utworzyć nową funkcję to klikasz podwójnie dowolny komponent co tworzy metodę dla niego, a następnie tylko zmieniasz nazwę tej metody.
Lepsze rozwiązanie: W BCB6 w oknie ClassExplorer klikasz prawym klawiszem TForm8 a potem New Method ....

3. Obiekty i zmienne używane w danym oknie lepiej deklarować w pliku UnitX.h a nie w UnitX.cpp (patrz Filter, Norm, Size) w sekcji private lub ew. public - jeśli dany obiekt ma być widoczny z innego okna.

4. Jeśli jakaś funkcja (metoda) jest częścią klasy okna (np TForm8) to nie musisz do komponentów w tym oknie odwoływać się podając za każdym razem Form1->...
Np.:
KOD cpp:     UKRYJ  
void __fastcall TForm8::FormCreate(TObject *Sender)
{
  Form8->Image1->Width = 100;
  Image1->Width = 100;   // to jest to samo, ale krótszy zapis
}
 


5. Nie musisz w kodzie przypisywać metody do zdarzenia (Button1->OnClick = Form8->LinearFiltr;). Możesz zrobić to w Obiect Inspector na zakładce Events.

6. Po co Ci funkcje (MinFiltr, MaxFiltr, MedFiltr, KuwaharaFiltr) jeśli z nich nie korzystasz?

Nie przepisuj bezmyślnie kodu. Nie da się zbudować aplikacji z fragmentów kodu z Internetu. W Internecie możesz znaleźć przykładowy kod, ale musisz go zrozumieć i adoptować do swojego programu a nie wstawić jak klocek lego do kodu. To że kompilator nie zgłasza błędów nie znaczy że wszystko będzie dobrze działało.

7. Po co Ci w Form8 obiekt BMP jeśli z niego nie korzystasz?

Za ten post autor Mironas otrzymał podziękowanie od:
xredom
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez Mironas » piątek, 19 kwietnia 2013, 13:06

xredom napisał(a):Oprócz tego mam szereg warning'ów lecz program się kompiluje:

Znowu poszedłeś na łatwiznę. Jeśli potrzebujesz pliku *.h (tutaj Filters.h) to utwórz taki plik (ręcznie lub za pomocą File>>New>>Other>>Header File) a nie twórz nowego okna (u Ciebie Form9).
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez Mironas » piątek, 19 kwietnia 2013, 13:21

8. Jeśli alokujesz pamięć za pomocą malloc to potem musisz ją zwolnić za pomocą free.
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez xredom » piątek, 19 kwietnia 2013, 14:57

Ok dzięki za wskazówki, przerobiłem tak jak mówiłeś lecz
Dziwnie budujesz niektóre funkcje. Prawdopodobnie idziesz na łatwiznę i jeśli potrzebujesz utworzyć nową funkcję to klikasz podwójnie dowolny komponent co tworzy metodę dla niego, a następnie tylko zmieniasz nazwę tej metody.

Tak buduje tak innych metod nie znam :( szukałem
Lepsze rozwiązanie: W BCB6 w oknie ClassExplorer klikasz prawym klawiszem TForm8 a potem New Method ....
i nie wiem gdzie to jest.
BMP używam do przesłania z formy1 image1 - bitmapy do formy8 image1 i image2
ok po twoich wskazówkach kod stał się bardziej przejrzysty no i nie wywala Warning'ów
plik cpp:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit8.h"
#include "Filters.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm8 *Form8;

//---------------------------------------------------------------------------
__fastcall TForm8::TForm8(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm8::LinearFiltr(TObject *Sender)
{
int rsume, gsume, bsume, graysume;
int margin = ((Size-1)/2);

//filtr dla obrazu kolorowego
for (int i=margin; i<Image1->Width-margin; i++)
    for (int j=margin; j<Image1->Height-margin; j++)
        {
            rsume = 0;
            gsume = 0;
            bsume = 0;
            for (int k=0; k<Size; k++)
                for (int l=0; l<Size; l++)
                    {
                        rsume += Filter[k*Size+l]*red[i+k-margin][j+l-margin];
                        gsume += Filter[k*Size+l]*green[i+k-margin][j+l-margin];
                        bsume += Filter[k*Size+l]*blue[i+k-margin][j+l-margin];
                    }
            rsume /= Norm;
            gsume /= Norm;
            bsume /= Norm;

            if (rsume > 255) rsume = 255;
            else if (rsume < 0) rsume = 0;
            if (gsume > 255) gsume = 255;
            else if (gsume < 0) gsume = 0;
            if (bsume > 255) bsume = 255;
            else if (bsume < 0) bsume = 0;

            Image2->Canvas->Pixels[i][j] = (TColor)rsume + (gsume << 8) + (bsume << 16);
        }

}

//zaladowanie wybranego filtru
void __fastcall TForm8::UpdateFilter(int *NewFilter, int size)
{
StringGrid1->RowCount = size;
StringGrid1->ColCount = size;
Filter = NewFilter;
for (int i=0; i<size; i++)
    for (int j=0; j<size; j++)
            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;
Label1->Caption = "1/" + IntToStr(Norm) + " *";
Label1->Visible = TRUE;
StringGrid1->Visible = TRUE;
Size = size;
}
//---------------------------------------------------------------------------

void __fastcall TForm8::FormCreate(TObject *Sender)
{
BMP = new Graphics::TBitmap();
       TColor color;
red = (unsigned char**)malloc(Image1->Width * sizeof(char*));
green = (unsigned char**)malloc(Image1->Width * sizeof(char*));
blue = (unsigned char**)malloc(Image1->Width * sizeof(char*));
for (int i=0; i<Image1->Width; i++)
    {
       red[i] = (unsigned char*)malloc(Image1->Height);
       green[i] = (unsigned char*)malloc(Image1->Height);
       blue[i] = (unsigned char*)malloc(Image1->Height);
       for (int j=0; j<Image1->Height; j++)
          {
             color = Image1->Canvas->Pixels[i][j];
             red[i][j] = (color & 0xFF);
             green[i][j] = ((color >> 8) & 0xFF);
             blue[i][j] = ((color >> 16) & 0xFF);
          }
    }

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

void __fastcall TForm8::ComboBox1Change(TObject *Sender)
{
         switch (ComboBox1->ItemIndex) {
        case 0: UpdateFilter(GAUSS1, GAUSS1_SIZE); break;
        case 1: UpdateFilter(GAUSS2, GAUSS2_SIZE); break;
        case 2: UpdateFilter(GAUSS3, GAUSS3_SIZE); break;
        case 3: UpdateFilter(GAUSS4, GAUSS4_SIZE); break;
        case 4: UpdateFilter(GAUSS5, GAUSS5_SIZE); break;
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm8::FormDestroy(TObject *Sender)
{
  delete BMP;
    free(red);
    free(green);
    free(blue);
}
//---------------------------------------------------------------------------

 

pliki nagłówkowe:
KOD cpp:     UKRYJ  
Unit8.h:
//---------------------------------------------------------------------------

#ifndef Unit8H
#define Unit8H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
class TForm8 : public TForm
{
__published:    // IDE-managed Components
        TImage *Image1;
        TBitBtn *BitBtn1;
        TBitBtn *BitBtn2;
        TComboBox *ComboBox1;
        TLabel *Label1;
        TStringGrid *StringGrid1;
        TButton *Button1;
        TImage *Image2;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall ComboBox1Change(TObject *Sender);
        void __fastcall LinearFiltr(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
         void __fastcall UpdateFilter(int *NewFilter, int size);
private:        // User declarations
public:         // User declarations
        __fastcall TForm8(TComponent* Owner);
        Graphics::TBitmap *BMP;
        int *Filter;
        unsigned char **red, **green, **blue, **gray;
        int Norm;
        int Size;

};
//---------------------------------------------------------------------------
extern PACKAGE TForm8 *Form8;
//---------------------------------------------------------------------------
#endif

Filters.h:
//---------------------------------------------------------------------------

#ifndef FiltersH
#define FiltersH
//---------------------------------------------------------------------------

    int GAUSS1_SIZE = 3;
    int GAUSS1[9] = {1, 2, 1,
                     2, 4, 2,
                     1, 2, 1};

    int GAUSS2_SIZE = 5;
    int GAUSS2[25] = {1, 1, 2, 1, 1,
                      1, 2, 4, 2, 1,
                      2, 4, 8, 4, 2,
                      1, 2, 4, 2, 1,
                      1, 1, 2, 1, 1};

    int GAUSS3_SIZE = 5;
    int GAUSS3[25] = {0, 1, 2, 1, 0,
                      1, 4, 8, 4, 1,
                      2, 8, 16,8, 2,
                      1, 4, 8, 4, 1,
                      0, 1, 2, 1, 0};

    int GAUSS4_SIZE = 5;
    int GAUSS4[25] = {1, 4, 7, 4, 1,
                      4,16,26,16, 4,
                      7,26,41,26, 7,
                      4,26,16,26, 4,
                      1, 4, 7, 4, 1};

    int GAUSS5_SIZE = 7;
    int GAUSS5[49] = {1, 1, 2, 2, 2, 1, 1,
                      1, 2, 2, 4, 2, 2, 1,
                      2, 2, 4, 8, 4, 2, 2,
                      2, 4, 8,16, 8, 4, 2,
                      2, 2, 4, 8, 4, 2, 2,
                      1, 2, 2, 4, 2, 2, 1,
                      1, 1, 2, 2, 2, 1, 1};


//---------------------------------------------------------------------------
#endif

w dalszym ciągu po wciśnięciu button1 dostaje wynikowe białe okienko mniejsze od image2, swoją drogą dobrze tego free wrzuciłem w FormDestroy ??
Avatar użytkownika
xredom
Bladawiec
Bladawiec
 
Posty: 22
Dołączył(a): niedziela, 14 kwietnia 2013, 20:00
Podziękował : 12
Otrzymał podziękowań: 0
System operacyjny: windows 7
Kompilator: C++ Bulider 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Rozmycie obrazu metodą Gaussa

Nowy postprzez Mironas » piątek, 19 kwietnia 2013, 15:35

xredom napisał(a):
Lepsze rozwiązanie: W BCB6 w oknie ClassExplorer klikasz prawym klawiszem TForm8 a potem New Method ....
i nie wiem gdzie to jest.

W BCB6 okno ClassExplorer otwierasz w menu: View >> ClassExplorer
Ewentualnie po prostu z palca w UnitX.h w sekcji private lub public wpisujesz:
KOD cpp:     UKRYJ  
private:
  void NazwaFunkcji(int parametr);


A w UnitX.cpp:
KOD cpp:     UKRYJ  
void TForm3::NazwaFunkcji(int parametr)
{
}
//---------------------------------------------------------------------------


xredom napisał(a):BMP używam do przesłania z formy1 image1 - bitmapy do formy8 image1 i image2

Niepotrzebnie. Wystarczy:
KOD cpp:     UKRYJ  
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
  Form3->Image1->Picture->Assign( Image->Picture );
  Form3->Image2->Picture->Assign( Image->Picture );
  Form3->ShowModal();
}
 

A wszystkie wpisy BMP usunąć.
Oczywiście dotyczy to przypadku gdy (tak jak w Twoim przykładzie) BMP stosujesz wyłącznie do przepisania obrazu:
Form1->Image1 >> BMP >> Form8->Image1
Tutaj BMP jest zbędny.
Inna sprawa, że ja wolałbym obraz przechowywać i edytować wyłącznie w BMP a TImage używać tylko do wyświetlania. W ten sposób upraszcza się zapis i łatwiej uniknąć pomylenia rozmiaru bitmapy z rozmiarem komponentu TImage (bo to nie to samo).

xredom napisał(a):w dalszym ciągu po wciśnięciu button1 dostaje wynikowe białe okienko mniejsze od image2

Nie sprawdzałem samego rozmycia. W Internecie masz sporo przykładów jak zrobić rozmycie. Tylko brać i stosować. A ty skąd brałeś ten przykład?

xredom napisał(a):swoją drogą dobrze tego free wrzuciłem w FormDestroy ??

Dobrze. Jeśli obiekt tworzysz w konstruktorze formy, to najlepiej usunąć go w destruktorze.
Tylko zwróć uwagę, że pamięć przydzielasz też dla poszczególnych red[x], green[x], blue[x] i tak samo powinieneś ją zwalniać - najpierw free(red[x]) (w pętli) a potem free(red).

Za ten post autor Mironas otrzymał podziękowanie od:
xredom
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 09:05

W zdarzeniu OnCreate dla Form8 tworzysz bitmapę BMP, ale nic z nią więcej nie robisz! Po co tak? Funkcja LineartFiltr nigdzie nie zostaje użyta więc po co ona tam wogóle jest?

Potem w pętli (zdarzenie OnCreate) wykonujesz jakieś obliczenia na Image1, pobierając jego rozmiar, a co pisała już Mironas rozmiar Image to nie to samo co rozmiar wczytanej do niej grafiki. Następnie pobierasz wartość pikseli z płótna Canvas obiektu Image1, a nie z grafiki. Operacje możesz wykonywać tylko na bitmapie, więc w Image1 musi być grafika w formacie *.bmp inaczej nie będzie działać.

Cały ten kod jest chaotyczny i niezrozumiały. Trzeba by spędzić kilka godzin nad jego analizą, a ja tyle czasu nie mam.
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 14:18

Mogę ci zaproponować własny filtr, nie wiem czy działa w oparciu o rozmycie Gaussa, ale to chyba zależy od wartości liczbowych przekazywanych do filtra:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
#include <memory>
private:
std::auto_ptr<TGraphic> BlurImage(TBitmap *Image);
void __fastcall GaussianFilter(TImage *ImageScr, TImage *Dest, int gValue);


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
#include <math.h> /* w C++Builder XE2 będzie: <System.Math.hpp> */

std::auto_ptr<TGraphic> TForm1::BlurImage(TBitmap *Image)
{
 int Div = 6;

 int flt[] = {
                 1, 1, 1,
                 0, 0, 0,
                 1, 1, 1
               };

 int XX[3];

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

 std::auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
 std::auto_ptr<TBitmap> tmpBitmap (new Graphics::TBitmap());


 Bitmap->Assign((TPersistent*)Image);

 Bitmap->PixelFormat = pf24bit;

 tmpBitmap->Assign((TPersistent*)Image);
 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;
        XX[i4] = Math::Max(XX[i4], 0);
        XX[i4] = Math::Min(XX[i4], 255);
        ptr[x + i4] = XX[i4];
   }
  }
 }

return Bitmap;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::GaussianFilter(TImage *ImageScr, TImage *ImageDest, int gValue)
{
 if(gValue <= 0)
 {
  ShowMessage("Wprowadź wartość większą od 0!");
  return;
 }

 std::auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
 Bitmap->Assign( (TPersistent*)ImageScr->Picture->Graphic );

 if(gValue == 1)
 {
  ImageDest->Picture->Graphic = BlurImage( Bitmap.get() ).get();
  return;
 }


 do
 {
  Bitmap->Assign( (TPersistent*)BlurImage( Bitmap.get() ).get() );
  gValue -= 1;
 }
 while( gValue > 0 );

 ImageDest->Picture->Graphic = Bitmap.get();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
 GaussianFilter(Image1, Image2, 100);
}


Kod zadziała z grafiką w każdym rodzaju, ale nie jest zbyt szybki.



PS. Zwróć uwagę na to jak kod jest uporządkowany.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
xredom
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez xredom » sobota, 20 kwietnia 2013, 18:16

Zmieniłem troszkę bo wyrzucało mi błędy:
KOD cpp:     UKRYJ  
w pliku nagłówkowym dodałem: using namespace std;
z:
std::auto_ptr<TGraphic> TForm1::BlurImage(TBitmap *Image)
na:
std::auto_ptr<TGraphic> TForm1::BlurImage(Graphics::TBitmap *Image)
podobnie w nagłówku
z:
std::auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
std::auto_ptr<TBitmap> tmpBitmap (new Graphics::TBitmap());

na:
std::auto_ptr<Graphics::TBitmap> Bitmap (new Graphics::TBitmap());
std::auto_ptr<Graphics::TBitmap> tmpBitmap (new Graphics::TBitmap());

oraz
z:
for(int i4 = 0; i4 < 3; i4++)
   {
        XX[i4] = XX[i4] / Div;
        XX[i4] = Math::Max(XX[i4], 0);
        XX[i4] = Math::Min(XX[i4], 255);
        ptr[x + i4] = XX[i4];
   }
na:
for(int i4 = 0; i4 < 3; i4++)
   {
        XX[i4] = XX[i4] / Div;
        XX[i4] = max(XX[i4], 0);
        XX[i4] = min(XX[i4], 255);
        ptr[x + i4] = XX[i4];
   }
 

Nadal mam takie błędy:

[C++ Error] Unit1.cpp(74): E2015 Ambiguity between 'auto_ptr<TBitmap>::operator auto_ptr<TGraphic>()' and 'auto_ptr<TGraphic>::auto_ptr(auto_ptr<TBitmap> &)'

Ostatnio edytowano sobota, 20 kwietnia 2013, 18:22 przez xredom, łącznie edytowano 1 raz
Avatar użytkownika
xredom
Bladawiec
Bladawiec
 
Posty: 22
Dołączył(a): niedziela, 14 kwietnia 2013, 20:00
Podziękował : 12
Otrzymał podziękowań: 0
System operacyjny: windows 7
Kompilator: C++ Bulider 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 18:18

Niewielka modyfikacja funkcji BlurImage nieco przyspiesza algorytm:

KOD cpp:     UKRYJ  
std::auto_ptr<TGraphic> TForm1::BlurImage(TBitmap *Image)
{
 int Div = 6;

 int flt[] = {
                 1, 1, 1,
                 0, 0, 0,
                 1, 1, 1
             };

 int XX[3];

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

 std::auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
 std::auto_ptr<TBitmap> tmpBitmap (new Graphics::TBitmap());


 Bitmap->Assign((TPersistent*)Image);

 Bitmap->PixelFormat = pf24bit;

 tmpBitmap->Assign((TPersistent*)Image);
 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];
         XX[j1] += ptru[x + 3 * i1 + j1] * flt[1 + i1];
         XX[j1] += ptrd[x + 3 * i1 + j1] * flt[7 + i1];
        }

   for(int i4 = 0; i4 < 3; i4++)
   {
        XX[i4] = XX[i4] / Div;
        XX[i4] = Math::Max(XX[i4], 0);
        XX[i4] = Math::Min(XX[i4], 255);
        ptr[x + i4] = XX[i4];
   }
  }
 }

 return Bitmap;
}

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
xredom
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez xredom » sobota, 20 kwietnia 2013, 18:31

Ok dzięki teraz takie pytanko bo miałem masę błędów czy te drobne zmiany które zastosowałem są ok ?
no i mam jeszcze taki 1 błąd przy kompilacji:

[C++ Error] Unit1.cpp(74): E2015 Ambiguity between 'auto_ptr<TBitmap>::operator auto_ptr<TGraphic>()' and 'auto_ptr<TGraphic>::auto_ptr(auto_ptr<TBitmap> &)'

Avatar użytkownika
xredom
Bladawiec
Bladawiec
 
Posty: 22
Dołączył(a): niedziela, 14 kwietnia 2013, 20:00
Podziękował : 12
Otrzymał podziękowań: 0
System operacyjny: windows 7
Kompilator: C++ Bulider 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 18:33

Kolejna optymalizacja nie przyspiesza kodu, ale go upraszcza:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
#include <memory>
//......
private:
std::auto_ptr<TGraphic> BlurImage(TImage *Image, int fValue);


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
#include <math.h> /* w C++Builder XE2 będzie: <System.Math.hpp> */


std::auto_ptr<TGraphic> TForm1::BlurImage(TImage *Image, int fValue)
{
 if(fValue <= 0)
 {
  ShowMessage("Wprowadź wartość większą od 0!");
  return (std::auto_ptr<TGraphic>) Image1->Picture->Graphic;
 }

 int Div = 6;

 int flt[] = {
                           1, 1, 1,
                           0, 0, 0,
                           1, 1, 1
                         };

 int XX[3];

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

 std::auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
 std::auto_ptr<TBitmap> tmpBitmap (new Graphics::TBitmap());


 Bitmap->Assign( (TPersistent*)Image->Picture->Graphic );

 Bitmap->PixelFormat = pf24bit;

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

 for(int f = 0; f <= fValue; f++)
{
 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];
         XX[j1] += ptru[x + 3 * i1 + j1] * flt[1 + i1];
         XX[j1] += ptrd[x + 3 * i1 + j1] * flt[7 + i1];
        }

   for(int i4 = 0; i4 < 3; i4++)
   {
        XX[i4] = XX[i4] / Div;
        XX[i4] = Math::Max(XX[i4], 0);
        XX[i4] = Math::Min(XX[i4], 255);
        ptr[x + i4] = XX[i4];
   }
  }
 }
 tmpBitmap->Assign(Bitmap.get());
}
 return Bitmap;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 Image2->Picture->Graphic = BlurImage(Image1, 50).get();
}

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
xredom
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 18:36

Jeżeli określasz przestrzeń nazw: using namespace std; to potem w konie nie piszesz już std::auto_ptr lecz samo: auto_ptr
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: Rozmycie obrazu metodą Gaussa

Nowy postprzez xredom » sobota, 20 kwietnia 2013, 18:44

ok usunąłem std:: i dalej mam ten błąd:

[C++ Error] Unit1.cpp(75): E2015 Ambiguity between 'auto_ptr<TBitmap>::operator auto_ptr<TGraphic>()' and 'auto_ptr<TGraphic>::auto_ptr(auto_ptr<TBitmap> &)'



swoją drogą pozmieniałem
KOD cpp:     UKRYJ  
auto_ptr<Graphics::TBitmap> Bitmap (new Graphics::TBitmap());

zamiast
KOD cpp:     UKRYJ  
auto_ptr<TBitmap> Bitmap (new Graphics::TBitmap());
 

bo mi coś takiego wyskakiwało może jest inny sposób :

[C++ Error] Unit1.cpp(86): E2015 Ambiguity between 'TBitmap' and 'Windows::TBitmap'

Ostatnio edytowano sobota, 20 kwietnia 2013, 18:46 przez xredom, łącznie edytowano 1 raz
Avatar użytkownika
xredom
Bladawiec
Bladawiec
 
Posty: 22
Dołączył(a): niedziela, 14 kwietnia 2013, 20:00
Podziękował : 12
Otrzymał podziękowań: 0
System operacyjny: windows 7
Kompilator: C++ Bulider 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Rozmycie obrazu metodą Gaussa

Nowy postprzez Cyfrowy Baron » sobota, 20 kwietnia 2013, 18:46

Po pierwsze na którą linię w kodzie wskazuje błąd? Po wtóre w swoim przedostatnim poście podałem prostszy kod!
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 Ogólne problemy z programowaniem

Kto przegląda forum

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