fc2ブログ

[ActionScript 3.0] HSVによる肌色検出

2007-08-31 | 21:56

人間の肌の色は色相Hの値が0~30の範囲に収まるらしい。
http://www.ai.kyutech.ac.jp/~toshi/kiso_2/ensyu/color/skin.html

下のスライダーを動かして上限(upper threshold)/下限(lower threshold)を指定するとその範囲の色相の部分が赤く変わります。
(肌の色は色相が0~30の範囲に収まるという話であって、色相が0~30の範囲であればそれは人間の肌だけであるというわけではないことに注意)

SkinUi.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()" 
backgroundColor="#FFFFFF" width="400" height="400">

	<mx:Script>
		<![CDATA[
		    import mx.core.UIComponent;
		    import mx.controls.*;
		    import mx.controls.sliderClasses.*;
                    private var skin:Skin = new Skin();
		    private function init():void{
			
			skin = new Skin();
			var ui:UIComponent = new UIComponent();
			ui.addChild(skin);
			ui.x = 10;
			ui.y = 100;

			this.addChild(ui);
                        onChange();
                    }

                    private function onChange():void{
                        gth.text = gslider.value.toString();
                        lth.text = lslider.value.toString();
                        skin.detect(gslider.value, lslider.value);
                    }

		]]>
	</mx:Script>
	<mx:Label  text="lower threshold" x="0" y="0"/>
        <mx:HSlider id="gslider" x="150" y="0" maximum="50" minimum="1" change="onChange()"  /> 
	<mx:Label  id="gth" x="350" y="0"/>
	<mx:Label  text="upper threshold" x="0" y="50"/>
        <mx:HSlider id="lslider" x="150" y="50" maximum="50" minimum="1" change="onChange()"  /> 
	<mx:Label  id="lth" x="350" y="50"/<
</mx:Application>
Skin.as
package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    [SWF(width="400",height="400",backgroundColor="#ffffff")]
    public class Skin extends Sprite {
        [Embed(source="wmn0021-024_m.jpg")]
            private var myImage:Class;

        private var bitmap:Bitmap;
        public function Skin() {
            bitmap = new myImage();
            addChild(bitmap);
        }

        public function detect(gtr:Number, less:Number):void{
            removeChild(bitmap);
            bitmap = new myImage();
            addChild(bitmap);
            for(var y:int = 0 ; y < bitmap.height; y++){
                for(var x:int = 0 ; x < bitmap.width; x++){
                    var pixel:Number = bitmap.bitmapData.getPixel(x,y);
                    var hsv:Object = rgb2hsv((pixel&0xff0000) >> 16,
                            (pixel & 0xff00) >> 8, (pixel & 0xff));
                    if(hsv.h > gtr && hsv.h < less)
                        bitmap.bitmapData.setPixel(x,y, 0xff0000);
                }
            }
        }

        private function rgb2hsv(r:int, g:int, b:int):Object{
            var hsv:Object = new Object();

            hsv.h = hsv.s = hsv.v = 0.0;
            var cmax:Number = Math.max(r,Math.max(g,b));
            var cmin:Number = Math.min(r,Math.min(g,b));
            hsv.v = cmax;
            var c:Number = cmax - cmin;
            if (cmax == 0.0) hsv.s = 0.0; else hsv.s = c/cmax;
            if (hsv.s != 0.0){
                if (r == cmax)
                {
                    hsv.h = (g - b)/c;
                }else if (g == cmax) {
                    hsv.h = 2 + (b - r)/c;
                }else{
                    if (b == cmax) hsv.h = 4 + ( r - g)/c;
                }
                hsv.h *= 60.0;
                if (hsv.h < 0.0) hsv.h += 360.0;
            }

            return hsv;
        }
    }
}

スポンサーサイト