简介
本篇是使用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