Développement de la classe detectionCouleur.as

Bonjour,

Pour le moment, je me heurte à quelques problèmes. La webcam que j'utilise pour le développement est une webcam de 3.0 megapixels. La plupart des ordinateurs portables ont une webcam d'environ 1.3 megapixels. Je constate que lorsque j'utilise ma isight 1.3 megapixels les zones sombres se retrouve dans mon écart de couleur. Ma détection est donc faussée. De plus, mon écart de couleur englobe une bonne partie des couleurs vertes proches du motif, mais aussi les couleurs bleu. Je vais aussi faire un test avec un caméscope mis comme webcam pour voir comment réagit mon code avec une caméra supérieur à 3 mégapixels.

La technique employée pour l'écart de couleur actuellement ne se base que sur la méthode Threshold de la classe BITMAPDATA. le résultat n'est pas assez précis.

J'ai 2 pistes à exploiter :

La première continuer sur le principe de threshold mais arriver à l'aide d'un slider supplémentaire à pouvoir corriger "la balance des blancs de la caméra. ca permettra peut-être de pouvoir se recaler sur l'écart de couleur à détecter.

Pour effectuer une détection plus précise, il faut que j'analyse ou plutot que j'exploite la méthode GetPixels qui fera l'objet de mes futures tests. Parmi mes recherches, je suis tombé sur la nouvelle classe Vector qui s'avère vraiment plus rapide pour manipuler les données issues de chaque pixel.
http://www.mikechambers.com/blog/2009/10/13/case-study-actionscript-3-performance-optimization/.

Mais pour pouvoir l'utiliser, j'ai besoin de flash CS4.0 et surtout du lecteur flash 10 et non 9. les gains de performance indiqués dans l'article de Mike Chambers sont vraiment intéressants.

Voici pour le moment la version flash9 avec la méthode threshold :

detectionCouleur.as

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.ActivityEvent;
	import flash.geom.Transform;
	import flash.geom.ColorTransform; 
	import fl.controls.Slider;
	import fl.events.SliderEvent;
        import fl.controls.SliderDirection;	
	import fl.controls.Label;
	/**
	 * ...
	 * @author Denis www.dipi-graphics.com
	 */
	public class detectionCouleur extends Sprite
	{
		//VARIABLE INIT
		var webcam:Camera;
		var vid:Video;
		var image:BitmapData;
		var imageB:Bitmap;
		var flip:Matrix = new Matrix();
 
		//isolant
		var threshold:uint =  0x00106010;
		var maskColor:uint = 0x00FFFFFF;
		var color:uint = 0xFF00FF00;
 
		//Pointeur
		var threshold1:uint =  0x0000ff00;
		var color1:uint = 0xFFFF0000;
		var maskColor1:uint = 0x0000FF00;
 
		//Constante
		var rect:Rectangle = new Rectangle(0,0,320,240);
		var pt:Point = new Point(0, 0);
		var rectPoint:Rectangle;
 
		//filtre
		//blur
		var flou:int = 5;
		var filter:BlurFilter = new BlurFilter(flou,flou,2);
 
		//saturation
		var s = 1;
		var rwgt:Number = .3086;
		var gwgt:Number = .6094;
		var bwgt:Number = .0820;
		var a:Number;
		var b:Number;
		var c:Number;
		var d:Number;
		var e:Number;
		var f:Number;
		var g:Number;
		var h:Number;
		var i:Number;
		var satMat:Array = new Array(a,b,c,0,0,d,e,f,0,0,g,h,i,0,0, 0, 0, 0, 1, 0);
		var saturate:ColorMatrixFilter = new ColorMatrixFilter(satMat);
 
		//OUTILS
		var rectangle:Shape = new Shape(); //zone rectangle de detection
		var blurSlider:Slider = new Slider();
		var blurLabel:Label = new Label()
		var blurText:TextField = new TextField();
		var saturationSlider:Slider = new Slider();
		var saturationLabel:Label = new Label();
		var saturationText:TextField = new TextField();
 
		//INITIALISATION
		public function detectionCouleur()
		{
			//Init Outils
			//const Slider Blur et Slider Saturation
			var format:TextFormat = new TextFormat();
                        format.font = "Arial";
                        format.color = 0x000000;
                        format.size = 10;
                        format.bold = true;
 
			//BLUR FILTER						          //SATURATION FILTER
                        blurText.defaultTextFormat = format;	        saturationText.defaultTextFormat = format;		
			blurText.text = "Blur Level";			        saturationText.text = "Saturation Level";
			blurText.selectable=false;				        saturationText.selectable=false;
			blurText.x = 360;						 saturationText.x = 360;
			blurText.y = 325;						        saturationText.y = 360;
			blurSlider.x = 360;						saturationSlider.x = 360;
			blurSlider.y = 345;						saturationSlider.y = 380;
			blurSlider.width = 200;					saturationSlider.width = 200;
			blurSlider.height = 20;					saturationSlider.height = 20;
			blurSlider.maximum = 100;				saturationSlider.maximum = 200;
			blurSlider.minimum = 0;					saturationSlider.minimum = 0;
			blurSlider.value = 50;					        saturationSlider.value = 50;
			blurLabel.text = "50%";					saturationLabel.text = "50%";
			blurLabel.x = 570;						saturationLabel.x = 570;
			blurLabel.y = 340;						saturationLabel.y = 375;
 
			addChild(blurText);
			addChild(blurSlider);
			addChild(blurLabel);
			addChild(saturationText);
			addChild(saturationSlider);
			addChild(saturationLabel);
 
			blurSlider.addEventListener(SliderEvent.CHANGE, blurHandler);
			saturationSlider.addEventListener(SliderEvent.CHANGE, saturationHandler);
 
			//matrice flip
			flip.translate( -320, 0 );
			flip.scale( -1, 1 );
 
			//matrice saturation
			a = rwgt + (1 - rwgt) * s;
			b = gwgt * (1 - s);
			c = bwgt * (1 - s);
			d = rwgt * (1 - s);
			e = gwgt + (1 - gwgt) * s;
			f = bwgt * (1 - s);
			g = rwgt * (1 - s);
			h = gwgt * (1 - s);
			i = bwgt + (1 - bwgt) * s;
			satMat = new Array(a, b, c, 0, 0, d, e, f, 0, 0, g, h, i, 0, 0, 0, 0, 0, 1, 0);
			saturate = new ColorMatrixFilter(satMat);
 
			//controle accès sécurisé à l'élément stage
			addEventListener(Event.ADDED_TO_STAGE,activation);
		}
		//ACTIVATION
		private function activation ( pEvt:Event ):void
		{
 
			var stageW = stage.stageWidth;
			var stageH = stage.stageHeight;
			webcam = Camera.getCamera();
			webcam.setMode( 320, 240, stage.frameRate );
			webcam.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
			vid = new Video(320, 240);
			vid.attachCamera(webcam);
			vid.x=0;
			vid.y=80;
			addChild(vid);
			removeEventListener(Event.ADDED_TO_STAGE, activation);
		}
		private function activityHandler(evt:ActivityEvent):void 
		{
			image = new BitmapData(320, 240, false);
			imageB = new Bitmap(image);
			if (!webcam.muted) 
			{
 
				//affichage image capturée
				addChild(imageB);
				imageB.x = 320;
				imageB.y = 80;
				addChild(rectangle);
				//lancement du timer de capture
				var t:Timer = new Timer(50);
				t.addEventListener(TimerEvent.TIMER, timerHandler);
				t.start();
 
 
 
 
			}
			webcam.removeEventListener(ActivityEvent.ACTIVITY, activityHandler);
 
		}
		//TIMER 
		private function timerHandler(evt:TimerEvent)
		{
 
			image.draw(vid, flip);//dessine l'image capturée avec effet miroir
			image.applyFilter(image, rect, pt, filter);//filtre blur
			image.applyFilter(image,rect,pt,saturate);//filtre saturation
 
                        // ISOLANT
                        //tout ce qui n'est pas dans mon ecart de couleur devient Vert 
			image.threshold(image, rect, pt, ">", threshold , color, maskColor, true);   
 
                        // POINTEUR
                        //tout ce qui n'est pas vert devient rouge 
	                image.threshold(image, rect, pt, "!=", threshold1 , color1, maskColor1, true); 
 
			rectPoint = image.getColorBoundsRect(0x00FFFFFF, 0xFFFF0000, true);
			rectangle.graphics.clear();
			rectangle.graphics.lineStyle(2, 0x0000FF);
			rectangle.graphics.drawRect((rectPoint.x+320),(rectPoint.y+80),rectPoint.width,rectPoint.height);
 
		}
		//Slider EVENT
		private function blurHandler(event:SliderEvent):void 
		{
			blurLabel.text = event.value + "%";
			flou = event.value / 5;
			filter = new BlurFilter(flou, flou, 2);
		}
		private function saturationHandler(event:SliderEvent):void 
		{
			saturationLabel.text = event.value + "%";
			s = event.value / 50;
			a = rwgt + (1 - rwgt) * s;
			b = gwgt * (1 - s);
			c = bwgt * (1 - s);
			d = rwgt * (1 - s);
			e = gwgt + (1 - gwgt) * s;
			f = bwgt * (1 - s);
			g = rwgt * (1 - s);
			h = gwgt * (1 - s);
			i = bwgt + (1 - bwgt) * s;
			var satMat:Array = new Array(a, b, c, 0, 0, d, e, f, 0, 0, g, h, i, 0, 0, 0, 0, 0, 1, 0);
			saturate = new ColorMatrixFilter(satMat);
		}
	}
 
}

Démo :
imprimez le motif ou munissez vous d'un objet vert pour pouvoir faire fonctionner la démo.
(voir explication setup et fonctionnement)


Denis P.

comments (0)
| More

Détection couleur : interface pour setup

Bonjour,

J'ai construit une petite interface pour pouvoir configurer de manière simple la détection de couleur. Dans la vidéo ci dessous, j'explique et expérimente la détection dans 2 environnements différents au niveau de l'éclairage.

Envie d'essayer ?

Vous êtes invité à participer au test afin que je sache si cela fonctionne sur d'autres webcams.
Conditions d'utilisation optimale: background clair dans une piece éclairée par la lumière du jour. Eviter les objets sombres.

Denis P.

comments (0)
| More

stage trouvé

J'ai trouvé mon stage, je le ferai chez Emakina à partir du 4 janvier.

Denis P.

comments (0)
| More