2016年12月3日 星期六

人臉貼圖動態呈現實作

這是來自班上




之前兩組所遇到的問題



如何做一個貼圖人臉功能



首先是先達到即時偵測人臉



之後針對左上角座標設定貼圖位置

用其 X  及 Y

Rectangle 結構

https://msdn.microsoft.com/zh-tw/library/system.drawing.rectangle(v=vs.110).aspx









using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using Emgu.CV.CvEnum;

namespace 人臉上面貼圖效果
{
    public partial class Form1 : Form
    {        
        CascadeClassifier face = new CascadeClassifier("haarcascade_frontalface_default.xml");
        Image<Bgr, byte> frame; // 靜態圖用的原彩色影像結構體
        Image<Gray, byte> grayImg; // 靜態圖用的灰階影像結構體(for 暫存)
        List<Rectangle> faces = new List<Rectangle>();//存放影像中出現多個人臉的List


        Capture cap;//攝影機
        Image<Bgr, byte> img;//載入的影格(不斷更新、不只一張)
        Image<Gray, byte> grayframe;
        Image<Bgr, byte> texture;
        Image<Gray, byte> grayTexture;
        bool openWebcam = false;
        bool detectFace = false;
        bool pasteTexture = false;


        public Form1()
        {
            InitializeComponent();
        }

        private void btnLoadImg_Click(object sender, EventArgs e)
        {
            string strFileName = string.Empty;

            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                frame = new Image<Bgr, byte>(ofd.FileName);
                imageBox2.Image = frame;
            }
        }

        private void btnFaceDetect_OnImage_Click(object sender, EventArgs e)
        {
            grayImg = frame.Convert<Gray, byte>();
            //Face Detect 
            Rectangle[] faceDetected = face.DetectMultiScale(grayImg,
                                                                1.1,
                                                                10,
                                                                new Size(30, 30),
                                                                Size.Empty);
            faces.AddRange(faceDetected);

            foreach(Rectangle f in faces)
            {
                frame.Draw(f , new Bgr(Color.Blue) , 2);
            }
            imageBox2.Image = frame;
        }

        private void btnPasteImg_onImage_Click(object sender, EventArgs e)
        {
            string strFileName = string.Empty;
            OpenFileDialog ofd = new OpenFileDialog();
            Image<Bgr, byte> texture;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                texture = new Image<Bgr, byte>(ofd.FileName);//取得貼圖
                foreach (Rectangle f in faces)
                {
                    //img.Draw(f, new Bgr(Color.Red), 2);

                    frame.ROI = new Rectangle(f.X, f.Y, texture.Width, texture.Height);
                    texture.CopyTo(frame);
                    frame.ROI = new Rectangle();
                    imageBox2.Image = frame;
                }
            }
        }


        private void btnOpenWebcam_Click(object sender, EventArgs e)
        {
            cap = new Capture(0);           
            Application.Idle += updateFrame;
            openWebcam = true;
            
            //imageBox1.Image = img;
        }

        private void updateFrame(object sender, EventArgs e)
        {
            if(openWebcam)
            {
                img = cap.QueryFrame();
                imageBox1.Image = img; //顯示
            }
            
            //imageBox1.Image = img; //顯示

            if(detectFace)
            {
                List<Rectangle> faces = new List<Rectangle>();                

                img = cap.QueryFrame();

                grayframe = img.Convert<Gray, byte>();

                Rectangle[] faceDetected = face.DetectMultiScale(grayframe,
                                                                     1.1,
                                                                     10,
                                                                     new Size(30, 30),
                                                                     Size.Empty);

                faces.AddRange(faceDetected);

                foreach (Rectangle f in faces)
                {
                    img.Draw(f, new Bgr(Color.Red), 2);
                }
                imageBox1.Image = img;
            }


            if(pasteTexture)
            {
                List<Rectangle> faces = new List<Rectangle>();

                img = cap.QueryFrame();

                grayframe = img.Convert<Gray, byte>();

                Rectangle[] faceDetected = face.DetectMultiScale(grayframe,
                                                                     1.1,
                                                                     10,
                                                                     new Size(30, 30),
                                                                     Size.Empty);
                faces.AddRange(faceDetected);

                foreach (Rectangle f in faces)
                {
                    //img.Draw(f, new Bgr(Color.Red), 2);
                    img.ROI = new Rectangle(f.X  , f.Y - 60, texture.Width, texture.Height);// 帽子要帶高一些
                    //method.1
                    //texture.CopyTo(img);


                    //method.2
                    grayTexture = texture.Convert<Gray,byte>();
                    //CvInvoke.cvNamedWindow("灰圖");
                    //CvInvoke.cvShowImage("灰圖", grayTexture);

                    CvInvoke.cvThreshold(grayTexture, grayTexture, 125, 255, THRESH.CV_THRESH_BINARY);
                    //CvInvoke.cvShowImage("二值圖", grayTexture);



                    CvInvoke.cvCopy(texture, img, grayTexture);

                    img.ROI = new Rectangle();
                }
                imageBox1.Image = img;
            }
        }

        private void btnFaceDetect_OnWebcam_Click(object sender, EventArgs e)
        {
            detectFace = true;
            pasteTexture = false;
        }

        private void btnPasteImg_onWebcam_Click(object sender, EventArgs e)
        {
            string strFileName = string.Empty;
            OpenFileDialog ofd = new OpenFileDialog();            
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                texture = new Image<Bgr, byte>(ofd.FileName);//取得貼圖
            }

            detectFace = false;
            pasteTexture = true;
        }
    }
}









沒有留言:

張貼留言