运动目标跟踪之“差分图像法”。它是根据当前图像与参考图像的差别分析来判断序列图像中是否有运动物体,来检测运动物体的。在环境亮度变化不大的情况下,如果对应像素灰度相差很小,可以认为此处景物是静止的;如果图像区域某处的灰度变化很大,则认为这是由于图像中运动物体引起的,然后求出运动目标在图像中的位置。
根据差分的参考图像不同,可以分为基于相邻帧差的算法和基于背景图像与当前帧差的算法:基于相邻帧差法是将前后两帧图像对应像素点的灰度值相减,基于背景图像与当前帧差的算法则是将当前帧和背景帧对应像素的灰度值相减。
此类帧间差算法可以分为三部分:1.选择、产生一个参考或者背景图像;2.做帧间差运算操作;3.选择应用一个合适的阈值。
参考图像可以使用多种方法获得,如选择屏幕相对静止时期的背景,或从一个动态序列中选择一个暂时的叫临近的图像。同时,应该在选择中加入更新策略,以保证参考图像保持不断更新。
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.MovieClip; import flash.display.Shape; import flash.events.Event; import flash.geom.Rectangle; import flash.net.URLRequest; import flash.text.TextField; public class Main extends MovieClip { public var tf:TextField; public function Main() { // constructor code stage?initStage(null):addEventListener(Event.ADDED_TO_STAGE, initStage); } private function initStage(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, initStage); var mv:MovieClip; var bmd1:BitmapData = new BitmapData(300, 300, true, 0x00000000); var bmp1:Bitmap = new Bitmap(bmd1); var bmd2:BitmapData = bmd1.clone(); var bmp2:Bitmap = new Bitmap(bmd2); var bmd3:BitmapData = bmd1.clone(); var bmp3:Bitmap = new Bitmap(bmd3); addChildAt(bmp1,0); addChildAt(bmp2,0); addChildAt(bmp3,0); bmp1.x = 300; bmp1.y = 0; bmp2.x = 600; bmp2.y = 0; bmp3.x = 0; bmp3.y = 300; var shape:Shape = new Shape(); addChildAt(shape,0); shape.x = 300; shape.y = 300; var rect:Rectangle = new Rectangle(0, 0, 300, 300); var ld:Loader = new Loader(); ld.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded); ld.load(new URLRequest("movie.swf")); function onLoaded(e:Event):void { mv = ld.content as MovieClip; addChildAt(mv,0); mv.x = mv.y = 0; bmd1.fillRect(rect, 0x00000000); bmd1.draw(mv); bmd2.fillRect(rect, 0x00000000); bmd2.draw(mv); updateBmd3(); addEventListener(Event.ENTER_FRAME, enterFrameHandler); } function enterFrameHandler(e:Event):void { bmd1.fillRect(rect, 0x00000000); bmd1.draw(bmd2); bmd2.fillRect(rect, 0x00000000); bmd2.draw(mv); updateBmd3(); } var lastBounds:Rectangle; function updateBmd3():void { var vec1:Vector.= bmd1.getVector(rect); var vec2:Vector.= bmd2.getVector(rect); var vec3:Vector.= new Vector.(); var len:int = vec1.length; for (var i:int = 0; i < len;i++ ) { vec3[i] = vec2[i] - vec1[i]; } bmd3.setVector(rect, vec3); var bounds:Rectangle = bmd3.getColorBoundsRect(0xFF000000, 0x00000000, false); shape.graphics.clear(); shape.graphics.lineStyle(1, 0xff0000, 1.0); shape.graphics.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); if (lastBounds) { tf.text = "小手信息:\n" +bounds+"\n" +"x方向速度:" + (bounds.x - lastBounds.x)+"px/frame\n" +"y方向速度:"+(bounds.y-lastBounds.y)+"px/frame\n"; } lastBounds = bounds; } } } }
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。