C#/.net/DotNet/Emgu.CV裁剪照片头像
头像裁剪有利于人脸识别批量照片预处理,安防领域可以快速通过视频定位人脸,进行抓拍,做人脸识别相关功能的可能会应用到人脸裁剪,以下是我在实践中应用的代码,如有需要复制粘贴即可使用。
using Emgu.CV;
using Emgu.CV.Structure;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
namespace CutFace
{
class Program
{
static void Main(string[] args)
{
FaceClassifier = InitFaceClassifier();
CutFace($@"{RootPath}\images", $@"{RootPath}\faceimages");
}
/// <summary>
/// 根路径
/// </summary>
public static string RootPath = AppDomain.CurrentDomain.BaseDirectory;
/// <summary>
/// 人脸级联分类器
/// </summary>
public static CascadeClassifier FaceClassifier { get; set; }
/// <summary>
/// 初始化人脸级联分类器
/// </summary>
public static CascadeClassifier InitFaceClassifier()
{
//判断opencv相关文件是否存在,不存在根据系统类型创建相关文件
if (!File.Exists($@"{RootPath}\cvextern.dll"))
{
var dir = $@"{RootPath}\opencv";
string zip = Directory.GetFiles(dir).Where(m => Environment.Is64BitProcess ? m.Contains("x64.zip") : m.Contains("x86.zip")).FirstOrDefault();
if (!string.IsNullOrEmpty(zip))
{
//将压缩包解压到根目录
new FastZip().ExtractZip(zip, RootPath, null);
}
}
//如果支持用显卡,则用显卡运算
CvInvoke.UseOpenCL = CvInvoke.HaveOpenCLCompatibleGpuDevice;
//构建级联分类器,利用已经训练好的数据,识别人脸
return new CascadeClassifier($@"{RootPath}\opencv\haarcascade_frontalface_alt.xml");
}
/// <summary>
/// 裁剪人脸
/// </summary>
/// <param name="srcPath">源路径</param>
/// <param name="outPath">输出路径</param>
public static void CutFace(string srcPath, string outPath)
{
if (!Directory.Exists(outPath))
{
Directory.CreateDirectory(outPath);
}
var files = Directory.GetFiles(srcPath);
int fcount = 0;
foreach (var f in files)
{
//加载要识别的图片
using (var img = new Image<Bgr, byte>(f))
{
using (var img2 = img.Clone())
{
//把图片从彩色转灰度
CvInvoke.CvtColor(img, img2, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
//亮度增强
CvInvoke.EqualizeHist(img2, img2);
//在这一步就已经识别出来了,返回的是人脸所在的位置和大小
var facesDetected = FaceClassifier.DetectMultiScale(img2, 1.1, 10, new Size(100, 100));
//循环把人脸部分切出来并保存
foreach (var item in facesDetected)
{
fcount++;
//彩照用img,黑白照用img2
using (MemoryStream ms = new MemoryStream(img.ToJpegData(80)))
{
using (Image b = Image.FromStream(ms))
{
using (var bmpOut = new Bitmap(200, 200, PixelFormat.Format32bppRgb))
{
using (var g = Graphics.FromImage(bmpOut))
{
g.DrawImage(b, new Rectangle(0, 0, 200, 200), new Rectangle(item.X - 30, item.Y - 30, item.Width + 60, item.Height + 60), GraphicsUnit.Pixel);
}
bmpOut.Save(f.Replace(srcPath, outPath), ImageFormat.Jpeg);
}
//只保留最先识别出来的人脸
break;
}
}
}
}
}
}
if (fcount > 0)
{
Console.WriteLine("头像处理成功!");
}
else
{
Console.WriteLine("没有头像照片可供处理!");
}
Console.ReadLine();
}
}
}

浙公网安备 33010602011771号