Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [Delphi] Вебкамера, датчик движения (https://forum.antichat.xyz/showthread.php?t=146775)

iama 08.10.2009 22:40

[Delphi] Вебкамера, датчик движения
 
Пишу датчик движения под вебкамеру. Подскажите, какой общий алгоритм может быть при сравнении двух последних изображений с веб камеры, если нужно обвести движущийся элемент красный цветом (по периметру)?
При надобности могу выложить исходники.

slesh 09.10.2009 10:03

вообще есть довольно интересный алгоритм. основанный на такой вещи:
ты сравниваеш 2 картинки. можно сразу загнуть в память их битмапы, и сравнивать память. Далее под размер битмапа можно выделить память и очистить ей. Если есть отклонение цветов больше допустимого, то в третью область памяти ставиш пометку что в этом месте изменилось.
В этоге в выделенной памяти можно будет наблюдать карту отклонений к примеру в Затем произвести так называемую очистку, т.е. удаление одиночно стоящих точек или маленьких групп точек.
Ну а потом пройдясь по горизонтали и вертикали на картинке, подсветить цветом места там где в выделенной памяти идет переход от черного к белому или от белого к черному. В этоге ты получиш обводку практически по контуру.
Ну или просто вычислить центры групп точек и обвести их овалом.
Это самый приметивный и самый простой в реализации алгоритм

iama 09.10.2009 17:47

обрабатываю два битмапа так -

Код:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
d1:=GetTickCount;
bmp2.Assign(bmp1); SampleGrabber1.GetBitmap(bmp1); if bmp2.Empty then exit;
k := 0;
for i := 0 to bmp1.Height - 1 do begin
  p1 := bmp1.ScanLine[i];  p2 := bmp2.ScanLine[i];
  for j := 0 to bmp1.Width - 1 do begin
    PriznakChange:=0;
    if p1 = p2 then continue;
    if (p1[j].r<>p2[j].r) and
      (p1[j].b<>p2[j].b) and
      (p1[j].g<>p2[j].g) then
      k:=k+1;
  end;
end;
Caption := 'Static';
if k > 307200 * StrToInt(edit1.Text) div 1000 then begin
  bmp1.SaveToFile(FormatDateTime('hhnnss',Now)+'.bmp');
  Caption := 'Move';
  Application.ProcessMessages;
end; Caption := Caption + ' ' + IntToStr(k);
end;

Всё то работает хорошо, но такое чувство, что видеопоток опаздывает на 10-15 мсекунд. Изза чего это может быть? Частота обновления таймера - 100мс, процедура обработки занимает 20-30мс.

slesh 11.10.2009 00:06

а ты посчитай сколько по времени вся процедура длится вместе с сохранением.
Засеки в начале и в конце время через GetTickCount

iama 11.10.2009 09:47

Я ж пишу, уже проверил.

flacs 11.10.2009 10:21

1. частота обновления слишком низкая, попробуй поставь 1 мс в таймере
2. попробовать вот такую схему, в отдельном потоке

Код:

while true do begin
  //.... обработчик
 sleep(1);
end;

3. Возможно также, что слишком большой размер изображения сохраняется, попробуй сделать его чернобелым что то вроде, Bitmap.PixelFormat:=pf1bit;

slesh 11.10.2009 12:02

А вообще есть вот такая вот хитрая вешь - библиотека OpenCV. Она вроде под С++ билдер, но скорее всего есть заточка и под делфи, потому что тоже на VCL сделан компонент.

Вот сайт там много по этой теме и алгоритмов для извлечения изображений.
http://www.smorodov.narod.ru/CompVision.htm


Время: 09:05