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 format
            var img = Dlib.LoadImage<RgbPixel>(imgPath);

            // find bradley's faces in image
            var faces = fd.Operator(img);
            if (faces.Count()==0)
            {
                return null;
            }
            var bradley = faces[0];

            // get bradley's landmark points
            var 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 points
            var hull = Cv2.ConvexHullIndices(bradleyPoints);
            var bradleyHull = from i in hull
                              select bradleyPoints[i];

            // find landmark points in face to swap
            var 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 points
            var hull2 = Cv2.ConvexHullIndices(bradleyPoints);
            var markHull = from i in hull2
                           select markPoints[i];


            // calculate Delaunay triangles
            var triangles = Utility.GetDelaunayTriangles(bradleyHull);

            // get transformations to warp the new face onto Bradley's face
            var warps = Utility.GetWarps(markHull, bradleyHull, triangles);

            // apply the warps to the new face to prep it for insertion into the main image
            var warpedImg = Utility.ApplyWarps(newImage, image.Width, image.Height, warps);


            // prepare a mask for the warped image
            var 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 face
            var 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 image
            var 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 image
            return 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;
        }

    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

和为 K 的子数组——前缀和+哈希

题目链接&#xff1a;力扣 注意&#xff1a;此题不能使用滑动窗口&#xff0c;因为数组中可能会出现负数。也就是说右指针向后移1位不能保证区间会增大&#xff0c;左指针向后移1位也不能保证区间和会减小。给定左右指针的位置没有二段性 已知sum[i]是从nums[0~i]的和&#x…

实现小程序商城首页【源码公开】

效果图 页面源码 <view class"index-container"><view class"header"><!--搜索框【仅样式&#xff0c;不做处理】 start--><van-search bindtap"clickSearch" disabled shape"round" background"#9c7bf0&q…

Pycharm安装dlib

目录 一、下载dilb 二、使用pip安装dlib库(亲测有效) 三、使用Pycharm安装(未使用) 一、下载dilb 官方网址:德利卜 皮皮 (pypi.org) 二、使用pip安装dlib库(亲测有效) 将下载好的whl文件放入工程文件中 接下来使用Python自带的pip进行安装 1.winR2.输入cmd&#xff0c;回车…

MySQL第六章、JDBC编程

目录 一、数据库编程的必备条件 二、Java的数据库编程&#xff1a;JDBC 三、JDBC工作原理 四、JDBC使用 4.1JDBC开发案例 一、数据库编程的必备条件 编程语言&#xff0c;如Java&#xff0c;C、C、Python等数据库&#xff0c;如Oracle&#xff0c;MySQL&#xff0c;SQL S…

十大网络安全上市公司分析,让我们重点聊聊F5

网络安全上市厂商业务广泛分布于网络安全硬件、软件&#xff0c;网络安全服务等板块&#xff0c;总体来看&#xff0c;十大网络安全上市公司的竞争可谓是如火如荼。今天让我们把目光集中在F5&#xff0c;这个能为我们所有人创造更安全的数字世界的企业&#xff0c;在应用及API交…

Linux下使用命令行和配置文件两种方式实现主从复制

一、什么是主从复制&#xff1f; Redis的主从复制&#xff08;Master-Slave Replication&#xff09;是一种数据复制机制&#xff0c;其中一个Redis实例充当主节点&#xff08;Master&#xff09;&#xff0c;而其他一个或多个Redis实例则充当从节点&#xff08;Slave&#xff…

基于GIS的生态敏感性评价与产业路径选择研究:以江西省吉安市为例

导读: 确立绿水青山就是金山银山的理念,建立生态经济体系,是新时代生态环境保护与经济发展的协调之道。对产业规划而言,与生态同行,构建绿色产业体系,是推动地区高质量发展的根本要求。鉴于此,文章从实证角度出发,以江西省吉安市为研究对象,采用生态敏感性评价方法,选…

【EXCEL】通过url获取网页表格数据

目录 0.环境 1.背景 2.具体操作 0.环境 windows excel2021 1.背景 之前我用python的flask框架的爬虫爬取过豆瓣网的电影信息&#xff0c;没想到excel可以直接通过url去获取网页表格内的信息&#xff0c;比如下图这是电影信息界面 即将上映电影 (douban.com) 通过excel操作&…

(栈队列堆) 剑指 Offer 31. 栈的压入、弹出序列 ——【Leetcode每日一题】

❓ 剑指 Offer 31. 栈的压入、弹出序列 难度&#xff1a;中等 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如&#xff0c;序列 {1,2,3,4,5} 是某栈的压栈序列&#xff0c;序…

【字符串编码解码问题】

字符串中编码解码问题 1.编码 byte[] getBytes()&#xff1a;使用平台的默认字符集将该String编码为一系列字节&#xff0c;将结果存储到新的字节数组中byte[] getBytes(String charsetName)&#xff1a;使用指定的字符集将该String编码为一系列字节&#xff0c;将结果存储到…

AHB协议理解

从小父亲就教育我&#xff0c;做一个对社会有用的人&#xff01; 目录 Chapter1 AHB Block Diagram Ginput signal lnput signals Output Signal Chapter3 Transfers AHB接口Overview Chapter6 Data Buses HWDATA HRDATA Chapter1 Introduction AHB: Advanced High-performanc…

ubuntu创建多用户并使用ssh链接

添加多个同时登录的用户 以下内容中的“username”根据自己需求自己定义 1.创建新用户 sudo useradd username2.给新用户添加管理权限 sudo vim /etc/sudoers打开的文件中添加如下内容 username ALL(ALL:ALL) ALL3.设置密码 输入&#xff1a; sudo passwd username打开的…

创建型模式 - 原型模式

概述 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。 结构 原型模式包含如下角色&#xff1a; 抽象原型类&#xff1a;规定了具体原型对象必须实现的的 clone() 方法。 具体原型类&#xff1a;实现抽象原型类的 clone() 方…

2023年牛客暑假多校-1 - J.Roulette题解

传送门&#xff08;lduoj&#xff09; 题目描述 Walk Alone is playing roulette, a kind of gambling. For simplification, we assume its rules and steps as follows: The whole gambling process composes of many turns.In the i-th turn:Walk Alone can choose an i…

Apache Doris (二十八):Doris 数据导入(六)Spark Load 1- 原理及配置

目录 1. 基本原理 2. Spark集群搭建 2.1 Spark Standalone 集群搭建 2.2 Spark On Yarn 配置 3. Doris配置Spark与Yarn 3.1 Doris配置Spark 3.2 Doris配置Yarn 进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质…

如何为HashMap设置初始化大小

如何为HashMap设置初始化大小 1.阿里巴巴代码规范的要求2.使用阿里巴巴插件扫描时3. 源码3.1 当初始化不设置大小时3.2 当初始化设置大小时 4. 测试附录 1.阿里巴巴代码规范的要求 2.使用阿里巴巴插件扫描时 3. 源码 3.1 当初始化不设置大小时 Map<Integer, BigDecimal>…

高时空分辨率、高精度一体化预测技术之风、光、水能源自动化预测技术

能源是国民经济发展和人民生活必须的重要物质基础。在过去的200多年里&#xff0c;建立在煤炭、石油、天然气等化石燃料基础上的能源体系极大的推动了人类社会的发展。但是人类在使用化石燃料的同时&#xff0c;也带来了严重的环境污染和生态系统破坏。近年来&#xff0c;世界各…

Spingboot 多模块引入第三方jar包

1. 在需要的模块中引入jar包 2. 在此模块中的pom.xml 中引用 3. 要想打包部署服务器&#xff0c;需要在启动模块中添加配置信息 ps&#xff1a;启动模块要引用此模块才能将此一起jar打包部署 <build><plugins><plugin><groupId>org.springframework.…

MySQL备份与还原/索引/视图

MySQL备份与还原/索引/视图练习 文章目录 一、备份与还原1、使用mysqldump命令备份数据库中的所有表2、备份booksDB数据库中的books表3、使用mysqldump备份booksDB和test数据库4、使用mysqldump备份服务器中的所有数据库5、使用mysql命令还原第二题导出的book表6、进入数据库使…

牛顿修正法在二阶近似方法中的应用

使用optimtool的牛顿修正法来应用学习 pip install optimtool --upgrade pip install optimtool>2.4.2optimtool包所依据的理论支撑中&#xff0c;还没有为二阶微分方法作邻近算子的近似与修正&#xff0c;所以二阶近似方法是研究无不可微项的可微函数的算子。 牛顿修正法…