环境:VS2012+OPENCV2.4.6
算法说明:
实现LOMO效果的三个步骤
第一、在绿色中提亮黄色,红色偏品红处理,蓝色偏粉处理。将画面整体提纯,暗部做稍微的提亮。
第二、lomo风照片画面中基本上只有两个深度层次,主体和背景,你很难看准中间的过度,主体往往都比较清晰而背景呢往往都有比较大的模糊
第三、暗角较大。前面我们说过LOMO的照片画面色彩艳丽,但是层次不鲜明,整体都是蒙蒙的感觉,因此照片整体看上去显得比较平面,
往往主体突出得不够,为了突出主体我们就必须给画面做一个暗角。
源图像
怀旧风
均衡化
模糊
LOMO尝试
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; int main() { Mat image= imread("boldt.jpg"); Mat new_image = Mat::zeros( image.size(), image.type() ); for( int y = 0; y < image.rows; y++ ) { for( int x = 0; x < image.cols; x++ ) { //第一、在绿色中提亮黄色,红色偏品红处理,蓝色偏粉处理。将画面整体提纯,暗部做稍微的提亮。 //////其实这个地方开根号*10是非常不科学滴 //蓝色偏粉处理....我次奥,蓝色怎么偏粉处理.....其实这个没有实现出来啥好看的效果 //new_image.at<Vec3b>(y,x)[0] = image.at<Vec3b>(y,x)[0]; new_image.at<Vec3b>(y,x)[0] = 10*sqrt(image.at<Vec3b>(y,x)[0]); //绿色中提亮黄色 new_image.at<Vec3b>(y,x)[1] = image.at<Vec3b>(y,x)[1]; //new_image.at<Vec3b>(y,x)[1] = 10*sqrt(image.at<Vec3b>(y,x)[1]); //红色偏品红处理 new_image.at<Vec3b>(y,x)[2] = image.at<Vec3b>(y,x)[2]; //new_image.at<Vec3b>(y,x)[2] = 10*sqrt(image.at<Vec3b>(y,x)[2]); } } //merge(channels,image); namedWindow("original image"); imshow("original image",image); namedWindow("怀旧风"); imshow("怀旧风",new_image); //调整下亮度啥的,个人感觉怎么对比度首先增强,然后再进行亮度增强 Mat mergeImg;//合并后的图像 //用来存储各通道图片的向量 vector<Mat> splitBGR(image.channels()); //分割通道,存储到splitBGR中 split(image,splitBGR); //对各个通道分别进行直方图均衡化 for(int i=0; i<image.channels(); i++) equalizeHist(splitBGR[i],splitBGR[i]); //合并通道 merge(splitBGR,mergeImg); namedWindow("equalizeHist"); imshow("equalizeHist", mergeImg); //第二、lomo风照片画面中基本上只有两个深度层次,主体和背景,你很难看准中间的过度,主体往往都比较清晰而背景呢往往都有比较大的模糊 Mat blur_image = Mat::zeros( image.size(), image.type() ); blur(new_image,blur_image,Size( 8, 8), Point(-1,-1),BORDER_DEFAULT); namedWindow("blur image"); imshow("blur image",blur_image); //第三、暗角较大。前面我们说过LOMO的照片画面色彩艳丽,但是层次不鲜明,整体都是蒙蒙的感觉,因此照片整体看上去显得比较平面, //往往主体突出得不够,为了突出主体我们就必须给画面做一个暗角。 Mat src=image; Mat res,roi,reverse_roi,reverse_res; res=Mat::zeros( image.size(), image.type() ); reverse_res=Mat::zeros( image.size(), image.type() ); //cout<<image.type()<<endl; roi=Mat::zeros( image.size(), image.type()); //用来提取外面的轮廓,所以要求外面全是白色 reverse_roi=Mat(image.size(),image.type()); for( int y = 0; y < reverse_roi.rows; y++ ) { for( int x = 0; x < reverse_roi.cols; x++ ) { reverse_roi.at<Vec3b>(y,x)[0] = 255; reverse_roi.at<Vec3b>(y,x)[1] = 255; reverse_roi.at<Vec3b>(y,x)[2] = 255; } } //尝试画椭圆 int thickness = 2; int lineType = 8; double angle=90; double w=image.rows; ellipse( roi, //输入输出的矩阵 Point( 2*w/3.0, w/2.0 ),//点的中心 Size( w/3.0, w/2.0 ),//轴线,轴心,坐标轴 angle,//旋转角度 0,//开始角度 360,//结束角度 Scalar( 255, 255, 255 ),//画线颜色 thickness,//粗细程度 lineType );//线的类型 //在白色的区域画黑线 ellipse(reverse_roi, Point( 2*w/3.0, w/2.0 ), Size( w/3.0, w/2.0 ), angle,0,360,Scalar( 0, 0, 0 ),thickness,lineType ); floodFill(reverse_roi, Point(w/2, w/2), Scalar( 0, 0, 0 )); //填充椭圆,这个填充绝对有问题啊有问题,果然需要Scalar( 255, 255, 255 ),而不是单纯的255 floodFill(roi, Point(w/2, w/2), Scalar( 255, 255, 255 )); image.copyTo(res,roi);//此处roi为mask image.copyTo(reverse_res,reverse_roi); //把中间的感兴趣区域的HSV中的亮度调高,饱和度提高....... cvtColor(res,res,CV_BGR2HSV); for( int y = 0; y < res.rows; y++ ) { for( int x = 0; x < res.cols; x++ ) { //饱和度0~1 res.at<Vec3b>(y,x)[1] = res.at<Vec3b>(y,x)[1]; //亮度0~1 res.at<Vec3b>(y,x)[2] = res.at<Vec3b>(y,x)[2]; } } cvtColor(res,res,CV_HSV2BGR); //把背景区域整体的HSV中的饱和度调高,亮度降低,为什么调饱和度会出现改变亮度的问题 cvtColor(reverse_res,reverse_res,CV_BGR2HSV); for( int y = 0; y < reverse_res.rows; y++ ) { for( int x = 0; x < reverse_res.cols; x++ ) { reverse_res.at<Vec3b>(y,x)[1] = 1.5*reverse_res.at<Vec3b>(y,x)[1]; if(reverse_res.at<Vec3b>(y,x)[1]>255) { reverse_res.at<Vec3b>(y,x)[1]=255; } reverse_res.at<Vec3b>(y,x)[2] = reverse_res.at<Vec3b>(y,x)[2]; } } cvtColor(reverse_res,reverse_res,CV_HSV2BGR); //主要是把外围的进行blur //blur(reverse_res,reverse_res,Size( 8, 8), Point(-1,-1),BORDER_DEFAULT); //合并新的图像 reverse_res=reverse_res+res; /////////////第三步之后重新处理第一第二步尝试下 for( int y = 0; y < image.rows; y++ ) { for( int x = 0; x < image.cols; x++ ) { //蓝色偏粉处理....我次奥,蓝色怎么偏粉处理.....其实这个没有实现出来啥好看的效果 //new_image.at<Vec3b>(y,x)[0] = image.at<Vec3b>(y,x)[0]; reverse_res.at<Vec3b>(y,x)[0] = 10*sqrt(reverse_res.at<Vec3b>(y,x)[0]); //绿色中提亮黄色 reverse_res.at<Vec3b>(y,x)[1] = reverse_res.at<Vec3b>(y,x)[1]; //new_image.at<Vec3b>(y,x)[1] = 10*sqrt(image.at<Vec3b>(y,x)[1]); //红色偏品红处理 reverse_res.at<Vec3b>(y,x)[2] = reverse_res.at<Vec3b>(y,x)[2]; //new_image.at<Vec3b>(y,x)[2] = 10*sqrt(image.at<Vec3b>(y,x)[2]); } } //blur all blur(reverse_res,reverse_res,Size( 2, 2), Point(-1,-1),BORDER_DEFAULT); namedWindow("trial image"); imshow("trial image",reverse_res); waitKey(); }