Obliczenia(DPF), jak je przyspieszyć?

0

Witam

Mam programik który oblicza przekształcenie fouriera obrazka i niestety mam problem gdyż obliczenia trwają strasznie długo czy możecie mi coś doradzić jak można je przyspieszyć lub jak zoptymalizować działanie programu.

Oto najważniejsza procedurka

//----------------- Dyskretne Przekształcenie Fouriera (DPF) ------------

procedure TForm1.Button1Click(Sender: TObject);
var
k1 : TColor;
G : Byte;
piksel, cx, cmulti, suma_c : TComplex;
suma_g : Byte;
suma_elementow : Byte;
i,j,x,y,u,v,xn,yn,xo,yo : integer;
xobr,yobr : Extended;

begin

suma_c := Cset (0.0, 0.0, cfRectangular);
yo := Image1.Height - 1;
xo := Image1.Width - 1;
xobr := 1 / xo;
yobr := 1 / yo;
Progress.Max := Image1.Width -1;

for u := 1 to Image1.Width do // macierz obrazu szerokosc x
for v := 1 to Image1.Height do // macierz obrazu wysokosc y
begin
cx := CSet(0.0, 0.0, cfRectangular);

Edit3.text := IntToStr(u);
Edit4.text := IntToStr(v);
suma_c := CSet(0.0, 0.0, cfRectangular);
for x := 1 to Image1.Width   do   // macierz obrazu  szerokosc
for y := 1 to Image1.Height  do  // macierz obrazu wysokosc                Begin
begin
  Application.ProcessMessages;
  Edit5.text := IntToStr(x);
  Edit6.text := IntToStr(y);
  k1 := Image1.Picture.Bitmap.Canvas.Pixels[x,y];  // macierz obrazu
  piksel := CSet( GetGValue(k1), 0.0);
  cmulti := CMult(CExp(CSet(0.0, (2*pi*-1*(((x*u)*xobr)+((y*v)*yobr))),cfRectangular)),piksel);
  suma_c := CAdd(suma_c, cmulti);
end;
cx := CAdd(cx, suma_c);
G := Round(CAbs(cx));
Image2.Picture.Bitmap.Canvas.Pixels[u, v] := RGB(G, G, G);

Progress.Position := u;

end;

end;

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

Pozdrawiam i z góry dzięki za pomoc

0

Pojęcia nie mam najmniejszego co to jest dyskretne przekształcenie Fouriera, ale chyba to zwalnia całą sprawę: Progress.Position := u;

pozdrawiam :)

0

Za to całe spowolnienie odpowiadają te linijki :
k1 := Image1.Picture.Bitmap.Canvas.Pixels[x,y];
Image2.Picture.Bitmap.Canvas.Pixels[u, v] := RGB(G, G, G);

Masz dwa wyjścia.

  1. Użyć metody ScanLine (szybsza, lecz i tak ma swoje mankamenty)
  2. Nie używać TBitmap, TCanvas, TImage TPicture.

Oto przykład stosowania scanLine :

bitmap.PixelFormat:=pf24Bit;  // konieczne!
for y := 0 to bitmap.Height-1 do  
 begin
   linia := bitmap.ScanLine[y];   // linia jest typu PByteArray;
   x:=0;
   repeat
        B := linia[x];  // odczytujemy składowe koloru piksela 
        G := linia[x+1]; // dla zapisu wyglądało by to tak : linia[x] := G;
        R := linia[x+2];
        x:=x+3;
   until x>(bitmap.Width-1)*3;
  // tu wykonujesz swoje operacje (kolor piksela o wsp. x i y jest równy rgb(R,G,B);
 end;

Pisałem z pamięci.. więc w razie błędów prosze pisać..

0
suma_c := Cset (0.0, 0.0, cfRectangular); //Może da się szybciej napisąć funkcje operujące na liczbach zespolonych
....
    Edit3.text := IntToStr(u); //Co to ma być? Przecież tego nawet nie zauważysz
    Edit4.text := IntToStr(v);

...
      Edit5.text := IntToStr(x); //Tego tym bardziej
      Edit6.text := IntToStr(y);
      k1 := Image1.Picture.Bitmap.Canvas.Pixels[x,y];  //ScanLine koniecznie
      piksel := CSet( GetGValue(k1), 0.0);
      cmulti := CMult(CExp(CSet(0.0, (2*pi*-1*(((x*u)*xobr)+((y*v)*yobr))),cfRectangular)),piksel); //To jest bardzo brzydkie. Ja bym to spróbował uprościć
...
    G := Round(CAbs(cx));  //Zobacz, czy nie dałoby się tutaj Trunc zamiast Round dać.
    Image2.Picture.Bitmap.Canvas.Pixels[u, v] := RGB(G, G, G);
    
    Progress.Position := u; //Kolejny spowalniający bajer

1 użytkowników online, w tym zalogowanych: 0, gości: 1