Color Detection part 1: ตรวจหาสีผิวมนุษย์ (Skin Detection)

                บทความในหัวข้อ Color detection ผมจะขอแบ่งออกเป็นหลายๆ ตอนนะครับ เพราะว่า color detection สามารถนำไปประยุกต์ใช้งานได้หลากหลายมากครับ อาทิเช่น ตรวจจับลูกบอลสีส้ม ตรวจจับสีผิวมนุษย์ ตรวจจับวัตถุที่มีสีต่างๆ และโปรแกรม ai auto-click diamond dash ผมก็ใช้หลักความรู้ทางด้าน color detection มาประยุกต์ในการเขียนโปรแกรมครับ ผมเชื่อว่าถ้าเราเข้าใจหลักในการทำ color detection เราจะสามารถเขียนโปรแกรมทางด้าน image processing เพื่อใช้วิเคราะห์สิ่งต่างๆ ที่เราสนใจได้ดียิ่งขึ้นแน่นอนครับ เอาละครับ เรามาเข้าเรื่องของเราดีกว่าครับ
ตอนที่ 1 (part1) ผมจะนำเสนอการตรวจหาสีผิวมนุษย์ (Skin detection) 
            ขั้นแรก: ผมได้นำ lab5:เขียนโปรแกรมติดต่อกับกล้อง มาประยุกต์ต่อนะครับ ถ้าใครยังไม่มี lab5 ขอให้กลับไปทำ lab5 ก่อนนะครับ << คลิ๊กเพื่อกลับไปทำ lab 5 >>
ขั้นที่สอง : ที่ฟังค์ชั่น private void process() เราจะมาเพิ่ม code ในส่วนนี้นะครับ โดยขั้นตอนการทำงานของโปรแกรมจะเป็นดังนี้นะครับ 
1.รับ
input มาจากกล้องวีดีโอ  
2.แปลงภาพจาก
RGB -> HSV
3.แยก
channel สีของรูป HSV โดยเราจะพิจารณาที่ channel[0] ครับ  ซึ่ง channel [0] คือค่า HUE ใน hsv model color เป็นค่าที่ใช้กำหนดสี
4.ใช้
cvInrange() มาตรวจสอบว่าส่วนใดของรูปมีค่าสีอยู่ใน range บ้าง โดยทั่วไปมนุษย์ที่มีสีผิวเป็นสีน้ำตาลช่วงของค่าสีต่ำสุดกับสูงสุดจะอยู่ในช่วง  0 - 20
5.ปรับปรุงภาพให้ดีขึ้น
6.แสดงรูป
output
              ขั้นที่สาม : ทำความรู้จักกับ cvInrange();  ซึ่งเป็นเมธอดหนึ่งในไลบราลี่ของ emgucv ประโยชน์ของมันคือใช้ตรวจสอบว่า ในรูปภาพมี pixel ไหนบ้างที่มีค่าสีอยู่ในช่วงที่กำหนด  สามารถอธิบายได้จากซูโดโค๊ดดังนี้ครับ 
            If   low <= img(x,y)  <= high; resultImg(x,y) == 255
            else  resultImg(x,y) == 0
โดย low = ช่วงต่ำสุดที่เรากำหนด   ,  high = ช่วงสูงสุดที่เราหนด  
       img(x,y) = pixel value ในรูป input   , resultImg(x,y) = pixel value ในรูป output
             ขั้นสุดท้าย : ป่ะลุยโค๊ด !!
private void process()
        {
            Image<Bgr,byte> cameraImage;
            cameraImage = capture.QueryFrame(); //input image
            Image<Hsv,byte> hsvImage = cameraImage.Convert<Hsv ,byte>(); //Convert RGB > HSV.
            if (cameraImage != null)
            {
                Image<Gray ,Byte> ResultImage = new Image<Gray ,Byte>(hsvImage.Width, hsvImage.Height); //Create result image.
                Image<Gray ,Byte> IlowCh0 = new Image<Gray ,Byte>(hsvImage.Width, hsvImage.Height, new Gray(0)); //Define low range(0).
                Image<Gray ,Byte> IHiCh0 = new Image<Gray ,Byte>(hsvImage.Width, hsvImage.Height, new Gray(20)); //Define high range(20).

                CvInvoke.cvInRange(hsvImage[0], IlowCh0, IHiCh0, ResultImage); //Use cvinrange() method and hsvImage[0] = hsvimage channel 0

                CvInvoke.cvErode(ResultImage, ResultImage, (IntPtr)null, 3);  //Morphorogy erosion.
                CvInvoke.cvDilate(ResultImage, ResultImage, (IntPtr)null, 4); //Morphorogy dilation.

                pbShowCamera1.Image = cameraImage.ToBitmap();  //show input image in picturebox.
                CvInvoke.cvShowImage("show result", ResultImage); // show output image in a new windows.
            }
      เมื่อรันโปรแกรมแล้วจะได้ output ดังภาพนะครับ บทความนี้ก็ขอจบเพียงเท่านี้ครับ ขอให้สนุกกับ image processing นะครับ

7 ความคิดเห็น

May 9, 2013 at 4:04 PM

ถ้าอยากจำนับว่ามีสีผิวอยู่กี่ pixel ทำยังไงคับ

Reply
May 9, 2013 at 5:13 PM

ถ้าไม่คิดอะไรมาก ก็ นับจุดที่เป็นสีขาวครับ หรือ pixel ที่มีค่าเท่ากับ 255 ครับ
coutPixel = 0
for(i = 0 ; i < row; i++ ){
for(j = 0 ; j < col ; j++){
if(pix == 255){
coutPixel += 1
}
}
}

หรือถ้าอยากจะ Advance ขึ้นมาหน่อย ลองดูเรื่อง contourArea [http://www.emgu.com/wiki/files/2.4.2/document/html/9e8689ba-7c6f-906d-f1c1-668d78d2826b.htm ]
ดูครับ เรื่องผลลัพธ์ผมไม่แน่ใจเท่าไหร่ว่าจะออกมาเท่ากันไหมเพราะยังไม่เคยทดสอบครับ ^_^

Reply
May 9, 2013 at 5:32 PM

ขอบคุณมากๆคับ

Reply
May 9, 2013 at 5:39 PM

ResultImage. อะไรตือค่าของ pixel คับ

Reply
May 9, 2013 at 5:49 PM

ถ้ายังไม่รู้จักคำว่า "ค่าของ pixel" ผมแนะนำลองกลับไปหาทฤษฏีพื้นฐานของ Image processing อ่านดูก่อนครับ ถ้าเรายังไม่รู้เรื่องพวกนี้ เราจะไม่สามารถทำอะไรได้เลย เรื่องนี้จำเป็นจริงๆ นะครับ

Reply
May 9, 2013 at 8:02 PM

Color pixelTemp = image.getPixel(x,y); ทำไม getPixel มันใช้ไม่ได้

Reply
May 10, 2013 at 10:15 AM

ผมแนะนำให้กลับไปอ่านที่ Lab4 ดีกว่าครับ ^_^
http://www.labplays.com/2013/01/lab4.html

Reply

Post a Comment

Templated by Blogger Items