边缘检测的Canny算子与碰撞

人机交互 everyinch 2358℃ 0评论

上篇博文演示了下落的小球与WebCamera视频图像中边缘的碰撞效果,对于视频边缘的提取略显粗糙,使用Canny算子可以提取更为精细的边缘
源代码:WebCamera_Canny

package{
import com.bit101.components.CheckBox;
import com.bit101.components.HUISlider;
import com.bit101.components.Panel;
import com.bit101.components.Style;
import com.coreyoneil.collision.CollisionList;
import com.quasimondo.bitmapdata.CameraBitmap;

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;

import ru.inspirit.bitmapdata.CannyEdgeDetector;

[SWF(frameRate=”31″)]
public class WebCamera_Canny extends Sprite{
private var camera:CameraBitmap;
private var cannyBmpd:BitmapData;
private var cannyBmp:Bitmap;

private var cannyEdgeDetector:CannyEdgeDetector;
private var _bold:Boolean = false;
private var _binary:Boolean = true;

private var w:int = 400;
private var h:int = 300;

private var collisionList:CollisionList;
private var bubbles:Array;
private var gravity:Number = 1;
private var friction:Number = 0.95;

private var panel:Panel;

public function WebCamera_Canny(){
if(stage) init();
else addEventListener(Event.ADDED_TO_STAGE,init);
}

private function init(e:Event = null):void{
initStage();

camera = new CameraBitmap(w,h,25,true);
addChild(new Bitmap(camera.bitmapData));
camera.addEventListener(Event.RENDER,onRenderCamera);

cannyEdgeDetector = new CannyEdgeDetector(camera.bitmapData);
cannyEdgeDetector.lowThreshold = 0.03;
cannyEdgeDetector.highThreshold = 0.18;

cannyBmpd = new BitmapData(w,h,false,0);
cannyBmp = new Bitmap(cannyBmpd);

var refBmp:Bitmap = new Bitmap(cannyBmpd);
refBmp.x = w;
addChild(refBmp);

collisionList = new CollisionList(cannyBmp);
collisionList.excludeColor(0xff000000,255,0,0,0);

bubbles = new Array();
for(var i:int=0;i<20;i++){ var bubble:Bubble = new Bubble(14,0xFFB6DD); bubble.x = Math.random()*w; bubble.vx = bubble.vy = 0; bubbles.push(bubble); addChild(bubble); collisionList.addItem(bubble); } initControls(); addEventListener(Event.ENTER_FRAME,onEnterframe); } private function initStage():void{ stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; } private function onRenderCamera(e:Event):void{ if(_bold){ cannyEdgeDetector.detectEdgesBold(cannyBmpd); } else{ cannyEdgeDetector.detectEdges(cannyBmpd,true); } } private function onEnterframe(e:Event):void{ var collisions:Array = collisionList.checkCollisions(); var numbers:Number = collisions.length; for(i = 0; i < numbers; i++){ var collision:Object = collisions[i]; var angle:Number = collision.angle; var overlap:int = collision.overlapping.length; var bubble:Bubble = collision.object1; bubble.rotation = angle*180/Math.PI; var sin:Number = Math.sin(angle); var cos:Number = Math.cos(angle); var vx0:Number = bubble.vx * cos + bubble.vy * sin; var vy0:Number = bubble.vy * cos - bubble.vx * sin; vx0 = ((bubble.mass - 50) * vx0) / (bubble.mass + 50); //vx0 = 0.4; bubble.vx = vx0 * cos - vy0 * sin; bubble.vy = vy0 * cos + vx0 * sin; bubble.vx -= cos * overlap / bubble.radius; bubble.vy -= sin * overlap / bubble.radius; } for(var i:uint = 0; i < 20; i++){ bubble = bubbles[i]; bubble.vy += gravity; bubble.vy *= friction; bubble.vx *= friction; bubble.y += bubble.vy; bubble.x += bubble.vx; if(bubble.y > h){
bubble.y = 0;
bubble.vy = bubble.vx = 0;
bubble.x = Math.random() * w;
}
else if(bubble.x > w){
bubble.x = w – bubble.width/2;
bubble.vx *= -1;
}
else if(bubble.x < 0){ bubble.x = bubble.width/2; bubble.vx *= -1; } } } private function initControls():void{ Style.PANEL = 0x333333; Style.BUTTON_FACE = 0x333333; Style.LABEL_TEXT = 0xF6F6F6; panel = new Panel(this); panel.width = w*2; panel.height = 40; panel.y = 300; var slide:HUISlider = new HUISlider(panel, 90, 5, 'LOW THRESHOLD', onLowThresChange); slide.setSliderParams(.01, .9, .03); slide.labelPrecision = 3; slide.width = 250; slide = new HUISlider(panel, 90, 18, 'HIGH THRESHOLD', onHighThresChange); slide.setSliderParams(.01, 1.0, .18); slide.labelPrecision = 3; slide.width = 250; var checkbox:CheckBox = new CheckBox(panel, 350, 22, 'GET BOLD EDGES', onBoldChange); checkbox.selected = false; checkbox = new CheckBox(panel, 350, 9, 'NORMALIZE CONTRAST', onNormContrastChange); checkbox.selected = false; checkbox = new CheckBox(panel, 500, 9, 'BINARY IMAGE', onBinaryChange); checkbox.selected = true; } private function onLowThresChange(e:Event):void{ cannyEdgeDetector.lowThreshold = HUISlider(e.currentTarget).value; } private function onHighThresChange(e:Event):void{ cannyEdgeDetector.highThreshold = HUISlider(e.currentTarget).value; } private function onBoldChange(e:Event):void{ _bold = CheckBox(e.currentTarget).selected; } private function onBinaryChange(e:Event):void{ _binary = CheckBox(e.currentTarget).selected; } private function onNormContrastChange(e:Event):void{ cannyEdgeDetector.doNormalizeContrast = CheckBox(e.currentTarget).selected; } } } [/code]



转载请注明:陈童的博客 » 边缘检测的Canny算子与碰撞

喜欢 (1)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量