编程环境:VS2012+OpenCV2.4.6
功能:
第一种是将指定三幅图的指定位置的像素直接搬移到新的图像上
第二种是讲指定三幅图按照我们设定好的大小非等比缩放到第三幅图上
三张源图像
两种效果图
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2\imgproc\imgproc.hpp>
- #include <iostream>
- using namespace std;
- using namespace cv;
- int main()
- {
- ///读入图像/
- ///image1
- //cv::Mat image::zeros(768,1300);
- Mat image1;
- image1= cv::imread("1.jpg");
- if(!image1.data)
- {
- cout<<"image does not exist"<<endl;
- }
- namedWindow("Image1");//定义窗口
- imshow("Image1",image1);//显示图像
- ///image2
- Mat image2;
- image2= cv::imread("2.jpg");
- if(!image2.data)
- {
- cout<<"image does not exist"<<endl;
- }
- namedWindow("Image2");
- imshow("Image2", image2);
- //image3
- Mat image3;
- image3= cv::imread("3.jpg");
- if(!image3.data)
- {
- cout<<"image does not exist"<<endl;
- }
- cv::namedWindow("Image3");
- cv::imshow("Image3", image3);
- ///定义生成图像/
- cv::Mat combine = cv::Mat::zeros( 700, 1300,image1.type());
- //cout<<image.type()<<endl; 我擦那个哈士奇竟然是16
- // define ROI
- Mat imageROI1= combine(Rect(0,0,500,700));
- Mat imageROI2= combine(Rect(500,0,800,350));
- Mat imageROI3= combine(Rect(500,350,800,350));
- //DEBUG
- //std::cout<<combine.cols<<" "<<combine.rows<<endl;
- //图像直接拷贝的方式~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~••
- image1(cv::Rect( 0, 0, 500, 700)).copyTo(imageROI1);
- image2(cv::Rect( 0, 0, 800, 350)).copyTo(imageROI2);
- image3(cv::Rect( 0, 0, 800, 350)).copyTo(imageROI3);
- //通过看到数值来验证是否是这个地方出错
- //std::cout<<combine(cv::Rect(0, 0, 3, 3))<<std::endl;
- //最终效果显示~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- namedWindow("Combined Image");
- imshow("Combined Image", combine);
- ///另外一种方式/
- /
- //那么我们使用另外一种方式,就是resize的方式来搞下这个东西,恩,让所有的图像都搞到这里面
- ///!!!建议用等比缩放然后获得出现的黑框
- resize(image1, imageROI1, imageROI1.size(),INTER_CUBIC);
- resize(image2, imageROI2, imageROI2.size(),INTER_CUBIC);
- resize(image3, imageROI3, imageROI3.size(),INTER_CUBIC);
- namedWindow("Combined Image++");
- imshow("Combined Image++", combine);
- waitKey(0);
- }
环境: OPENCV2.4.6+VS2012
功能:
对每个像素进行修改,提高亮度
另一种方法是讲BGR三个通道分开,分别进行均衡化,当然出现的效果就比较丑
源图像
效果图1(BGR均衡化)
效果图2
WIN32 控制窗的参数
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2\imgproc\imgproc.hpp>
- #include <iostream>
- using namespace std;
- using namespace cv;
- int main()
- {
- //
- 直方图均衡化的方式修改源图像,当然这是一次性的效果
- ///
- //读入图像
- Mat mat = imread("3.jpg");
- namedWindow("original");
- imshow("original", mat);
- Mat mergeImg;//合并后的图像
- //用来存储各通道图片的向量
- vector<Mat> splitBGR(mat.channels());
- //分割通道,存储到splitBGR中
- split(mat,splitBGR);
- //对各个通道分别进行直方图均衡化
- for(int i=0; i<mat.channels(); i++)
- equalizeHist(splitBGR[i],splitBGR[i]);
- //合并通道
- merge(splitBGR,mergeImg);
- namedWindow("equalizeHist");
- imshow("equalizeHist", mergeImg);
- ///另外一种方式,可以选择参数的方式,控制对比度和亮度//
- double alpha; /**< 控制对比度 */
- int beta; /**< 控制亮度 */
- Mat image = imread("3.jpg");
- Mat new_image = Mat::zeros( image.size(), image.type() );
- /// 初始化
- cout << " Basic Linear Transforms " << endl;
- cout << "-------------------------" << endl;
- cout << "* Enter the alpha value [1.0-3.0]: ";
- cin >> alpha;
- cout << "* Enter the beta value [0-100]: ";
- cin >> beta;
- /// 执行运算 new_image(i,j) = alpha*image(i,j) + beta
- for( int y = 0; y < image.rows; y++ )
- {
- for( int x = 0; x < image.cols; x++ )
- {
- for( int c = 0; c < 3; c++ )
- {
- new_image.at<Vec3b>(y,x)[c] = saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
- }
- }
- }
- namedWindow("alpha_beta", 1);
- imshow("alpha_beta", new_image);
- waitKey();
- return 0;
- }
算法说明:
实现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();
- }
算法说明:
定义感兴趣区域,然后将需要的水印复制到感兴趣区域上
我们这个地方专门加到了BGR三个通道的G通道,让整个效果更加明显
环境:VS2012+OpenCV2.4.6
源图像
效果图
- #include <vector>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <iostream>
- using namespace cv;
- using namespace std;
- int main()
- {
- float x,y;
- //专门加到绿色通道
- // read images
- Mat logo= cv::imread("5.bmp",0);
- Mat image1= cv::imread("boldt.jpg");
- cv::namedWindow("orig");
- cv::imshow("orig",image1);
- // split 3-channel image into 3 1-channel images
- std::vector<cv::Mat> channels;
- cv::split(image1,channels);
- Mat imageROI= channels.at(1);
- cout<<"请输入x的位置" "x的位置范围为0到"<<image1.cols-logo.cols<<endl;
- cin>>x;
- //防止溢出
- if((x>=0)&&(x<=image1.cols-logo.cols))
- x=x;
- else if(x<0)
- x=0;
- else x=image1.cols-logo.cols;
- cout<<"请输入y的位置""y的位置范围为0到"<<image1.rows-logo.rows<<endl;
- cin>>y;
- if((y>=0)&&(y<=image1.rows-logo.rows))
- y=y;
- else if(y<0)
- y=0;
- else y=image1.rows-logo.rows-1;
- cv::addWeighted(imageROI(cv::Rect(x,y,logo.cols,logo.rows)),1.0,
- logo,0.5,0.,imageROI(cv::Rect(x,y,logo.cols,logo.rows)));
- cv::merge(channels,image1);
- cv::namedWindow("吃货");
- cv::imshow("吃货",image1);
- cv::waitKey();
- return 0;
- }
算法:
将摄入图像的左半边进行翻转,同时根据喜剧效果,将未翻转和翻转的图像合成到一副图像上
想法来源:
WIN32:
源图像
翻转图像
效果图
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- /*int main(){
- cv::Mat image=cv::imread("1.jpg");
- cv::namedWindow("My Image");
- cv::imshow("My image",image);
- cv::waitKey(5000);
- return 1;
- }*/
- //demo 2
- //如果此处加了 using namespace cv,那么则下面不用cv::
- #include <iostream>
- using namespace std;
- int main()
- {
- ///
- //demo1 图像翻转加权重相加
- /
- //cv::Mat image;
- //std::cout<<"size,"<<image.size().height<<","
- // <<image.size().width<<std::endl;
- //image= cv::imread("1.jpg");
- //if(!image.data)
- //{
- // cout<<"image does not exist"<<endl;
- //}
- //cv::namedWindow("Original Image");//定义窗口
- //cv::imshow("Original Image",image);//显示图像
- //cv::Mat result;
- //cv::flip(image,result,1);//整理表示水平翻转,0表示垂直翻转,负数表示既有水平也有垂直翻转
- //cv::namedWindow("Output Image");
- //cv::imshow("Output Image", result);
- //cv::addWeighted(image,0.8,result,0.8,0,image);
- //cv::namedWindow("combine");
- //cv::imshow("combine", image);
- ///
- demo2 暂时只有水平翻转,然后进行动态的合并,第一步先是静态合并
- //
- float x,y;
- cv::Mat image;
- /*std::cout<<"size,"<<image.size().height<<","
- <<image.size().width<<std::endl;*/
- image= cv::imread("1.jpg");
- if(!image.data)
- {
- cout<<"image does not exist"<<endl;
- }
- cv::namedWindow("Original Image");//定义窗口
- cv::imshow("Original Image",image);//显示图像
- cv::Mat result;
- cv::flip(image,result,1);//整理表示水平翻转,0表示垂直翻转,负数表示既有水平也有垂直翻转
- cv::namedWindow("Output Image");
- cv::imshow("Output Image", result);
- /*cv::addWeighted(image,0.8,result,0.8,0,image);
- cv::namedWindow("combine");
- cv::imshow("combine", image);*/
- cout<<"请输入x的位置" "x的位置范围为0到"<<image.cols-1<<endl;
- cin>>x;
- 防止溢出
- /*if((x>=0)&&(x<=image.cols))
- x=x;
- else if(x<0)
- x=0;
- else x=image.cols;*/
- //y=image.rows;
- // 我觉得这个地方的cvcreatemat函数用的不对,应该是创建一个mat,这里创建了cvmat
- //cv::Mat combine=cvCreateMat(3*image.cols,2*image.rows,3);
- //cv::Mat combine=cvCreateMat(2*image.cols,image.rows,CV_32FC1);
- //定义动态combine
- //cv::Mat combine = cv::Mat::zeros(image.rows,2*image.cols,image.type());
- cv::Mat combine = cv::Mat::zeros(image.rows,2*x,image.type());
- // define ROI
- cv::Mat imageROI1= combine(cv::Rect(0,0,x,image.rows));
- cv::Mat imageROI2= combine(cv::Rect(x,0,x,image.rows));
- //DEBUG
- //std::cout<<combine.cols<<" "<<combine.rows<<endl;
- //combine.copyTo(image(x,y,3))
- //cv::Mat combine(image,cv::Rect(0,0,x+1,y));
- //combine(cv::Rect(0,0,image.cols,image.rows)) = image;
- //原来的copy凡是
- //imageROI2=result;
- image(cv::Rect( 0, 0, x, image.rows)).copyTo(imageROI1);
- result(cv::Rect( image.cols-x, 0, x, image.rows)).copyTo(imageROI2);
- //通过看到数值来验证是否是这个地方出错
- //std::cout<<combine(cv::Rect(0, 0, 3, 3))<<std::endl;
- cv::namedWindow("Combined Image");
- cv::imshow("Combined Image", combine);
- cv::waitKey(0);
- //cv::imwrite("2.jpg",result);
- }
- //编程环境:VS2012,Opencv2.4.6
- #include <opencv2/opencv.hpp>
- #include <iostream>
- using namespace cv;
- using namespace std;
- int main(int argc, char* argv[])
- {
- VideoCapture cap1;
- VideoCapture cap2;
- cap1.open(0);
- cap2.open(1);
- if(!cap1.isOpened())
- {
- return -1;
- }
- if(!cap2.isOpened())
- {
- return -2;
- }
- double w = 320, h = 240;
- cap1.set(CV_CAP_PROP_FRAME_WIDTH,w);
- cap1.set(CV_CAP_PROP_FRAME_HEIGHT,h);
- cap2.set(CV_CAP_PROP_FRAME_WIDTH,w);
- cap2.set(CV_CAP_PROP_FRAME_HEIGHT,h);
- Mat frame1,frame2;
- bool stop = false;
- namedWindow("Video1");
- namedWindow("Video2");
- while(!stop)
- {
- cap1>>frame1;
- /*if (frame1.empty())
- {
- return -1;
- }*/
- imshow("Video1",frame1);
- cap2>>frame2;
- /*if (frame2.empty())
- {
- return -2;
- }*/
- imshow("Video2",frame2);
- if(waitKey(30) >=0)
- stop = true;
- }
- return 0;
- }
C 风格代码 OpenCV1 实现,较为鲁棒,环境同上
- #include <opencv2/opencv.hpp>
- using namespace cv;
- int main(int argc, char* argv[])
- {
- CvCapture* capture1 = cvCreateCameraCapture( 0 );
- CvCapture* capture2 = cvCreateCameraCapture( 1 );
- double w = 320, h = 240;
- cvSetCaptureProperty ( capture1, CV_CAP_PROP_FRAME_WIDTH, w );
- cvSetCaptureProperty ( capture1, CV_CAP_PROP_FRAME_HEIGHT, h );
- cvSetCaptureProperty ( capture2, CV_CAP_PROP_FRAME_WIDTH, w );
- cvSetCaptureProperty ( capture2, CV_CAP_PROP_FRAME_HEIGHT, h );
- cvNamedWindow( "Camera_1", CV_WINDOW_AUTOSIZE );
- cvNamedWindow( "Camera_2", CV_WINDOW_AUTOSIZE );
- IplImage* frame1;
- IplImage* frame2;
- while(1)
- {
- frame1 = cvQueryFrame( capture1 );
- //if( !frame1 ) break;
- cvShowImage( "Camera_1", frame1 );
- frame2 = cvQueryFrame( capture2 );
- //if( !frame2 ) break;
- cvShowImage( "Camera_2", frame2 );
- int key = cvWaitKey(30);
- if( key == 27 ) break;
- }
- cvReleaseCapture( &capture1 );
- cvReleaseCapture( &capture2 );
- cvDestroyWindow( "Camera_1" );
- cvDestroyWindow( "Camera_2" );
- return 0;
- }