opencv实现人像优化

简介

  本篇是使用opencv,简单实现人像优化功能:美白、肤色、祛斑和磨皮。注:本篇所使用的图片来源自网络。

具体实现

总体框架

  1、使用到了之前教程中的opencv实现button控件,每个功能,对应一个控件选择,然后都分别使用一个Trackbar,来手动控制,对图片处理的强度。
首先打开两幅图片,一张是作为操作选项的背景图片img,另一张是我们需要处理的图片dst_img,接着在在img显示窗口上,进行button的初始化
ButtonShow操作。最后分别对背景图片img和操作图片dst_img绑定了鼠标操作函数,同时,当用户按下键值之后,就直接退出程序。
int main(int argc,char **argv){
	if(argc < 2){
		printf("Please input picture!!\n");
		return -1;
	}
	memcpy(pic_name, argv[1], sizeof(argv[1]));
	img = imread(back_name,1);
	dst_img = imread(pic_name,1);
	imwrite(tmpPic, dst_img);
 
	ButtonShow();
	imshow(back_show, img);
	imshow(pic_show, dst_img);
	cvSetMouseCallback(back_show, on_mouse, NULL);
	cvSetMouseCallback(pic_show, pic_mouse, NULL);
	waitKey();
}

button响应

  鼠标点击button位置,响应对应的button操作,在之前的教程中已经讲过,这里不细讲了。主要看下,button被选择之后的具体响应操作。
首先需要注意:buttonFlag[buttonNum]用来保存button的当前状态,当某个button被选中之后,对应的buttonFlag被置为true,其他则被置为false。
在buttong响应函数on_button中,设置了当前button的选择状态。接着为对应选择的button创建了对应的Trackbar,Trackbar相关的初始化参数保存在
facePara中,同时关联好了,对应button功能被选择之后的操作函数:xxx_trackbar。
void on_button(int buttonNow, Mat dst_img){
	int i;
	char str[20];
 
	for(i=0; i<buttonNum; i++){
		if(i == buttonNow){
			buttonFlag[i] = true;
		}else{
			buttonFlag[i] = false;
		}
	}
	switch(buttonNow){
		case 0:
			createTrackbar(buttonName[buttonNow], back_show, &facePara[buttonNow][0], facePara[buttonNow][1], dermabrasion_trackbar);
			break;
		case 1:
			createTrackbar(buttonName[buttonNow], back_show, &facePara[buttonNow][0], facePara[buttonNow][1], Whitening_trackbar);
			break;
		case 2:
			createTrackbar(buttonName[buttonNow], back_show, &facePara[buttonNow][0], facePara[buttonNow][1], complexion_trackbar);
			break;
		case 3:
			createTrackbar(buttonName[buttonNow], back_show, &facePara[buttonNow][0], facePara[buttonNow][1], qudou_trackbar);
			break;
		default:
			break;
	}
}

磨皮

  使用的方式很简单,就是直接对当前图像,使用cvSmooth做轻微的模糊处理。
void dermabrasion_trackbar(int pos, void *){
	dst_img = imread(tmpPic, 1);
	IplImage pI_1 = dst_img, pI_2;
	CvScalar s1;
	int width = dst_img.rows;
	int height = dst_img.cols;
	Mat src2 = cv::Mat(width, height, CV_8UC3, 1);
 
	pI_2 = src2;
	if(facePara[0][0]%2 ==0){
		facePara[0][0] += 1;
	}
	cvSmooth(&pI_1, &pI_2, CV_GAUSSIAN, facePara[0][0]);
 
	imwrite(tmpPic, src2);
	imshow(pic_show, src2);
}

美白

  直接根据用户拖动trackbar的强度facePara[1][0],来直接对图片增加亮度,进而改变皮肤的美白程度。
void Whitening_trackbar(int pos, void *){
	dst_img = imread(tmpPic, 1);
	IplImage pI_1 = dst_img;
	CvScalar s1;
	int light_now;
	int i, j;
	int width = dst_img.rows;
	int height = dst_img.cols;
 
	if(faceParaTmp[1] == -100){
		light_now = facePara[1][0] - 30;
		faceParaTmp[1] = facePara[1][0];
	}else{
		light_now = facePara[1][0] - faceParaTmp[1];
		faceParaTmp[1] = facePara[1][0];
	}
 
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[0] = s1.val[0] + light_now;
			s1.val[1] = s1.val[1] + light_now;
			s1.val[2] = s1.val[2] + light_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imwrite(tmpPic, dst_img);
	imshow(pic_show, dst_img);
}

肤色

  直接根据用户拖动trackbar的强度facePara[2][0],来直接对图片增减亮度,进而改变肤色的红润。
void complexion_trackbar(int pos, void *){
	dst_img = imread(tmpPic, 1);
	IplImage pI_1 = dst_img;
	CvScalar s1;
	int R_now;
	int i, j;
	int width = dst_img.rows;
	int height = dst_img.cols;
 
	if(faceParaTmp[2] == -100){
		R_now = facePara[2][0] - 15;
		faceParaTmp[2] = facePara[2][0];
	}else{
		R_now = facePara[2][0] - faceParaTmp[2];
		faceParaTmp[2] = facePara[2][0];
	}
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[2] = s1.val[2] + (R_now * 2);
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imwrite(tmpPic, dst_img);
	imshow(pic_show, dst_img);
}

祛斑

  这一步的实现和前面几步有些区别,这里使用到了前面教程:图像复原中使用的函数inpaint,来去除掉选中的斑点。
    1、首先是在button中选中:qudou。
    2、接着鼠标在目标图片上左键按下移动的时候,鼠标上会有一个小圆圈提示,把小圆圈移动到需要去除掉斑点的位置,放开鼠标左键。函数inpaint
便会开始根据小圆圈进行修复。
void doDermabrasion(Mat dst, int x, int y){
	Mat mat1;
	int width = dst.rows;
	int height = dst.cols;
	mat1 = cv::Mat(width, height, CV_8UC1, cv::Scalar(0, 0, 0));
	circle(dst, Point(x, y), facePara[3][0], Scalar(100, 100, 100), -1);
	circle(mat1, Point(x, y), facePara[3][0], Scalar(255, 255, 255), -1);
	inpaint(dst, mat1, dst, 1, CV_INPAINT_TELEA);
}
 
void pic_mouse( int event, int x, int y, int flags, void* ustc){
	if(buttonFlag[3]){
		if(event == CV_EVENT_LBUTTONDOWN){
			flag_mouse = true;
			dst_img = imread(tmpPic, 1);
			circle(dst_img, Point(x, y), facePara[3][0], Scalar(100, 100, 100), -1);
			imshow(pic_show, dst_img);
		}else if(event == CV_EVENT_LBUTTONUP){
			flag_mouse = false;
			dst_img = imread(tmpPic, 1);
			doDermabrasion(dst_img, x, y);
			imshow(pic_show, dst_img);
			imwrite(tmpPic, dst_img);
		}else if((event == CV_EVENT_MOUSEMOVE) && (flag_mouse)){
			dst_img = imread(tmpPic, 1);
			circle(dst_img, Point(x, y), facePara[3][0], Scalar(100, 100, 100), -1);
			imshow(pic_show, dst_img);
		}
	}
}

效果演示

  对应的效果演示如下:
    优化前:
        
    优化后:
        

代码下载

     现在路径:http://download.csdn.net/detail/u011630458/8754741
时间: 2024-10-10 00:10:32

opencv实现人像优化的相关文章

opencv实现图像优化

简介 本篇是使用opencv实现,对图像亮度.对比度.锐化.白平衡和饱和度的调整. 具体实现 总体框架 1.首先是打开需要调整的图片到src中,接着创建了一张新图片src2,将对对象编辑的所有bar,绑定到src2中.接着循环等待用户操作. 如果用户按下'q',则退出程序:用户按下's',则保存当前图片到新文件中. memcpy(pic_name,argv[1],sizeof(argv[1]));   src=cv::imread(pic_name,1); width = src.rows; h

OpenCV中的SVM参数优化

OpenCV中的SVM参数优化 标签: svm参数优化opencv SVMSVR参数优化CvSVMopencv CvSVM 2014-08-19 10:31 2995人阅读 评论(8) 收藏 举报  分类: 机器学习(11)  opencv(18)  版权声明:本文为博主原创文章,未经博主允许不得转载. SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最常用的是用于分类,不过SVM也可以用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,OpenC

使用Qt创建第一个OpenCV的Gui应用

写在前面 学习OpenCV有一些小日子了,发现群里还有很多初学OpenCV的人像我当初一样跌跌撞撞到处找资料,所以在这里把学习笔记分享给大家,希望有志学习OpenCV进行计算机视觉活动的小伙伴们能少走一些弯路. 经过多方面查阅资料,了解到Qt开发平台对OpenCV的支持很好,但是在网上这方面的资料很少,能查到的大部分的图形交互设计都是基于OpenCV2.0之前的数据结构IplImage,而OpenCV现在官方已经更新到2.4.9版本了.偶然发现一本好书最近得到了一本好书< OpenCV 2 Co

EmguCV学习 与opencv的区别和联系

openCV是因特尔的一个开源的视觉库,里面几乎包含了所有的图像处理的经典算法,并且采用C和少量的C++编写,运行效率很高,对于做图像处理这方面工作的,认识opencv是必须的工作.不过opencv有个很大的不足,这在于它几乎没有提供gui这方面接口,很难满足目前应用程序开发的需要,而万恶的MFC框架丑陋的界面也成为了我的噩梦,MFC与opencv和界面优化几乎让我在图像处理这一块儿无法动弹. C#是.net平台上的明星语言,可以很容易做出漂亮的界面.EmguCV是将opencv封装的一个.ne

OpenCV优化:图像的遍历4种方式

OpenCV优化:图像的遍历4种方式 分类: 算法学习2014-04-13 23:43 1312人阅读 评论(0) 收藏 举报 opencv 目录(?)[+] OpenCV优化:图像的遍历4种方式 我们在实际应用中对图像进行的操作,往往并不是将图像作为一个整体进行操作,而是对图像中的所有点或特殊点进行运算,所以遍历图像就显得很重要,如何高效的遍历图像是一个很值得探讨的问题. 一.遍历图像的4种方式:at<typename>(i,j) Mat类提供了一个at的方法用于取得图像上的点,它是一个模板

基于暗通道去雾算法的实现与优化(二)opencv在pc上的实现

上一篇中,学习了何的论文中的去雾方法,这一篇中,我按照何的论文思路借助opencv 2.4.10 进行了实现,效果的确很好,就是耗时太多了,效果见下图:蓝色圆圈代表大气光值的取值点. 突然发现上一篇中忘了介绍大气光值A的求解了,论文中是这样做的: 1.首先取暗通道图中最亮的千分之一的像素点. 2.根据这些像素点的位置在原图中搜索一个最亮的点,这个点的强度(intensity)就是我们要求的A啦. 论文作者何认为这样做的好处就是避免了原图中比较亮的物体作为A的值,比如图片中的白色的汽车,如果从原图

OpenCV中的SVM參数优化

SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最经常使用的是用于分类,只是SVM也能够用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,opencv中自然也是有集成好了,我们能够直接调用.OpenCV中的SVM算法是基于LibSVM软件包开发的,LibSVM是台湾大学林智仁(Lin Chih-Jen)等开发设计的一个简单.易于使用和高速有效的SVM模式识别与回归的软件包. 网上讲opencv中SVM使用的文章有非常多,但讲SVM參数优化的文章却

IOS 用openCv实现简单的扣人像的

最近要实现人像扣图的功能,我在网上查到的扣图的方式主要有两种,一种是coreImage 色域,一种是openCv边缘检测 第一种适合纯色背景,扣图精准,第二种,适合复杂背景,但是默认的扣图不精确,如下图 1.处理前的照片 2.处理后的照片 coreImage 网上已经有很多实现了,也有很多文章,我就不多说了,我只把我实现的代码贴出来,代码粘过去就能用,另忘了,导入CubeMap.c //coreImage 扣图 createCubeMap(值1,值2)值范围0-360 扣掉值1到值2范围内的颜色

18、OpenCV Python 简单实现一个图片生成(类似抖音生成字母人像)

1 __author__ = "WSX" 2 import cv2 as cv 3 import numpy as np 4 5 def local_threshold(img): #局部阈值 6 gray = cv.cvtColor(img , cv.COLOR_BGR2GRAY) #首先变为灰度图 7 binary = cv.adaptiveThreshold( gray ,255 , cv.ADAPTIVE_THRESH_GAUSSIAN_C , cv.THRESH_BINARY