odczyt klatek z filmu

0

Witam.

Odtwarzam film za pomoca DSPack'a i chce analizowac kazda klatke filmu. Odczytuje wartosci R, G, B kazdego pixela i na ich podstawie wyliczam srednie wartosci R,G,B dla calej klatki.
Korzystam z Sample Grabbera:

procedure TForm1.SampleGrabberBuffer(sender: TObject; SampleTime: Double;
pBuffer: Pointer; BufferLen: Integer);
var
i, R, G, B, X, Y : Integer;
Bitmap: TBitmap;
begin
f:=f+1;
if CallBack.Checked then
begin
i:=0; R:=0; G:=0; B:=0; X:=0; Y:=0;
Bitmap:= TBitmap.Create;
SampleGrabber.GetBitmap(Bitmap, pBuffer, BufferLen);
while X < Bitmap.Width -1 do
begin
Y:=0;
while Y< Bitmap.Height -1 do
begin
R:=R + GetRValue(Bitmap.Canvas.Pixels[x,y]);
G:=G + GetGValue(Bitmap.Canvas.Pixels[x,y]);
B:=B + GetBValue(Bitmap.Canvas.Pixels[x,y]);
i:=i+1;
Y:=Y+1;
end;
X:=X+1;
end;

  Label1.Caption:= Format('Red: %s', [IntToStr(R Div i)]);
  Label2.Caption:= Format('Green: %s', [IntToStr(G Div i)]);
  Label3.Caption:= Format('Blue: %s', [IntToStr(B Div i)]);
  Label4.Caption:= Format('i: %s', [IntToStr(i)]);
 end;

// Bitmap.Free;
end;

I problem w tym ze w ten sposob kazda klatka filmu jest przetwarzana prawie przez jedna sekunde !!! A dla przykladu komponent VideoLab robi to w czasie rzeczywistym (20-25 klatek na sek.).
Czy jest jakis sposob aby to przyspieszyc w DSPacku?? Moze jakis inny sposob zamiast kopiowania klatki do Tbitmap (Bo chyba to zżera tyle czasu i pamieci)?

I dlaczego komenda Bitmap.Free wywala mi program??

Dzieki za wszelki podpowiedzi.
Pozdrawiam.

0

A moze zna ktos jakis komponent graficzny, ktory tworzy np. histogram obrazka i w ten sposob moglbym oszybciej odczytac wartosci RGB?

0

Działa powoli, bo uzywasz Canvas.Pixels. Użyj lepiej ScanLine.

0

Ok. Uzywam Scanline :

...
linia: PByteArray;
...
for Y:=0 to Image.Picture.Bitmap.Height-1 do
begin
linia:=Image.Picture.Bitmap.ScanLine[Y];
for X:=0 to Image.Picture.Bitmap.Width-1 do
begin
G:=G + GetGValue(linia[X]);
R:=R + GetRValue(linia[X]);
B:=B + GetBValue(linia[X]);
i:=i+1;
end;
end;

Ale teraz odczytuje mi tylko wartosc R. Pozostale czyli G i B maja caly czas wartosc zero.
Dlaczego?
Pewnie nie do konca zrozumialem jak dziala Scanline.
Ktos wie gdzie tkwi blad?

Dzieki za szybka odpowiedz.

0

Ok. Uzywam Scanline :

...
linia: PByteArray;
...
for Y:=0 to Image.Picture.Bitmap.Height-1 do
begin
linia:=Image.Picture.Bitmap.ScanLine[Y];
for X:=0 to Image.Picture.Bitmap.Width-1 do
begin
G:=G + GetGValue(linia[X]);
R:=R + GetRValue(linia[X]);
B:=B + GetBValue(linia[X]);
i:=i+1;
end;
end;

Ale teraz odczytuje mi tylko wartosc R. Pozostale czyli G i B maja caly czas wartosc zero.
Dlaczego?
Pewnie nie do konca zrozumialem jak dziala Scanline.
Ktos wie gdzie tkwi blad?

Dzieki za szybka odpowiedz.

Tez nie jestem w tym doswiadczony, ale z tego co wiem powinien byc wczesniej jeszcze okreslony format bitmapy. Zrobiles to?

0

PixelFormat musi być ustawiony na pf24bit, a kolory to tak się pobiera:

B:=B+linia[X3];
G:=G+linia[X
3+1];
R:=R+linia[X*3+2];

ewentualnie r może się zamienić z b, bo nie pamiętam, czy to było w rgb, czy w bgr.

0

Ok. Dzieki serdeczne.

Zrobilem to tak:

Image.Picture.Bitmap.PixelFormat:=pf24bit;
for Y:=0 to Image.Picture.Bitmap.Height-1 do
begin
linia:=Image.Picture.Bitmap.ScanLine[Y];
for X:=0 to Image.Picture.Bitmap.Width-1 do
begin
B:=B + linia[X3];
G:=G + linia[X
3+1];
R:=R + linia[X*3+2];
i:=i+1;
end;
end;

Testowalem i dziala.
Dzieki.
Pozdrawiam.

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