基于人脸68特征点识别的美颜算法(一) 大眼算法 C++

1、加载一张原图,并识别人脸的68个特征点

	cv::Mat img = cv::imread("5.jpg");// 人脸68特征点的识别函数vector<Point2f> points_vec = dectectFace68(img);// 大眼效果函数Mat dst0 = on_BigEye(800, img, points_vec);

请添加图片描述
2、函数

vector<Point2f> dectectFace68(Mat src)
{vector<Point2f> points_vec;int* pResults = NULL;//在检测函数中使用了pBuffer。  //如果你调用多个线程中的函数,请为每个线程创建一个缓冲区!  unsigned char* pBuffer = (unsigned char*)malloc(DETECT_BUFFER_SIZE);if (!pBuffer){fprintf(stderr, "Can not alloc buffer.\n");//return 100;}Mat gray;cvtColor(src, gray, CV_BGR2GRAY);int doLandmark = 1;// do landmark detection  pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step,1.2f, 2, 48, 0, doLandmark);int cxa = *pResults;ofstream file("facedata.txt", ios::out);//打印检测结果 if (0 == cxa){}else{for (int i = 0; i < (pResults ? *pResults : 0); i++){short* p = ((short*)(pResults + 1)) + 142 * i;//rectangle(src, Rect(p[0], p[1], p[2], p[3]), Scalar(0, 255, 0), 2);if (doLandmark){for (int j = 0; j < 68; j++){char c[8];_itoa(j, c, 10);Point2f ff(p[6 + 2 * j], p[6 + 2 * j + 1]);points_vec.push_back(ff);file << ff.x << "\t" << ff.y << endl;/*	circle(src, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 3, Scalar(0, 0, 255), 3);CvPoint font;putText(src, c, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 23, 0), 1);*/}}}}return points_vec;
}// 双线性插值算法
void BilinearInsert(Mat& src, Mat& dst, float ux, float uy, int i, int j)
{auto Abs = [&](float f) {return f > 0 ? f : -f;};int c = src.channels();if (c == 3){//存储图像得浮点坐标CvPoint2D32f uv;CvPoint3D32f f1;CvPoint3D32f f2;//取整数int iu = (int)ux;int iv = (int)uy;uv.x = iu + 1;uv.y = iv + 1;//step图象像素行的实际宽度  三个通道进行计算(0 , 1 2  三通道)f1.x = ((uchar*)(src.data + src.step * iv))[iu * 3] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * iv))[(iu + 1) * 3] * (uv.x - iu);f1.y = ((uchar*)(src.data + src.step * iv))[iu * 3 + 1] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * iv))[(iu + 1) * 3 + 1] * (uv.x - iu);f1.z = ((uchar*)(src.data + src.step * iv))[iu * 3 + 2] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * iv))[(iu + 1) * 3 + 2] * (uv.x - iu);f2.x = ((uchar*)(src.data + src.step * (iv + 1)))[iu * 3] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * (iv + 1)))[(iu + 1) * 3] * (uv.x - iu);f2.y = ((uchar*)(src.data + src.step * (iv + 1)))[iu * 3 + 1] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * (iv + 1)))[(iu + 1) * 3 + 1] * (uv.x - iu);f2.z = ((uchar*)(src.data + src.step * (iv + 1)))[iu * 3 + 2] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step * (iv + 1)))[(iu + 1) * 3 + 2] * (uv.x - iu);((uchar*)(dst.data + dst.step * j))[i * 3] = f1.x * (1 - Abs(uv.y - iv)) + f2.x * (Abs(uv.y - iv));  //三个通道进行赋值((uchar*)(dst.data + dst.step * j))[i * 3 + 1] = f1.y * (1 - Abs(uv.y - iv)) + f2.y * (Abs(uv.y - iv));((uchar*)(dst.data + dst.step * j))[i * 3 + 2] = f1.z * (1 - Abs(uv.y - iv)) + f2.z * (Abs(uv.y - iv));}
}//图像局部缩放算法
void LocalTranslationWarp_Eye(Mat& img, Mat& dst, int warpX, int warpY, int endX, int endY, float radius)
{//平移距离 float ddradius = radius * radius;//计算|m-c|^2//size_t mc = (endX - warpX) * (endX - warpX) + (endY - warpY) * (endY - warpY);//计算 图像的高  宽 通道数量int height = img.rows;int width = img.cols;int chan = img.channels();auto Abs = [&](float f) {return f > 0 ? f : -f;};for (int i = 0; i < width; i++){for (int j = 0; j < height; j++){// # 计算该点是否在形变圆的范围之内//# 优化,第一步,直接判断是会在(startX, startY)的矩阵框中if ((Abs(i - warpX) > radius) && (Abs(j - warpY) > radius))continue;float distance = (i - warpX) * (i - warpX) + (j - warpY) * (j - warpY);if (distance < ddradius){float rnorm = sqrt(distance) / radius;float ratio = 1 - (rnorm - 1) * (rnorm - 1) * 0.5;//映射原位置float UX = warpX + ratio * (i - warpX);float UY = warpY + ratio * (j - warpY);//根据双线性插值得到UX UY的值BilinearInsert(img, dst, UX, UY, i, j);}}}
}//大眼效果
Mat on_BigEye(int b, Mat src, vector<Point2f> points_vec)
{Mat dst = src.clone();Point2f left_landmark = points_vec[38];Point2f	left_landmark_down = points_vec[27];Point2f	right_landmark = points_vec[44];Point2f	right_landmark_down = points_vec[27];Point2f	endPt = points_vec[30];//# 计算第4个点到第6个点的距离作为距离/*float r_left = sqrt((left_landmark.x - left_landmark_down.x) * (left_landmark.x - left_landmark_down.x) +(left_landmark.y - left_landmark_down.y) * (left_landmark.y - left_landmark_down.y));cout << "左眼距离:" << r_left;*/float r_left = b;//	# 计算第14个点到第16个点的距离作为距离//float	r_right = sqrt(//	(right_landmark.x - right_landmark_down.x) * (right_landmark.x - right_landmark_down.x) +//	(right_landmark.y - right_landmark_down.y) * (right_landmark.y - right_landmark_down.y));//cout << "右眼距离:" << r_right;float r_right = b;//	# 瘦左                     //LocalTranslationWarp_Eye(src, dst, left_landmark.x, left_landmark.y, endPt.x, endPt.y, r_left);//	# 瘦右LocalTranslationWarp_Eye(src, dst, right_landmark.x, right_landmark.y, endPt.x, endPt.y, r_right);return dst;
}

3、图像结果
请添加图片描述
大眼睛结果
请添加图片描述

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

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

相关文章

动手学深度学习(Pytorch版)代码实践 -计算机视觉-38实战Kaggle比赛:图像分类 (CIFAR-10)

38实战Kaggle比赛&#xff1a;图像分类 (CIFAR-10) 比赛链接&#xff1a;CIFAR-10 - Object Recognition in Images | Kaggle 导入包 import os import glob import pandas as pd import numpy as np import torch import torchvision from torch.utils.data import Dataset…

R语言数据分析案例39-合肥市AQI聚类和多元线性回归

一、研究背景 随着全球工业化和城市化的迅速发展&#xff0c;空气污染问题日益凸显&#xff0c;已成为影响人类健康和环境质量的重大挑战。空气污染不仅会引发呼吸系统、心血管系统等多种疾病&#xff0c;还会对生态系统造成不可逆转的损害。因此&#xff0c;空气质量的监测和…

MySQL高阶:事务和并发

事务和并发 1. 事务创建事务 2. 并发和锁定并发问题 3. 事务隔离等级3.1 读取未提交隔离级别3.2 读取已提交隔离级别3.3 重复读取隔离级别3.4 序列化隔离级别 4. 死锁 1. 事务 事务&#xff08;trasaction&#xff09;是完成一个完整事件的一系列SQL语句。这一组SQL语句是一条…

经典小游戏(一)C实现——三子棋

switch(input){case 1:printf("三子棋\n");//这里先测试是否会执行成功break;case 0:printf("退出游戏\n");break;default :printf("选择错误&#xff0c;请重新选择!\n");break;}}while(input);//直到输入的结果为假&#xff0c;循环才会结束} …

go Channel原理 (二)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

error: Sandbox: rsync.samba in Xcode project

在Targets 的 Build Settings 搜索&#xff1a;User script sandboxing 设置为NO

python课程设计作业-TCP客户端-服务端通信

说明文档 目录 小组成员分工 作品功能介绍 使用的工具和方法 设计的步骤 课程设计中遇到的问题 结论 1. 小组成员分工 本次课程设计由以下小组成员完成&#xff1a; xxx 2. 作品功能介绍 本次课程设计的作品是一个简单的基于 TCP 协议的客户端-服务端通信示例。通过这个示…

【SpringBoot Web框架实战教程】06 SpringBoot 整合 Druid

不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。大家好&#xff0c;我是闲鹤&#xff0c;微信&#xff1a;xxh_1459&#xff0c;十多年开发、架构经验&#xff0c;先后在华为、迅雷服役过&#xff0c;也在高校从事教学3年&#xff1b;目前已创业了…

阿里云centos7.9 挂载数据盘到 www目录

一、让系统显示中文 参考&#xff1a;centos7 怎么让命令行显示中文&#xff08;英文-&#xff1e;中文&#xff09;_如何在命令行中显示中文-CSDN博客 1、输入命令&#xff1a;locale -a |grep "zh_CN" 可以看到已经存在了中文包 2、输入命令&#xff1a;sudo vi…

AGPT•intelligence:带你领略全新量化交易的风采

随着金融科技的快速发展&#xff0c;量化交易已经成为了投资领域的热门话题。越来越多的投资者开始关注和使用量化交易软件来进行投资决策。在市场上有许多量化交易软件可供选择。 Delaek&#xff0c;是一位资深的金融科技专家&#xff0c;在 2020年成立一家专注于数字资产量化…

第一后裔延迟高怎么办?快速降低第一后裔延迟

第一后裔/The First Descendant一款射击游戏&#xff0c;融合了刷宝、角色扮演、团队合作、剧情等元素&#xff0c;让每个玩家都能在自己的角度上&#xff0c;找到切入点&#xff0c;并不断地成长&#xff0c;一步步解开后裔身上隐藏的秘密。近期该作正式上线&#xff0c;很多玩…

vue项目创建+eslint+Prettier+git提交规范(commitizen+hooks+husk)

# 步骤 1、使用 vue-cli 创建项目 这一小节我们需要创建一个 vue3 的项目&#xff0c;而创建项目的方式依然是通过 vue-cli 进行创建。 不过这里有一点大家需要注意&#xff0c;因为我们需要使用最新的模板&#xff0c;所以请保证你的 vue-cli 的版本在 4.5.13 以上&#xff…

Debian linux忘记root密码如何重置

重启电脑, 到下图再按 e 键 在页面中可以看到有个ro的行&#xff0c;在ro行的尾部&#xff0c;添加 rw init/bin/bas 3. ctrl X 启动系统&#xff0c;最后会进入命令行模式 4. 重设root密码&#xff0c;输入命令 passwd root&#xff0c;按照提示输入新密码并确认 5. 重启系…

基于Python的自动化测试框架-Pytest总结-第一弹基础

Pytest总结第一弹基础 入门知识点安装pytest运行pytest测试用例发现规则执行方式命令行执行参数 配置发现规则 如何编写测试Case基础案例断言语句的使用pytest.fail() 和 Exceptions自定义断言函数异常测试测试类形式 pytest的Fixture使用Fixture入门案例使用fixture的Setup、T…

昇思25天学习打卡营第8天|模型训练

昇思25天学习打卡营第8天|模型训练 前言模型训练构建数据集定义神经网络模型定义超参、损失函数和优化器超参损失函数优化器 训练与评估 个人任务打卡&#xff08;读者请忽略&#xff09;个人理解与总结 前言 非常感谢华为昇思大模型平台和CSDN邀请体验昇思大模型&#xff01;从…

linux中如何启动python虚拟环境

找到python虚拟环境所在目录 执行下面的命令即可 source auth_python/bin/activate

【遇坑笔记】Node.js 开发环境与配置 Visual Studio Code

【遇坑笔记】Node.js 开发环境与配置 Visual Studio Code 前言node.js开发环境配置解决pnpm 不是内部或外部命令的问题&#xff08;pnpm安装教程&#xff09; 解决 pnpm : 无法加载文件 C:\Program Files\nodejs\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。 前言 最近部…

【代码随想录】【算法训练营】【第49天】 [300]最长递增子序列 [674]最长连续递增序列 [718]最长重复子数组

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 49&#xff0c;周二&#xff0c;坚持不了一点~ 题目详情 [300] 最长递增子序列 题目描述 300 最长递增子序列 解题思路 前提&#xff1a;最大递增子序列的长度 思路&#xff1a;动态规划 d…

基于X86+FPGA的精密加工检测设备解决方案

应用场景 随着我国高新技术的发展和国防现代化发展&#xff0c;航空、航天等领域需 要的大型光电子器件&#xff0c;微型电子机械、 光 电信息等领域需要的微型器件&#xff0c;还有一些复杂零件的加工需求日益增加&#xff0c;这些都需要借助精密甚至超精密的加工检测设备 客…

esp12实现的网络时钟校准

网络时间的获取是通过向第三方服务器发送GET请求获取并解析出来的。 在本篇博客中&#xff0c;网络时间的获取是一种自动的行为&#xff0c;当系统成功连接WiFi获取到网络天气后&#xff0c;系统将自动获取并解析得到时间和日期&#xff0c;为了减少误差每两分钟左右进行一次校…