PDA

Просмотр полной версии : Оптимизация алгоритма распознавания движения в видео


tali4
21.07.2009, 11:42
Добрый день.

У меня следующая проблема.
В некотором приложении происходит управление с помощью веб-камеры следующим образом:


detector = new MotionDetectorAreas( output , BLOCKS , SENSITIVITY, [btn1, btn2]);
//output -- видео с камеры
onEnterFrame=step;

function step ()
{
var differences:Array = detector.getDifferences( );

for ( var b:Number=0; b<differences.length; b++ )
{
var helpRectangle:Rectangle = new Rectangle( differences[b].x , differences[b].y , BLOCKS , BLOCKS );

if(btn1.hitTest((differences[b].x+BLOCKS/2+this._x+this._parent._x) , (differences[b].y+BLOCKS/2+this._y+this._parent._y)))
{
onEnterFrame=null;
Tweener.addTween(btn1, {_alpha:100,
time:0.3,
onComplete:function()
{
Tweener.addTween(btn1, {_alpha:30, time:0.2, onComplete:repairEnterFrame});
}
});
}

if(btn2.hitTest( (differences[b].x+BLOCKS/2+this._x+this._parent._x) , (differences[b].y+BLOCKS/2+this._y+this._parent._y)))
{
onEnterFrame=null;
Tweener.addTween(btn2, {_alpha:100,
time:0.3,
onComplete:function()
{
Tweener.addTween(btn2, {_alpha:30, time:0.2, onComplete:repairEnterFrame});
}
});
}
}
}


function repairEnterFrame()
{
onEnterFrame=step;
}


где MotionDetectorAreas--класс


import flash.geom.Point;
import flash.media.Camera;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.geom.*;

class MotionDetectorAreas
{
private var video:Video;
private var oldData:BitmapData;
private var newData:BitmapData;
private var blockSize:Number;
private var sensitivity:Number;
private var areas:Array;

public function MotionDetectorAreas ( argVideo:Video ,
argBlockSize:Number ,
argSensitivity:Number,
argareas:Array)
{

video = argVideo;
blockSize = argBlockSize;
sensitivity = argSensitivity;
areas=argareas;

oldData = new BitmapData( video._width , video._height , false );
newData = new BitmapData( video._width , video._height , false );

}


public function getDifferences ( ):Array
{
var mt:Matrix=new Matrix();
mt.translate(-video._width, 0);
mt.scale(-1, 1);
newData.draw(video, mt);

var differences:Array = [ ];

// looping through points with stepping


for(var i:Number=0; i<areas.length; i++)
{
for ( var px:Number = areas[i]._x ; px < areas[i]._x+areas[i]._width ; px += blockSize )
{
for ( var py:Number = areas[i]._y ; py < areas[i]._y+areas[i]._height ; py += blockSize )
{
var oldPixel:Number = oldData.getPixel( px , py );
var newPixel:Number = newData.getPixel( px , py );

if ( Math.abs( newPixel - oldPixel ) > sensitivity )
{
differences.push( new Point( px , py ) );
}
}
}
}
oldData.copyPixels( newData , newData.rectangle , new Point( 0 , 0 ) );
return differences;
}
}



Большие проблемы с производительностью. Тестил, отрисовывая BitmapData, которая получается из var differences:Array = detector.getDifferences( ); Изза тормозов появляется "шлейф", который приводит к двойному нажатию на кнопки. Пробовал:
1) выполнять код раз в 2 фрейма
2) выполнять код по таймеру
3) увеличивать размер блоков(blockSize)
но результат всегда примерно одинаковый. Так же заметил что тормозов добавляет hitTest. Еще одна проблема в том что в основном ролике воспроизводится видео и есть onEnterFrame функции.

Если у кого то есть предложения по оптимизации, буду очень благодарен

Добавлено через 3 часа 54 минуты
убрал onEnterFrame=null; и сделал восстановление enterFrame по флагу.
Немного помогло. Тормозов меньше. Но все равно залеко от идеала