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 по флагу.
Немного помогло. Тормозов меньше. Но все равно залеко от идеала
У меня следующая проблема.
В некотором приложении происходит управление с помощью веб-камеры следующим образом:
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 по флагу.
Немного помогло. Тормозов меньше. Но все равно залеко от идеала