[delphi] praca z obrazem, przeszukiwanie

0

witam wszystkich ponownie,

mam następujący problem :

potrzebuje jakiś bardzo szybki algorytm, który będzie w stanie przeszukiwać obrazek załadowany do TImage.

generalnie zasada jest bardzo prosta, petla przeszukuje obrazek az do znalezienia piksela o danej wartości, następnie przeszukuje cały obrazek w poszukiwaniu kolejnego piksela o takiej samej wartości (wartość będzie stała, zakładajmy że chodzi o kolor FFFFFF) następnie jeśli znajdzie 2 piksele takie same w rożnych częściach obrazka, sprawdza kolejne "podpiksele" np idąc od obu pikseli pod kątem 45 w dolny prawy róg i sprawdzając czy kolejne... powiedzmy 10 pikseli jest identycznych, jeśli tak, to zwraca pozycję obu pikseli.

miał ktoś z czymś takim do czynienia ?

zrobiłem swój algorytm działający na zasadzie petli która szuka piksela o wartości FFFFFF a następnie drugiego, jeśli znajdzie to robi dokładnie to co opisałem wyżej, na core 2 duo 2,13 przeskanowanie w ten sposób obrazka 1000x1000 px to około 40 sekund, a to stanooowczo za dużo,
rozwiązanie problemu potrzebne jest do pracy magisterskiej, wdzięczny byłbym za pomoc lub wskazanie jakiegoś gotowego lub prawie gotowego rozwiązania problemu. na procesorze i3 2,13 - tak na marginesie :) - przeliczenie takiego obrazka zajęło 11 sekund :P

Pozdrawiam
Ramzess

0

Pierwsze co, to nie używaj Pixels tylko ScanLine. I wtedy powiedz jakie masz czasy.

0

aja bym proponowal wstawic obrazek do jednowymiarowej tablicy np. array of integer

ponziej funkcja zwracajaca f(x) czyli jak szerokosc obrazka jest 100 a jestemsy w x = 102 to f(x) zwroci = 2 - czyli druga linijka proste 102-100 = 2 itp. itd.

0

w Twoim wypadku najlepiej bedzie polaczyc oba rozwiazania:
wyciagnac wartosc pixeli uzywajac scanline a nastepnie wrzucic to wszystko do tablicy i potem wyszukiwac juz w tablicy.
generalnie temat byl juz wielokrotnie poruszany wiec poszukaj.

0

Tutaj mam kod

procedure TForm1.Button2Click(Sender: TObject);
Var
     i: Integer;
     j: Integer;
Begin
     image1.Picture.LoadFromFile('plik.bmp');
     for i:= 0 to 733 do begin
          for j:= 0 to 444 do begin



          end;
        end;

End;

ale nie moge ogarnac tego skanline.

jak to wrzucic do tablicy ?

ustalmy ze tablica ma wymiar dokladnie 733x444
wystarczy jesli bedzie wrzucalo do tablicy pod warunkiem ze kolor sprawdzany = FFFFFF;

moglby mnie ktos wesprzec ? termin sie zbliza, a ja nie jestem mistrzem programowania ;/

Ramzess

0

scanline dziala tak, ze laduje Ci caly wiersz pixeli do tablicy.
ale w tablicy nie siedza "kolory", jako TColor tylko wartosci R,G,B. sa zapisane w takiej kolejnosci:
B G R B G R B G R B G R B G R B G R B G R B G R B G R ...
pierwsze 3 bajty tablicy to wartosci B,G i R pierwszego pixela.
nastepne 3 bajty z tablicy to wartosci B,G i R drugiego pixela itd...

ten kod zaczernia wszystkie pixele:

var bmp : TBitmap;
    x,y : integer;
    line : PByteArray;
begin
{...}
   for y := 0 to bmp.Height-1 Do
   begin
     line := bmp.ScanLine[y];
     x := 0;
     while (x < (bmp.Width-1)*3) do
     begin
         line[x+0] := 0; //b
         line[x+1] := 0; //g
         line[x+2] := 0; //r
         Inc(x,3);
     end;
   end;

teraz lapiesz?

P.S. kazdy pisze jak mu wygodniej, ale pytanie do Ramzessa: czy nie pogubisz sie w kodzie nazywajac zmienne "i,j"? ja zawsze w przypadku grafiki nazywam x,y.

P.S. 2: a tu kod do wrzucenia bitmapy do tablicy:

var bmp : TBitmap;
    x,y : integer;
    line : PByteArray;
    tablica:array[0..1023,0..767] of TColor;//moze jako globalna?
begin
{...}
  for y := 0 to bmp.Height-1 Do
    begin
      line := bmp.ScanLine[y];
      x := 0;
      while (x < (bmp.Width-1)*3) do
           begin
             tablica[x,y]:= RGB(   line[x+2], line[x+1], line[x+0]   );
             Inc(x,3);
           end;
    end;

i potem tylko zeby sprawdzic kolor jakiegos pixela:

for x:=0 to 1023 do
  for y:=0 to 767 do
    if tablica[x,y]=clLime then...

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