Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Provera da li se manja slika nalazi u vecoj slici

[es] :: Pascal / Delphi / Kylix :: Provera da li se manja slika nalazi u vecoj slici

[ Pregleda: 1358 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Provera da li se manja slika nalazi u vecoj slici18.09.2009. u 06:06 - pre 178 meseci
Dakle, treba mi funkcija koja proverava da li se neka manja slika sadrzi u nekoj vecoj slici i ako se nalazi, vraca koordinate manje slike (slike se ucitavaju tokom runtimea).
Napisao sam ovako nesto:

Code:
  TImageCompareInfo = record
                        Found                    : Boolean;
                        Left, Top, Width, Height : Integer;
                      end;

function CompareImage(ABigImage, ASmallImage : TBitmap; var imagecomp : TImageCompareInfo) : Boolean;
var
  C1, C2, C3, C4 : Integer;
  different      : Boolean;
begin
  result := FALSE;

  ABigImage.PixelFormat := pf24bit;

  For C1 := 0 to ABigImage.Height - ASmallImage.Height - 1 Do
  Begin
    For C2 := 0 to ABigImage.Width - ASmallImage.Width - 1 Do
      If ABigImage.Canvas.Pixels[C2, C1] = ASmallImage.Canvas.Pixels[0, 0] Then
      Begin
        different := FALSE;
        For C3 := C2 + 1 to C2 + ASmallImage.Width - 1 Do
        Begin
          For C4 := C1 + 1 to C1 + ASmallImage.Height - 1 Do
          Begin
            If ABigImage.Canvas.Pixels[C3, C4] - ASmallImage.Canvas.Pixels[C3 - C2, C4 - C1] > $01 Then
            Begin
              different := TRUE;
              Break;
            End;
          End;
          If different Then
            Break;
        End;

        If not different Then
        Begin
          imagecomp.Found := TRUE;
          imagecomp.Left := C2;
          imagecomp.Top := C1;
          imagecomp.Width := ASmallImage.Width;
          imagecomp.Height := ASmallImage.Height;
          result := TRUE;
          Exit;
        End;
      End;
  End;
end;


Medjutim, da li postoji neka optimizovanija funkcija koja radi ovo ? Jer ovoj mojoj treba otprilike 4-5 sekundi da procesuira sliku od 1440x900.

Hvala unapred.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Provera da li se manja slika nalazi u vecoj slici18.09.2009. u 12:20 - pre 178 meseci
> Medjutim, da li postoji neka optimizovanija funkcija koja radi ovo ? Jer ovoj mojoj treba otprilike 4-5 sekundi da procesuira sliku od 1440x900.

Koristi ScanLine da porediš red po red.

 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Provera da li se manja slika nalazi u vecoj slici18.09.2009. u 15:18 - pre 178 meseci
Napisao sam ovako nesto pomocu ScanLine, ali ne radi i ne mogu da uocim zasto :\ Verovatno lose radim sa ScanLine().

Code:
function CompareImage(smallImage, bigImage : TBitmap) : Boolean;
var
  C1, C2, C3, C4           : Integer;
  smallLine, bigLine       : PByteArray;
  different                : Boolean;
  smallTmpLine, bigTmpLine : PByteArray;
begin
  result := FALSE;
  
  smallLine := smallImage.ScanLine[0]; // skeniramo prvu liniju male slike

  For C1 := 0 to bigImage.Height - smallImage.Height - 1 Do // postavljamo brojac po Y komponenti velike slike
  Begin
    bigLine := bigImage.ScanLine[C1]; // skeniramo C1 liniju velike slike

    For C2 := 0 to bigImage.Width - smallImage.Width - 1 Do // uporedjujemo da li je prvi pixel male slike = nekom pixelu prethodno skenirane linije velike slike
      If bigLine[C2] = smallLine[0] Then
      Begin
        different := FALSE;

        For C4 := 0 to smallImage.Height - 1 Do // brojac po Y komponenti male slike
        Begin
          smallTmpLine := smallImage.ScanLine[C4];
          bigTmpLine := bigImage.ScanLine[C1 + C4];

          For C3 := C2 to C2 + smallImage.Width - 1 Do // uporedujemo dve prethodno skenirane linije
            If bigTmpLine[C3] <> smallTmpLine[C3 - C2] Then
            Begin
              different := TRUE;
              Break;
            End;

          If different Then
            Break;
        End;

        If not different Then
          result := TRUE;
      End;
  End;
end;


Funkcija postavlja brojac od 0 do visina velike slike - 1 i uporedjuje prvi pixel male slike sa svakim pixelom velike slike. Ako se poklapaju onda postavlja jos dva brojaca (C4 i C3) koji uporedjuju malu sliku sa tim iseckom iz velike slike, pocevsi od koordinate prvog pixela koji se poklapa.
 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Provera da li se manja slika nalazi u vecoj slici20.09.2009. u 15:00 - pre 178 meseci
Resio sam problem.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
93.86.158.*



+62 Profil

icon Re: Provera da li se manja slika nalazi u vecoj slici25.09.2009. u 09:57 - pre 178 meseci
Razmisljao sam malo o ovom (zanimljivom) problemu.
Plus, secam se i nekih (davnih?) prica u stilu "Delphi nije los, ali danas ima ozbiljnijih alata bla, bla, bla".
Posto je autor trazio/pitao za neku optimizovanu verziju resenja problema, dajem skroman prilog,
bas u inat ovim nevernim Tomama .
Delphi je veoma jak sa tipovima podataka. Iako neki smatraju da je ovo ogranicenje,
to zapravo nije tacno, sto cemo i pokazati na primeru.

Evo prvo nekoliko cinjenica iz D, koje ce nam pomoci da ovo uradimo kako lici:

1) Delphi ima veoma mocan rad sa stringovima; sve je to pisano u asembleru.
Pa tako, poredjenje dva stringa je prakticno trenutno, nebitno od velicine istih.
Rutina radi upravo tako kako je autor teme radio poredjenje dve scan linije: byte po byte,
odnosno char po char, i odustajanje na prvu razliku.

2) Sada je vec jasno na koju pricu navodim, ideja je da eliminisemo unutrasnju/malu petlju koja poredi pixele,
odnosno bajtove iz scan linije.

3) Funkcija copy() koja vraca substring (za one koji nisu znali) radi sa maltene svim kolekcijama karaktera,
pa tako i sa char arrays.

4) Mi cemo zato iskoristiti pointer na char array. kao sto sledi.


Evo malo koda:

Code:

type
  TCharArray = array[0..$8000] of char;
  PCharArray = ^TCharArray;
var
  PCASour, PCADest: PCharArray;
begin
  PCASour := BmpSour.ScanLine[Any1];  // neka linija prve bmp
  PCADest := BmpDest.ScanLine[Any2];  // neka linija druge bmp
 // sada poredimo odsecke linija po svom nahodjenju
  Differrent := copy(PCASour^, AnyStart1, AnyLength1) <> copy(PCADest^, AnyStart2, AnyLength2); // i, zbogom mala petljo...


Kako vam se cini ovo? ;)

Rajko

EDIT: U zadnjoj liniji sam stavio '=' umesto '<>'; ispravljeno. :)


[Ovu poruku je menjao Rapaic Rajko dana 25.09.2009. u 11:47 GMT+1]
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Provera da li se manja slika nalazi u vecoj slici

[ Pregleda: 1358 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.