之前兩組所遇到的問題
如何做一個貼圖人臉功能
首先是先達到即時偵測人臉
之後針對左上角座標設定貼圖位置
用其 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;
}
}
}
沒有留言:
張貼留言