Skocz do zawartości

[Delphi] - szukam naprawdę szybkiego sposobu obróbki Bitmapy


Integer

Polecane posty

Witam

 

Szukam naprawdę szybkiego sposobu przeszukiwania i obróbki bitmapy,

Czegoś co by się mieściło 1-2 msec max w kilku, chodzi tu o operacje w stylu:

- przeszukiwanie bitmapy w w poszukiwaniu wybranego koloru,

- albo w poszukiwaniu kolorów z wyłączeniem kilku kilkudziesięciu z listy z listy,

- zamiana czerwonawych na 0, 0, 255 itp

 

Jest kilka procedur które sie tym zajmuja ale operacja na R,G,B: Byte i odczytanie ze Bitmap.ScanLine[y] okazuje się dość wolna,

gdyż suma operacji od wczytania bitmapy , przez filtrowanie, kontrastowanie, rozjaśnianie, wyszukiwanie tych odpowiednich,

wyszukiwanie plam o zbliżonym odcieniu trwa od 6000 - 12000 msec a mi potrzebna jest max 100msec albo coś tego rzędu,

no 1000 jeszcze przejdzie w ostateczności.

 

Dodatkowo te operacje powtarzały by się co 100msec przez powiedzmy godzinę i teraz mam po prostu klina.

Prosiłbym o podpowiedź co można by zastosować aby takie parametry osiągnąć,

mam kilka teorii ale aż boję się o nich myśleć....

Link do komentarza
Udostępnij na innych stronach

Cały kod jest dość obszerny (8 większych modułów i kilka miejszych) i wolałbym go nie upubliczniać ale dla przykładu:

 

procedure TPictSearchObjCustom.PrzygotowanieBitmap(var _BmpOrgiL: TBitmap);
begin //
 _BmpOrgiL.PixelFormat:= pf24bit;

 FBmpPrev.Assign(_BmpOrgiL);

 FZoomR:= _BmpOrgiL.Width / FBmpSkalaWidth;
 FZoomI:= _BmpOrgiL.Width div FBmpSkalaWidth;

 Application.ProcessMessages;
 if FZoomI>1 then begin             // 640x480 -> 80x60
   ZoomTrueColor(FBmpPrev, FZoomI);           // pomniejszony orginał
   {
   MosaicWithColor(FBmpPrev, FZoomI);                       // pomniejszony orginał
   Application.ProcessMessages;
   Zoom(FBmpPrev, FZoomI);
   Application.ProcessMessages;
   }
 end;

 Application.ProcessMessages;
 FBmpMono.Assign(FBmpPrev);
   // Contrast(FBmpGray, 70);
   // Lightness(FBmpGray, 80);
   // ContrastLightness(FBmpGray,  70, 80);
   // ExpandUpDownColor(FBmpGray, 80, 255);
   ContrastLightnessExpandUpDownColor (FBmpMono, 80, 70, 90, 255);

 GrayScale(FBmpMono);

 //FBmpMono.Assign(FBmpGray);
   ThresholdByte(FBmpMono, 255, 0, 90);
   // KasujSamotnePixele1(FBmpMono, 128);
   // MosaicToBlack(FBmpMono, 4);                       // pomniejszony orginał
   Application.ProcessMessages;                                  
end;

+ZrŚŚy\"xŹnui'procedure GrayScale(var Bitmap:TBitmap);
var
Row:^TRGBTriple; // wskaźnik do rekordu reprezentującego składowe RGB Pixela
H,V,Index:Integer;
begin
Bitmap.PixelFormat:=pf24bit;
for V:=0 to Bitmap.Height-1 do
 begin
   Row:=Bitmap.ScanLine[V];
   for H:=0 to Bitmap.Width -1 do
   begin
   Index := ((Row.rgbtRed * 77 +       //77 to stała dla czerwieni
      Row.rgbtGreen* 150 +           //150 stała dla zielonego
      Row.rgbtBlue * 29) shr 8);    //29  stała dla niebieskiego
      Row.rgbtBlue:=Index;
      Row.rgbtGreen:=Index;
      Row.rgbtRed:=Index;
      inc(Row);{ Nie wolno przypisywać X:=0 lub 1,2 bo to Wskaźnk!!! poruszamy się inc() lub dec()}

   end;
 end;
end;

 

domyślam się że jeden taki piksel jest sprawdzany z 9 razy jak nie więcej czy jest koloru czerwonego czy tez nie.., ale głowie się i nic szybszego mi nie przychodzi do głowy.

Link do komentarza
Udostępnij na innych stronach

gdzie dla całości obrazu:

 

 function  TPictObszaryRGB.Point_SprPoint(_xs, _ys: Integer): Boolean;
var p: pbytearray;
   r,g,b: Byte;
   X3: Integer;
begin
 Result:= False;
 Application.ProcessMessages;

 if (not ((0<_xs) and (_xs<FBmpMono.Width-1))) or    // X lub Y nie mieści sie w ramce
    (not ((0<_ys) and (_ys<FBmpMono.Height-1))) then Exit;

 p:= FBmpMono.Scanline[_ys];
 x3:= _xs*3;
 // pobieranie wartości pierwszej składowej koloru
 b:= p[x3];
 g:= p[x3+1];
 r:= p[x3+2];
 if not Point_NotTlo(r, g, b) then Exit;
 Point_ZmienNaColorOdkr(p, _xs);
 Result:= True;
end;

function  TPictObszaryRGB.Obszar_DodajPoint(_NewOb: PObsz; _xs, _ys: Integer): Boolean;
begin
 Result:= False;
 if not Point_SprPoint(_xs, _ys) then Exit;
 if not ObszAddPoint(_NewOb, _xs, _ys) then Exit;
 Result:= True;
end;

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...