C# OpenCvSharp+DlibDotNet 人脸替换 换脸

效果

Demo下载

项目

VS2022+.net4.8+OpenCvSharp4+DlibDotNet

 相关介绍参考

代码

using DlibDotNet;
using OpenCvSharp.Extensions;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;namespace OpenCvSharp_人脸替换
{public partial class Form1 : Form{public Form1(){InitializeComponent();}Bitmap bmp;string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string imgPath = "";string startupPath = "";Bitmap bmp2;string imgPath2 = "";FrontalFaceDetector fd;ShapePredictor sp;private void button2_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;imgPath = ofd.FileName;bmp = new Bitmap(imgPath);pictureBox1.Image = new Bitmap(imgPath);}private void button3_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox2.Image = null;imgPath2 = ofd.FileName;bmp2 = new Bitmap(imgPath2);pictureBox2.Image = new Bitmap(imgPath2);}private void button1_Click(object sender, EventArgs e){if (pictureBox1.Image==null || pictureBox2.Image==null){return;}pictureBox3.Image = ProcessImage(bmp, bmp2);}/// <summary>/// Process the original selfie and produce the face-swapped image./// </summary>/// <param name="image">The original selfie image.</param>/// <param name="newImage">The new face to insert into the selfie.</param>/// <returns>A new image with faces swapped.</returns>public Bitmap ProcessImage(Bitmap image, Bitmap newImage){// convert image to dlib formatvar img = Dlib.LoadImage<RgbPixel>(imgPath);// find bradley's faces in imagevar faces = fd.Operator(img);if (faces.Count()==0){return null;}var bradley = faces[0];// get bradley's landmark pointsvar bradleyShape = sp.Detect(img, bradley);var bradleyPoints = (from i in Enumerable.Range(0, (int)bradleyShape.Parts)let p = bradleyShape.GetPart((uint)i)select new OpenCvSharp.Point(p.X, p.Y)).ToArray();// get convex hull of bradley's pointsvar hull = Cv2.ConvexHullIndices(bradleyPoints);var bradleyHull = from i in hullselect bradleyPoints[i];// find landmark points in face to swapvar imgMark = Dlib.LoadImage<RgbPixel>(imgPath2);var faces2 = fd.Operator(imgMark);if (faces2.Count() == 0){return null;}var mark = faces2[0];var markShape = sp.Detect(imgMark, mark);var markPoints = (from i in Enumerable.Range(0, (int)markShape.Parts)let p = markShape.GetPart((uint)i)select new OpenCvSharp.Point(p.X, p.Y)).ToArray();// get convex hull of mark's pointsvar hull2 = Cv2.ConvexHullIndices(bradleyPoints);var markHull = from i in hull2select markPoints[i];// calculate Delaunay trianglesvar triangles = Utility.GetDelaunayTriangles(bradleyHull);// get transformations to warp the new face onto Bradley's facevar warps = Utility.GetWarps(markHull, bradleyHull, triangles);// apply the warps to the new face to prep it for insertion into the main imagevar warpedImg = Utility.ApplyWarps(newImage, image.Width, image.Height, warps);// prepare a mask for the warped imagevar mask = new Mat(image.Height, image.Width, MatType.CV_8UC3);mask.SetTo(0);Cv2.FillConvexPoly(mask, bradleyHull, new Scalar(255, 255, 255), LineTypes.Link8);// find the center of the warped facevar r = Cv2.BoundingRect(bradleyHull);var center = new OpenCvSharp.Point(r.Left + r.Width / 2, r.Top + r.Height / 2);// blend the warped face into the main imagevar selfie = BitmapConverter.ToMat(image);var blend = new Mat(selfie.Size(), selfie.Type());Cv2.SeamlessClone(warpedImg, selfie, mask, center, blend, SeamlessCloneMethods.NormalClone);// return the modified main imagereturn BitmapConverter.ToBitmap(blend);}private void Form1_Load(object sender, EventArgs e){fd = Dlib.GetFrontalFaceDetector();sp = ShapePredictor.Deserialize("shape_predictor_68_face_landmarks.dat");Dlib.Encoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28049.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树--C语言实现数据结构

本期带大家一起用C语言实现二叉树&#x1f308;&#x1f308;&#x1f308; 1、二叉树的定义 二叉树是一种特殊的树状数据结构&#xff0c;它由节点组成&#xff0c;每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点 二叉树的链式存储结构是指用 链表 来表示…

【数据结构】二叉树详解(1)

⭐️ 前言 ✨ 二叉树的概念性质 ⭐️ 二叉树链式结构的实现 结构定义&#xff1a; #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int BinaryTreeDataType;typedef struct BinaryTreeNode {BinaryTreeDataType value;struct Binary…

【Python统计与数据分析实战_01】位置与分散程度的度量

数据描述性分析 1.描述统计量1.1 位置与分散程度的度量1.1.1 例子一 单维数组1.1.2 例子二 多维数组 1.2 关系度量1.3 分布形状的度量1.3.1 统计量&#xff1a;偏度和峰度 1.4 数据特性的总括 1.描述统计量 数据的统计分析分为统计描述和统计推断两部分。前者通过绘制统计图、…

港联证券-尾盘集合竞价拉升意味着什么意思?

在股票市场中&#xff0c;尾盘集合竞价是指每个交易日的最后几分钟&#xff0c;即下午14:57到3:00之间的交易。在这段时间内&#xff0c;所有股票的买卖都将以竞价的方式进行&#xff0c;最终价格以最高买价与最低卖价的平均值确定&#xff0c;成交量也将作为当日的收盘价和成交…

Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

相关文章&#xff1a; Django实现接口自动化平台&#xff08;十二&#xff09;自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解&#xff0c;查看本章内容时&#xff0c;要结合整体项目代码来看&#xff1a; pytho…

SQL语句GROUP BY、HAVING、EXISTS、SQL函数(Null判断、日期相关、计算数值和字符串操作 )

目录 GROUP BY HAVING EXISTS SQL函数 Null判断函数 日期数据类型及函数 计算数值和字符串操作函数 AVG(平均值) COUNT(数据条数) FIRST/LAST(第一条数据) MAX/MIN(最大值) SUM(列总和) UCASE/ LCASE (转换大小写) MID(截取字符串) LEN(字符值的长度) ROUND(数…

学习记录——SpectFormer、DilateFormer、ShadowFormer

SpectFormer: Frequency and Attention is what you need in a Vision Transformer, arXiv2023 频域混合注意力SpectFormer 2023 论文&#xff1a;https://arxiv.org/abs/2304.06446 代码&#xff1a;https://badripatro.github.io/SpectFormers/ 摘要视觉变压器已经成功地应用…

nginx基础2——配置文件详解(网页配置篇)

文章目录 一、基本了解二、nginx.conf配置参数2.1 调试参数2.2 必配参数2.3 优化性能参数2.4 event{}段配置参数2.5 网络连接参数2.6 fastcgi配置参数2.7 总结常配参数 三、http{}段配置参数3.1 配置结构3.2 精简配置网页3.3 location定义网页3.3.1 root path用法3.3.1 alias p…

哪些方法可以一键批量查询快递单号

想做好电商或者物流行业&#xff0c;可千万不能虎头蛇尾&#xff0c;前端的高效并不够&#xff0c;我们还要做好后端的及时跟踪维护。当大量快递集中发出之后&#xff0c;我们必须及时地跟踪物流信息&#xff0c;掌握快递的动态&#xff0c;小编今天要和大家安利一款实用的辅助…

Linux系统部署Tomcat详细教程(图文讲解)

前言&#xff1a;本篇博客教大家如何一步一步使用Linux系统去部署自己的Tomcat服务器&#xff0c;每一行代码都是我自己严格执行过的&#xff0c;共分为了8点进行阐述&#xff0c;逻辑清晰&#xff01; 目录 一、安装JDK环境 二、准备Tomcat安装包 三、安装Tomcat 四、配置…

Nuxt.js--》解密Nuxt.js:构建优雅、高效的现代化Vue.js应用

博主今天开设Nuxt.js专栏&#xff0c;带您深入探索 Nuxt.js 的精髓&#xff0c;学习如何利用其强大功能构建出色的前端应用程序。我们将探讨其核心特点、灵活的路由系统、优化技巧以及常见问题的解决方案。无论您是想了解 Nuxt.js 的基础知识&#xff0c;还是希望掌握进阶技巧&…

精智达在科创板上市:募资约11亿元,深创投等为其股东

7月18日&#xff0c;深圳精智达技术股份有限公司&#xff08;下称“精智达”&#xff0c;SH:688627&#xff09;在上海证券交易所科创板上市。本次上市&#xff0c;精智达的发行价为46.77元/股&#xff0c;发行数量为2350.2939万股&#xff0c;募资总额为10.99亿元&#xff0c;…