C++ OpenCV生成蒙太奇图像的示例详解

目录
  • 前言
  • 一、输入模板图像
  • 二、读取素材图像
  • 三、生成蒙太奇模板
  • 四、生成蒙太奇图像
  • 五、源码
  • 总结

前言

本文将使用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 temp;
	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;

			//将当前素材图像拷贝到temp零时变量
			images[index].copyTo(temp);

			//将temp图像赋值给需要生成的蒙太奇图像对应区域
			temp = dst(Rect(j * step_x, i * step_y, step_x, step_y));
		}
	}

	imshow("dst", dst);

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

	//将当前素材图像拷贝到temp零时变量
	images[index].copyTo(temp);

	//将temp图像赋值给需要生成的蒙太奇图像对应区域
	temp = 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_x*30, step_y*30), 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 temp;
	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;

			//将当前素材图像拷贝到temp零时变量
			images[index].copyTo(temp);

			//将temp图像赋值给需要生成的蒙太奇图像对应区域
			temp = 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.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);
	waitKey(0);
	system("pause");
	return 0;
}

总结

本文使用OpenCV C++生成蒙太奇图像,关键步骤有以下几点。

1、将你需要生成的蒙太奇图像模板resize成合适大小,使其恰好能够被素材图像填充。

2、载入素材图像。

3、使用素材图像去填充蒙版图。核心就是上面的两个for循环。

4、将蒙版与模板图像进行融合,改变其像素权值就可以生成蒙太奇图像了。

本文使用较为简单,也比较容易理解的程序生成蒙太奇图像。网上也有许多是使用直方图匹配——将模板图像分割成不等分区域,然后使用素材库中的图像与这些区域一一进行直方图匹配,找到最匹配的那张图像填充该区域。有兴趣的小伙伴可以尝试一下这种方法!!

以上就是C++ OpenCV生成蒙太奇图像的示例详解的详细内容,更多关于C++ OpenCV蒙太奇图像的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++ OpenCV实现图像修复功能

    目录 前言 一.OpenCV inpaint 二.源码 三.效果显示 前言 本文将使用OpenCV C++ 对有瑕疵的图像进行修复.OpenCV 提供了inpaint API可进行图像修复. 一.OpenCV inpaint 原图如图所示.本案例的需求是希望能够将图像上的红线给消除.OpenCV 提供的inpaint API能够实现这个效果. void inpaint( InputArray src, 原图 InputArray inpaintMask, 二进制掩模,指示要修复的像素 Outpu

  • C++ OpenCV实战之制作九宫格图像

    目录 前言 一.九宫格图像 二.源码 三.效果显示 总结 前言 本文将使用OpenCV C++ 制作九宫格图像.其实原理很简单,就是将一张图像均等分成九份.然后将这九个小块按一定间隔(九宫格效果)拷贝到新画布上就可以啦. 一.九宫格图像 原图如图所示.本案例的需求是希望将图像均等分成九份,制作九宫格图像.首先得将原图均等分成九份. 如图所示.将原图均等分成九份,然后将这每一个小方块按照一定的间隔(九宫格效果)拷贝到新图像就可以了.具体算法思想请看源码注释. 二.源码 #include<iostr

  • C++ OpenCV实战之图像全景拼接

    目录 前言 一.OpenCV Stitcher 1.功能源码 2.效果 二.图像全景拼接 1.特征检测 2.计算单应性矩阵 3.透视变换 4.图像拼接 5.功能源码 6.效果 三.源码 总结 前言 本文将使用OpenCV C++ 进行图像全景拼接.目前使用OpenCV对两幅图像进行拼接大致可以分为两类. 一.使用OpenCV内置API Stitcher 进行拼接. 二.使用特征检测算法匹配两幅图中相似的点.计算变换矩阵.最后对其进行透视变换就可以了. 一.OpenCV Stitcher imag

  • C++ OpenCV实战之图像透视矫正

    目录 前言 一.图像预处理 二.轮廓提取 1.提取最外轮廓 2.提取矩形四个角点 3.将矩形角点排序 三.透视矫正 四.源码 前言 本文将使用OpenCV C++ 进行图像透视矫正. 一.图像预处理 原图如图所示.首先进行图像预处理.将图像进行灰度.滤波.二值化.形态学等操作,目的是为了下面的轮廓提取.在这里我还使用了形态学开.闭操作,目的是使整个二值图像连在一起.大家在做图像预处理时,可以根据图像特征自行处理. Mat gray; cvtColor(src, gray, COLOR_BGR2G

  • C++之OpenCV图像高光调整具体流程

    实现原理 PS中的高光命令是一种校正由于太接近相机闪光灯而有些发白的焦点的方法.在用其他方式采光的图像中,这种调整也可用于使高光区域变暗.要实现图像的高光调整,首先要识别出高光区:再通过对高光区的色彩进行一定变换,使其达到提光或者暗化效果:最后也是最重要的,就是对高光区和非高光区的边缘作平滑处理. 下方介绍具体流程. 具体流程 1)读取识别图像的原图,并转灰度图,再归一化. // 生成灰度图 cv::Mat gray = cv::Mat::zeros(input.size(), CV_32FC1

  • C++ OpenCV制作哈哈镜图像效果

    目录 前言 一.凸透镜 1.功能源码 2.效果显示 二.凹透镜 1.功能源码 2.效果显示 三.源码 前言 本文将使用OpenCV C++ 制作哈哈镜图像.其实原理很简单,就是让图像像素扭曲,将像素重新进行映射. 一.凸透镜 制作凸透镜效果(将图像放大).根据网上查找的变换公式: 图像放大:凸透镜 x = (dx / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cx; y = (dy / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) /

  • C++ OpenCV生成蒙太奇图像的示例详解

    目录 前言 一.输入模板图像 二.读取素材图像 三.生成蒙太奇模板 四.生成蒙太奇图像 五.源码 总结 前言 本文将使用OpenCV C++ 生成蒙太奇图像. 一.输入模板图像 原图如图所示.我们将对此图生成蒙太奇图像. Mat src = imread("Taylor.jpg"); if (src.empty()) { cout << "No image!" << endl; system("pause"); retur

  • C++ OpenCV实现物体尺寸测量示例详解

    目录 前言 一.图像透视矫正 二.物体定位 三.尺寸测量 四.效果显示 五.源码 总结 前言 本文将使用OpenCV C++ 进行物体尺寸测量.具体来说就是先定位到待测物体的位置,然后测量物体的宽高. 一.图像透视矫正 原图如图所示.本案例的需求是测量图片中两张卡片的尺寸.首先,我们得定位到两张卡片的位置.第一步,我们首先得将白色A4纸切割出来,这样方便定位到两张卡片所在位置.这里用到的算法是图像透视矫正,具体可以参考OpenCV C++案例实战四<图像透视矫正> //图像矫正 void ge

  • Python+Matplotlib绘制3D图像的示例详解

    目录 1. 绘制3D柱状图 2. 绘制3D曲面图 示例1 示例2 3.绘制3D散点图 4. 绘制3D曲线图 1. 绘制3D柱状图 绘制3D柱状图使用的是axes3d.bar()方法. 可能跟我们中学学的有一点不同的是,其语法如下: bar(left, height, zs=0, zdir=‘z’, *args, **kwargs) 其中left表示指向侧边的轴,zs表示指向我们的方向的轴,height即表示高度的轴.这三者都需要是一维的序列对象.在调用相关方法的时候,比如设置轴标签,还有一点需要

  • C#生成EMF矢量图形文件示例详解

    目录 前言 原因 实现 绘制位置错误 结论 前言 公众号上有网友询问我如何生成 EMF 文件的问题: 本以为非常简单,我快速给出了解决方案: var bitmap = new Bitmap(640, 480); var g = Graphics.FromImage(bitmap); g.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 100, 100); bitmap.Save("

  • Python OpenCV图像处理之图像滤波特效详解

    目录 1分类 2邻域滤波 2.1线性滤波 2.2非线性滤波 3频域滤波 3.1低通滤波 3.2高通滤波 1 分类 图像滤波按图像域可分为两种类型: 邻域滤波(Spatial Domain Filter),其本质是数字窗口上的数学运算.一般用于图像平滑.图像锐化.特征提取(如纹理测量.边缘检测)等,邻域滤波使用邻域算子——利用给定像素周围像素值以决定此像素最终输出的一种算子 频域滤波(Frequency Domain Filter),其本质是对像素频率的修改.一般用于降噪.重采样.图像压缩等. 按

  • 详解Python中生成随机数据的示例详解

    目录 随机性有多随机 加密安全性 PRNG random 模块 数组 numpy.random 相关数据的生成 random模块与NumPy对照表 CSPRNG 尽可能随机 os.urandom() secrets 最佳保存方式 UUID 工程随机性的比较 在日常工作编程中存在着各种随机事件,同样在编程中生成随机数字的时候也是一样,随机有多随机呢?在涉及信息安全的情况下,它是最重要的问题之一.每当在 Python 中生成随机数据.字符串或数字时,最好至少大致了解这些数据是如何生成的. 用于在 P

  • OpenCV学习之图像梯度算子详解

    目录 1.Sobel算子 2.Scharr算子 3.laplacian算子 本文是OpenCV图像视觉入门之路的第12篇文章,本文详细的介绍了图像梯度算子的各种操作,例如:Sobel算子Scharr算子laplacian算子等操作. 1.Sobel算子 Sobel算子是一种图像边缘检测算子,它是一种空间滤波器,可以检测图像中的边缘,而梯度运算是一种求导数的方法,可以用来检测图像中的局部变化. import cv2 import numpy as np from numpy import unic

  • OpenCV学习之图像形态学处理详解

    目录 1.腐蚀操作 2.膨胀操作 3.开闭运算 4.梯度运算 5.Top Hat Black Hat运算 本文是OpenCV图像视觉入门之路的第11篇文章,本文详细的在图像形态学进行了图像处理,例如:腐蚀操作.膨胀操作.开闭运算.梯度运算.Top Hat Black Hat运算等操作. 1.腐蚀操作 从下面代码中可以看到有三幅腐蚀程度不同的图,腐蚀越严重像素就越模糊 import cv2 import numpy as np from numpy import unicode if __name

  • Python+OpenCV人脸检测原理及示例详解

    关于opencv OpenCV 是 Intel 开源计算机视觉库 (Computer Version) .它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. OpenCV 拥有包括 300 多个 C 函数的跨平台的中.高层 API .它不依赖于其它的外部库 -- 尽管也可以使用某些外部库. OpenCV 对非商业应用和商业应用都是免费 的.同时 OpenCV 提供了对硬件的访问,可以直接访问摄像头,并且 opencv 还提供了一个简单的 GUI(graph

  • OpenCV实现相机标定示例详解

    目录 环境准备 相机标定 棋盘格图片 实时显示相机的画面 在线标定 实时显示相机画面,按键保存能检测到角点的 棋盘格图片 离线标定 畸变矫正 环境准备 vs2015+opencv4.10安装与配置 相机标定 棋盘格图片 可以自己生成,然后打印到A4纸上.(也可以去TB买一块,平价买亚克力板的,不反光买氧化铝材质,高精度买陶瓷的) /** * 生成棋盘格图片 **/ int generateCalibrationPicture() { //Mat frame = imread("3A4.bmp&q

随机推荐