OPENCV LOMO效果

环境:VS2012+OPENCV2.4.6

算法说明:

实现LOMO效果的三个步骤

 

第一、在绿色中提亮黄色,红色偏品红处理,蓝色偏粉处理。将画面整体提纯,暗部做稍微的提亮。

第二、lomo风照片画面中基本上只有两个深度层次,主体和背景,你很难看准中间的过度,主体往往都比较清晰而背景呢往往都有比较大的模糊

第三、暗角较大。前面我们说过LOMO的照片画面色彩艳丽,但是层次不鲜明,整体都是蒙蒙的感觉,因此照片整体看上去显得比较平面,

往往主体突出得不够,为了突出主体我们就必须给画面做一个暗角。


源图像


怀旧风

OPENCV LOMO效果_第1张图片

均衡化

OPENCV LOMO效果_第2张图片

模糊

OPENCV LOMO效果_第3张图片

LOMO尝试

OPENCV LOMO效果_第4张图片









#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();
	
}





你可能感兴趣的:(C++,算法,opencv,计算机视觉)