OpenCV C++案例实战二《生成蒙太奇图像》

OpenCV C++案例实战二《生成蒙太奇图像》

前言

本文将使用OpenCV C++ 生成蒙太奇图像。

一、输入模板图像

请添加图片描述
原图如图所示。我们将对此图生成蒙太奇图像。

	Mat src = imread("Taylor.jpg");
	if (src.empty())
	{
		cout << "No image!" << endl;
		system("pause");
		return 0;
	}

 
 
    	resize(src, src, Size(step_x*30, step_y*30), 1, 1, INTER_CUBIC);
    
     
     

      这里的step_x,step_y表示素材图像尺寸。我们要把模板图像resize成 Size(step_x 30, step_y*30)尺寸,将模板图像分割成30x30个block,即使用30x30张素材图像来生成我们的蒙太奇图像。

      二、读取素材图像

      请添加图片描述所有素材图像。

      //获取文件夹下所有图像路径
      int getImagePathList(string folder, vector<String> &imagePathList)
      {
      	glob(folder, imagePathList);
      	return 0;
      }
      
       
       

        我们定义getImagePathList函数获取文件夹下所有图像的路径。

        	vector<Mat>images;
        	string filename = "images/";
        	cout << "loading..." << endl;
        

        vector<String> imagePathList;
        getImagePathList(filename, imagePathList);

        for (int i = 0; i < imagePathList.size(); i++)
        {
        Mat img = cv::imread(imagePathList[i]);

        resize(img, img, Size(step_x, step_y), 1, 1, INTER_AREA);

        images.push_back(img);

        }
        cout << “done!” << endl;

          我们将读取进来的所有素材图像都resize成 Size(step_x, step_y)大小,并把它们都push_back到images容器内,以便后续使用。

          三、生成蒙太奇模板

          	int rows = src.rows;
          	int cols = src.cols;
          	//height:表示生成的蒙太奇图像需要多少张素材图像填充rows
          	//width:表示生成的蒙太奇图像需要多少张素材图像填充cols
          	int height = rows / step_y, width = cols / step_x;
          

          Mat dst = Mat(src.size(), CV_8UC3, Scalar(255, 255, 255));
          for (int i = 0; i < height; ++i)
          {
          for (int j = 0; j < width; ++j)
          {
          //index表示当前素材图像的索引
          int index = i * width + j;

          //将图像赋值给需要生成的蒙太奇图像对应区域
          images[index].copyTo(dst(Rect(j step_x, i step_y, step_x, step_y)));
          }
          }

          imshow(“dst”, dst);

            通过两个for循环就可以遍历到每个蒙版区域。这个类似于遍历图像的所有像素,只不过我们把步长加大了而已。整个代码的核心就是以下这句。

            			//将图像赋值给需要生成的蒙太奇图像对应区域
            			images[index].copyTo(dst(Rect(j * step_x, i * step_y, step_x, step_y)));	
            
             
             

              请添加图片描述
              将所有的素材图像copy到指定区域就可以生成蒙版图像啦。接下来我们就得对这个蒙版图像做像素处理了。

              四、生成蒙太奇图像

              	for (int i = 0; i < rows; ++i)
              	{
              		for (int j = 0; j < cols; ++j)
              		{
              			//像素RGB值修改
              			dst.at<Vec3b>(i, j)[0] = 0.312*dst.at<Vec3b>(i, j)[0] + 0.698*src.at<Vec3b>(i, j)[0];
              			dst.at<Vec3b>(i, j)[1] = 0.312*dst.at<Vec3b>(i, j)[1] + 0.698*src.at<Vec3b>(i, j)[1];
              			dst.at<Vec3b>(i, j)[2] = 0.312*dst.at<Vec3b>(i, j)[2] + 0.698*src.at<Vec3b>(i, j)[2];
              }
              }
              

              imshow(“蒙太奇图像”, dst);

                我们通过遍历模板图像所有像素,并改变它们的权值,就可以得到蒙太奇图像啦。
                请添加图片描述
                这就是我们生成的蒙太奇图像

                五、源码

                #include <iostream>
                #include<opencv2/opencv.hpp>
                using namespace std;
                using namespace cv;
                

                //素材图像尺寸
                const int step_x = 20;
                const int step_y = 20;

                //获取文件夹下所有图像路径
                int getImagePathList(string folder, vector<String> &imagePathList)
                {
                glob(folder, imagePathList);
                return 0;
                }

                int main()
                {
                Mat src = imread(“Taylor.jpg”);
                if (src.empty())
                {
                cout << “No image!” << endl;
                system(“pause”);
                return 0;
                }

                resize(src, src, Size(step_x30, step_y30), 1, 1, INTER_CUBIC);

                vector<Mat>images;
                string filename = “images/”;
                cout << “loading…” << endl;

                vector<String> imagePathList;
                getImagePathList(filename, imagePathList);

                for (int i = 0; i < imagePathList.size(); i++)
                {
                Mat img = cv::imread(imagePathList[i]);

                resize(img, img, Size(step_x, step_y), 1, 1, INTER_AREA);

                images.push_back(img);

                }
                cout << “done!” << endl;

                int rows = src.rows;
                int cols = src.cols;
                //height:表示生成的蒙太奇图像需要多少张素材图像填充rows
                //width:表示生成的蒙太奇图像需要多少张素材图像填充cols
                int height = rows / step_y, width = cols / step_x;

                Mat dst = Mat(src.size(), CV_8UC3, Scalar(255, 255, 255));
                for (int i = 0; i < height; ++i)
                {
                for (int j = 0; j < width; ++j)
                {
                //index表示当前素材图像的索引
                int index = i * width + j;

                //将图像赋值给需要生成的蒙太奇图像对应区域
                images[index].copyTo(dst(Rect(j step_x, i step_y, step_x, step_y)));
                }
                }

                imshow(“dst”, dst);

                for (int i = 0; i < rows; ++i)
                {
                for (int j = 0; j < cols; ++j)
                {
                //像素RGB值修改
                dst.at<Vec3b>(i, j)[0] = 0.312dst.at<Vec3b>(i, j)[0] + 0.698src.at<Vec3b>(i, j)[0];
                dst.at<Vec3b>(i, j)[1] = 0.312dst.at<Vec3b>(i, j)[1] + 0.698src.at<Vec3b>(i, j)[1];
                dst.at<Vec3b>(i, j)[2] = 0.312dst.at<Vec3b>(i, j)[2] + 0.698src.at<Vec3b>(i, j)[2];
                }
                }

                imshow(“蒙太奇图像”, dst);
                waitKey(0);
                system(“pause”);
                return 0;
                }

                  总结

                  本文使用OpenCV C++生成蒙太奇图像,关键步骤有以下几点。
                  1、将你需要生成的蒙太奇图像模板resize成合适大小,使其恰好能够被素材图像填充。
                  2、载入素材图像。
                  3、使用素材图像去填充蒙版图。核心就是上面的两个for循环。
                  4、将蒙版与模板图像进行融合,改变其像素权值就可以生成蒙太奇图像了。

                  评论
                  添加红包

                  请填写红包祝福语或标题

                  红包个数最小为10个

                  红包金额最低5元

                  当前余额3.43前往充值 >
                  需支付:10.00
                  成就一亿技术人!
                  领取后你会自动成为博主和红包主的粉丝 规则
                  hope_wisdom
                  发出的红包
                  实付
                  使用余额支付
                  点击重新获取
                  扫码支付
                  钱包余额 0

                  抵扣说明:

                  1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                  2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                  余额充值