#include <iostream>
#include <vector>
#include <opencv2\imgproc\types_c.h>
#include <opencv2\objdetect.hpp>
#include <opencv2\features2d.hpp>
#include <opencv2\calib3d.hpp>
#include <opencv2\photo.hpp>
#include "Histogram1D.hpp"
using namespace cv;
using namespace std;
vector<Rect> DetectFace(Mat target);
Mat Change2Gray(Mat ori);
void HistSpecify(const Mat &src, const Mat &ref, Mat &result);
void EqualizeImage(const Mat &src, Mat &dst);
int main()
{
Mat img, img_gray;
Mat target, target_gray;
target = imread("target.jpg");
img = imread("ori.jpg");
//resize(target, target, Size(img.cols, img.rows));
//直方图规定化
HistSpecify(target, img, target);
//获取灰度图
img_gray = Change2Gray(img);
target_gray = Change2Gray(target);
//检测两张图的脸部
vector<Rect> faces_1 = DetectFace(target_gray);
vector<Rect> faces_2 = DetectFace(img_gray);
Mat target_roi;
if (faces_1.size() == 0)
{
cout << "目标图没有人脸";
getchar();
return -1;
}
//Debug:脸部画矩形标记
//rectangle(target, Point(faces_1[0].x, faces_1[0].y), Point(faces_1[0].x + faces_1[0].width, faces_1[0].y + faces_1[0].height), Scalar(0, 255, 0), 1, 8);
Rect rect(faces_1[0].x, faces_1[0].y, faces_1[0].width, faces_1[0].height);
if (faces_2.size() == 0)
{
cout << "原图没有人脸";
getchar();
return -1;
}
//Debug:脸部画矩形标记
//rectangle(img, Point(faces_2[0].x, faces_2[0].y), Point(faces_2[0].x + faces_2[0].width, faces_2[0].y + faces_2[0].height), Scalar(0, 255, 0), 1, 8);
//截取目标脸部
target_roi = target(rect);
//将目标脸部大小放缩到原图脸部大小
resize(target_roi, target_roi, Size(faces_2[0].width, faces_2[0].height));
//imshow("cut", target_roi);
//创建遮罩
Mat mask = Mat::zeros(img.rows, img.cols, CV_8UC3);
Mat src = Mat::zeros(img.rows, img.cols, CV_8UC3);
Mat white = Mat::zeros(faces_2[0].width, faces_2[0].height, CV_8UC3);
white.setTo(Scalar(256, 256, 256));
Rect roi_rect(faces_2[0].x, faces_2[0].y, faces_2[0].width, faces_2[0].height);
white.copyTo(mask(roi_rect));
target_roi.copyTo(src(roi_rect));
//边界融合
Mat result = Mat::zeros(img.rows, img.cols, CV_8UC3);
Point center(faces_2[0].x + (int)(faces_2[0].width / 2), faces_2[0].y + (int)(faces_2[0].height / 2));
seamlessClone(src, img, mask, center, result, NORMAL_CLONE);
//高斯模糊
GaussianBlur(img, img, Size(5, 5), 0);
//抠出区域
/*bitwise_not(mask, mask_turn);
bitwise_and(img, mask_turn, img);
target_roi.copyTo(mask(roi_rect));
add(mask, img, img);
GaussianBlur(img, img, Size(9, 9), 1);*/
//imshow("mask", mask);
int c = 0;
imshow("target", target);
imshow("ori", img);
imshow("res", result);
while (c != 27)
{
c = waitKey(1);
if (c == 102)
{
flip(target_roi, target_roi, 1);
target_roi.copyTo(src(roi_rect));
seamlessClone(src, img, mask, center, result, NORMAL_CLONE);
imshow("target", target);
imshow("ori", img);
imshow("res", result);
}
}
imwrite("output.jpg", result);
return 0;
}
//检测人脸位置
vector<Rect> DetectFace(Mat target)
{
CascadeClassifier faceCascade;
faceCascade.load("haarcascade_frontalface_alt.xml");
vector<Rect> faces;
faceCascade.detectMultiScale(target, faces, 1.2, 6, 0, Size(0, 0));
return faces;
}
//获取灰度图像
Mat Change2Gray(Mat ori)
{
Mat gray;
if (ori.channels() == 3)
{
cvtColor(ori, gray, CV_BGR2GRAY);
}
else
{
gray = ori;
}
return gray;
}
/**
* @brief EqualizeImage 对灰度图像进行直方图均衡化
* @param src 输入图像
* @param dst 均衡化后的图像
*/
void EqualizeImage(const Mat &src, Mat &dst)
{
Histogram1D hist1D;
Mat hist = hist1D.getHistogram(src);
hist /= (src.rows * src.cols); // 对得到的灰度直方图进行归一化,得到密度(0~1)
float cdf[256] = { 0 }; // 灰度的累积概率
Mat lut(1, 256, CV_8U); // 创建用于灰度变换的查找表
for (int i = 0; i < 256; i++)
{
// 计算灰度级的累积概率
if (i == 0)
{
cdf[i] = hist.at<float>(i);
}
else
{
cdf[i] = cdf[i - 1] + hist.at<float>(i);
}
lut.at<uchar>(i) = static_cast<uchar>(255 * cdf[i]); // 创建灰度的查找表
}
LUT(src, lut, dst); // 应用查找表,进行灰度变化,得到均衡化后的图像
}
/**
* @brief HistSpecify 对灰度图像进行直方图规定化
* @param src 输入图像
* @param ref 参考图像,解析参考图像的直方图并用于规定化
* @param result 直方图规定化后的图像
* @note 手动设置一个直方图并用于规定化比较麻烦,这里使用一个参考图像来进行
*/
void HistSpecify(const Mat &src, const Mat &ref, Mat &result)
{
Histogram1D hist1D;
Mat src_hist = hist1D.getHistogram(src);
Mat dst_hist = hist1D.getHistogram(ref);
float src_cdf[256] = { 0 };
float dst_cdf[256] = { 0 };
// 直方图进行归一化处理
src_hist /= (src.rows * src.cols);
dst_hist /= (ref.rows * ref.cols);
// 计算原始直方图和规定直方图的累积概率
for (int i = 0; i < 256; i++)
{
if (i == 0)
{
src_cdf[i] = src_hist.at<float>(i);
dst_cdf[i] = dst_hist.at<float>(i);
}
else
{
src_cdf[i] = src_cdf[i - 1] + src_hist.at<float>(i);
dst_cdf[i] = dst_cdf[i - 1] + dst_hist.at<float>(i);
}
}
// 累积概率的差值
float diff_cdf[256][256];
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
diff_cdf[i][j] = fabs(src_cdf[i] - dst_cdf[j]);
}
}
// 构建灰度级映射表
Mat lut(1, 256, CV_8U);
for (int i = 0; i < 256; i++)
{
// 查找源灰度级为i的映射灰度
// 和i的累积概率差值最小的规定化灰度
float min = diff_cdf[i][0];
int index = 0;
for (int j = 1; j < 256; j++)
{
if (min > diff_cdf[i][j])
{
min = diff_cdf[i][j];
index = j;
}
}
lut.at<uchar>(i) = static_cast<uchar>(index);
}
// 应用查找表,做直方图规定化
LUT(src, lut, result);
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【探索人工智能的宝藏之地】 无论您是计算机相关专业的在校学生、老师,还是企业界的探索者,这个项目都是为您量身打造的。无论您是初入此领域的小白,还是寻求更高层次进阶的资深人士,这里都有您需要的宝藏。不仅如此,它还可以作为毕设项目、课程设计、作业、甚至项目初期的立项演示。 【人工智能的深度探索】 人工智能——模拟人类智能的技术和理论,使其在计算机上展现出类似人类的思考、判断、决策、学习和交流能力。这不仅是一门技术,更是一种前沿的科学探索。 【实战项目与源码分享】 我们深入探讨了深度学习的基本原理、神经网络的应用、自然语言处理、语言模型、文本分类、信息检索等领域。更有深度学习、机器学习、自然语言处理和计算机视觉的实战项目源码,助您从理论走向实践,如果您已有一定基础,您可以基于这些源码进行修改和扩展,实现更多功能。 【期待与您同行】 我们真诚地邀请您下载并使用这些资源,与我们一起在人工智能的海洋中航行。同时,我们也期待与您的沟通交流,共同学习,共同进步。让我们在这个充满挑战和机遇的领域中共同探索未来!
资源推荐
资源详情
资源评论
收起资源包目录
基于OpenCV已训练好的分类器进行人脸检测,并替换为目标人脸.zip (56个子文件)
资料总结
change-face
change-face
ori.jpg 61KB
haarcascade_frontalface_alt.xml 661KB
Histogram1D.hpp 2KB
main.cpp 5KB
x64
Release
vc141.pdb 996KB
Histogram1D.obj 1.49MB
change-face.tlog
CL.write.1.tlog 2KB
change-face.write.1u.tlog 2KB
CL.command.1.tlog 1KB
link.command.1.tlog 2KB
link.read.1.tlog 5KB
link.write.1.tlog 668B
change-face.lastbuildstate 223B
CL.read.1.tlog 61KB
change-face.Build.CppClean.log 1KB
change-face.log 376B
main.obj 1.64MB
Debug
vc141.pdb 2.13MB
Histogram1D.obj 57KB
vc141.idb 563KB
change-face.tlog
CL.write.1.tlog 2KB
CL.command.1.tlog 1KB
link.command.1.tlog 3KB
link.read.1.tlog 5KB
link.write.1.tlog 806B
change-face.lastbuildstate 221B
CL.read.1.tlog 61KB
change-face.log 115B
main.obj 437KB
output.jpg 32KB
target.jpg 47KB
change-face.vcxproj.filters 1020B
change-face.vcxproj 7KB
change-face.vcxproj.user 162B
.vs
change-face
v15
Browse.VC.db 42.1MB
.suo 35KB
ipch
AutoPCH
3bf9ef62ac15bc81
MAIN.ipch 25.13MB
ec96cd0ab41572df
HISTOGRAM1D.ipch 69.19MB
9af2dfe3d2259a72
MAIN.ipch 75.31MB
77fa08260288e87c
HISTOGRAM1D.ipch 72.31MB
11d32e20281cb5f2
MAIN.ipch 76.44MB
2c4fd00709be825f
HISTOGRAM1D.ipch 72.31MB
x64
Release.zip 2.13MB
Release
ori.jpg 61KB
opencv_world400d.lib 2.34MB
change-face.pdb 6.42MB
haarcascade_frontalface_alt.xml 661KB
change-face.exe 505KB
change-face.ipdb 221KB
opencv_world400.lib 2.27MB
target.jpg 47KB
change-face.iobj 566KB
Debug
change-face.ilk 667KB
change-face.pdb 716KB
change-face.exe 139KB
change-face.sln 1KB
共 56 条
- 1
资源评论
妄北y
- 粉丝: 1w+
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功