基于Opencv的自动美颜功能代码

原来程序的设想是先对照片进行人脸识别,然后对人脸进行美颜处理;

花了大时间进行了人脸分类器的训练,但是识别效果还是不理想,所先跳过人脸识别,实现美颜处理;

找到了一个PS美颜的教程http://www.jb51.net/photoshop/9715_2.html 了解到高斯模糊,深入了解;

找到了一个图像修复的函数inpaint,深入了解;

以上两个函数大致就可以实现美颜处理了,为了结合以前所学,添加了滑条交互和摄像头自拍功能,这个小项目也算是这段时间所学的汇总见证吧。

#include "opencv2/core/core.hpp"  
#include"opencv2/highgui/highgui.hpp"  
#include"opencv2/imgproc/imgproc.hpp"  
#include<iostream>
#include<opencv2/opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"  

#define TRACKBARNAME "魔法棒大小"
#define RESULT "美颜后"
#define ORIGIN "美颜前"

using namespace cv;

//***************************************************************//
//全局变量定义
//***************************************************************//
bool g_bDrawing = false; //鼠标点击flag
Point g_CurrPoint, g_OrgPoint;//鼠标当前位置
int g_nThick , g_nBlue = 140, g_nGreen = 140, g_nRed = 140;//线型
RNG &rng = theRNG();
Mat dst_step1;//高美颜后的图
Mat dst;//高斯模糊图
Mat mengban1;//蒙版
Mat image;   //自拍后的图像名
Mat frame;   //视频显示桢

//****************************************************************//
//调用摄像头实现自拍函数
//***************************************************************//
void cameraCapture()
{
	char key;
	bool flag=1;	
	int i = 8;
	//打开摄像头
	VideoCapture capture(0);
	//大循环,为了截图后继续显示摄像头实时图片
	while (flag)
	{
		//给key一个初始值,便于循环一开始进行
		key = 'c';
		//判断key是否为空格,不为空格则循环,即显示摄像头
		while (key != ' ')
		{
			key = cvWaitKey(10);
			capture >> frame;			
			imshow("摄像头", frame);		
			waitKey(3);
			flag = 0;
		}
		//便于观察key是否有效
		imwrite("image.jpg", frame);
		key = 'c';
		destroyAllWindows();
	}
	
}

//****************************************************************//
//滑动条改变笔触大小的回调函数
//***************************************************************//
void changePenSize(int i,void *)
{
	g_nThick = i;
}

//****************************************************************//
//磨皮(高斯模糊)
//***************************************************************//
int GaussianBlur(){
	image = imread("image.jpg");
	int value1 = 3, value2 = 1; //磨皮程度与细节程度的确定
	int dx = value1 * 5;    //双边滤波参数之一  
	double fc = value1*12.5; //双边滤波参数之一  
	int p = 50; //透明度  
	Mat temp1, temp2, temp3, temp4;
	//双边滤波  
	bilateralFilter(image, temp1, dx, fc, fc);
	temp2 = (temp1 - image + 128);
	//高斯模糊  
	GaussianBlur(temp2, temp3, Size(2 * value2 - 1, 2 * value2 - 1), 0, 0);
	temp4 = image + 2 * temp3 - 255;
	dst = (image*(100 - p) + temp4*p) / 100;
	dst.copyTo(dst_step1);	
	return 0;
}

//***************************************************************//
//inpaint函数 手动选择杂色点
//***************************************************************//
void onMouse(int event, int x, int y, int flag, void *param)
{
	Mat &img = *(cv::Mat*)param;
	switch (event)
	{
		//移动鼠标的时候
	case CV_EVENT_MOUSEMOVE:
	{							   							
		g_OrgPoint = g_CurrPoint;
		g_CurrPoint = Point(x, y);
		if (g_bDrawing == 1)
         {				
			line(dst_step1, g_CurrPoint, g_OrgPoint, Scalar(255), g_nThick);
			imshow(RESULT, dst_step1);
			line(mengban1, g_CurrPoint, g_OrgPoint, Scalar(255), g_nThick);
		 }
	}
		break;
		//点击鼠标左键时
	case CV_EVENT_LBUTTONDOWN:
	{
			g_bDrawing = true;
			g_OrgPoint = Point(x, y);
			g_CurrPoint = g_OrgPoint;
	}
		break;
		//松开鼠标左键时
	case CV_EVENT_LBUTTONUP:
	{
			g_bDrawing = false;
			inpaint(dst_step1, mengban1, dst_step1, 3, INPAINT_NS);
			imshow(RESULT, dst_step1);
			imwrite("美颜结果图.jpg", dst_step1);
	}   
		break;
	}
}

//***************************************************************//
//程序说明
//***************************************************************//
void Introduction()
{
	printf("\n\\*****************************************************************************\\\n");
	printf("\\*****************************************************************************\\");
	printf("\n\t\t\t\t自拍美颜程序!\n");
	printf("\n\n功能介绍:\n\n1、自动调用摄像头\n2、按下空格键实现自拍\n3、自动美颜\n4、魔法笔点击图片杂色进行自动修复");
	printf("\n\n\t\t\t\t谢谢您的使用!\n");
	printf("\\*****************************************************************************\\\n");
	printf("\\*****************************************************************************\\\n");
}

//***************************************************************//
//主函数
//***************************************************************//
int main()
{
	//***************************************************************//
	//程序说明
	//***************************************************************//
	Introduction();

	//***************************************************************//
	//调用摄像头获取需要美颜的自拍
	//***************************************************************//
	cameraCapture();
	image = imread("image.jpg");
	imshow(ORIGIN, image);

	//***************************************************************//
	//图像磨皮功能
	//***************************************************************//
	GaussianBlur();
	
	//***************************************************************//
	//inpaint函数变量准备
	//***************************************************************//
	//用一个变量来存储原图像 为MASK 分配空间
	mengban1.create(dst_step1.size(), CV_8UC1);
	mengban1 = Scalar::all(0);
	namedWindow(RESULT);
	setMouseCallback(RESULT, onMouse, 0);

	//***************************************************************//
	//创建滑条改变笔触大小
	//***************************************************************//
	int originValue = 2;
	createTrackbar(TRACKBARNAME, RESULT, &originValue, 30, changePenSize);
	changePenSize(originValue,0);

	//***************************************************************//
	//美颜后的照片
	//***************************************************************//
	imshow(RESULT, dst_step1);
	waitKey();		

	return 0;
}
每天8点下班,9点半学习到12点,断断续续学了3个礼拜,我觉得很有成就感。也是为了证明我的学习能力不必任何人差!
  • 11
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值