[Delphi] Вебкамера, датчик движения

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by iama, 8 Oct 2009.

  1. iama

    iama New Member

    Joined:
    6 Aug 2009
    Messages:
    11
    Likes Received:
    2
    Reputations:
    0
    Пишу датчик движения под вебкамеру. Подскажите, какой общий алгоритм может быть при сравнении двух последних изображений с веб камеры, если нужно обвести движущийся элемент красный цветом (по периметру)?
    При надобности могу выложить исходники.
     
    #1 iama, 8 Oct 2009
    Last edited: 8 Oct 2009
    1 person likes this.
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    вообще есть довольно интересный алгоритм. основанный на такой вещи:
    ты сравниваеш 2 картинки. можно сразу загнуть в память их битмапы, и сравнивать память. Далее под размер битмапа можно выделить память и очистить ей. Если есть отклонение цветов больше допустимого, то в третью область памяти ставиш пометку что в этом месте изменилось.
    В этоге в выделенной памяти можно будет наблюдать карту отклонений к примеру в Затем произвести так называемую очистку, т.е. удаление одиночно стоящих точек или маленьких групп точек.
    Ну а потом пройдясь по горизонтали и вертикали на картинке, подсветить цветом места там где в выделенной памяти идет переход от черного к белому или от белого к черному. В этоге ты получиш обводку практически по контуру.
    Ну или просто вычислить центры групп точек и обвести их овалом.
    Это самый приметивный и самый простой в реализации алгоритм
     
  3. iama

    iama New Member

    Joined:
    6 Aug 2009
    Messages:
    11
    Likes Received:
    2
    Reputations:
    0
    обрабатываю два битмапа так -

    Code:
    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мс.
     
    #3 iama, 9 Oct 2009
    Last edited: 9 Oct 2009
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    а ты посчитай сколько по времени вся процедура длится вместе с сохранением.
    Засеки в начале и в конце время через GetTickCount
     
    1 person likes this.
  5. iama

    iama New Member

    Joined:
    6 Aug 2009
    Messages:
    11
    Likes Received:
    2
    Reputations:
    0
    Я ж пишу, уже проверил.
     
  6. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    1. частота обновления слишком низкая, попробуй поставь 1 мс в таймере
    2. попробовать вот такую схему, в отдельном потоке

    Code:
    while true do begin
      //.... обработчик
     sleep(1);
    end;
    3. Возможно также, что слишком большой размер изображения сохраняется, попробуй сделать его чернобелым что то вроде, Bitmap.PixelFormat:=pf1bit;
     
  7. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    А вообще есть вот такая вот хитрая вешь - библиотека OpenCV. Она вроде под С++ билдер, но скорее всего есть заточка и под делфи, потому что тоже на VCL сделан компонент.

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