Пишу датчик движения под вебкамеру. Подскажите, какой общий алгоритм может быть при сравнении двух последних изображений с веб камеры, если нужно обвести движущийся элемент красный цветом (по периметру)? При надобности могу выложить исходники.
вообще есть довольно интересный алгоритм. основанный на такой вещи: ты сравниваеш 2 картинки. можно сразу загнуть в память их битмапы, и сравнивать память. Далее под размер битмапа можно выделить память и очистить ей. Если есть отклонение цветов больше допустимого, то в третью область памяти ставиш пометку что в этом месте изменилось. В этоге в выделенной памяти можно будет наблюдать карту отклонений к примеру в Затем произвести так называемую очистку, т.е. удаление одиночно стоящих точек или маленьких групп точек. Ну а потом пройдясь по горизонтали и вертикали на картинке, подсветить цветом места там где в выделенной памяти идет переход от черного к белому или от белого к черному. В этоге ты получиш обводку практически по контуру. Ну или просто вычислить центры групп точек и обвести их овалом. Это самый приметивный и самый простой в реализации алгоритм
обрабатываю два битмапа так - 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мс.
а ты посчитай сколько по времени вся процедура длится вместе с сохранением. Засеки в начале и в конце время через GetTickCount
1. частота обновления слишком низкая, попробуй поставь 1 мс в таймере 2. попробовать вот такую схему, в отдельном потоке Code: while true do begin //.... обработчик sleep(1); end; 3. Возможно также, что слишком большой размер изображения сохраняется, попробуй сделать его чернобелым что то вроде, Bitmap.PixelFormat:=pf1bit;
А вообще есть вот такая вот хитрая вешь - библиотека OpenCV. Она вроде под С++ билдер, но скорее всего есть заточка и под делфи, потому что тоже на VCL сделан компонент. Вот сайт там много по этой теме и алгоритмов для извлечения изображений. http://www.smorodov.narod.ru/CompVision.htm