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:表示生成的蒙太奇图像需要多少张素材图像填充colsint 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_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:表示生成的蒙太奇图像需要多少张素材图像填充colsint 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.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、将蒙版与模板图像进行融合,改变其像素权值就可以生成蒙太奇图像了。

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

  1. OpenCV C++案例实战二十九《遥感图像分割》

    OpenCV C++案例实战二十九<遥感图像分割> 前言 一.准备数据 二.K-Means分类 三.效果显示 四.源码 总结 前言 本案例基于k-means机器学习算法进行遥感图像分割.主 ...

  2. OpenCV C++案例实战二十二《手势识别》

    OpenCV C++案例实战二十二<手势识别> 前言 一.手部关键点检测 1.1 功能源码 1.2 功能效果 二.手势识别 2.1算法原理 2.2功能源码 三.结果显示 3.1功能源码 3 ...

  3. OpenCV C++案例实战二十七《角度测量》

    OpenCV C++案例实战二十七<角度测量> 前言 一.鼠标响应事件 1.1功能源码 1.2功能效果 二.计算直线角度 2.1 计算直线斜率 2.2计算直线角度 2.3功能源码 三.绘制 ...

  4. OpenCV C++案例实战二十一《制作视频播放器》

    OpenCV C++案例实战二十一<制作视频播放器> 前言 一.源码 二.效果 总结 前言 本文将使用OpenCV C++ 制作简易视频播放器,用于实现视频播放基本功能. 1.通过创建滑动 ...

  5. OpenCV C++案例实战十二《图像全景拼接》

    OpenCV C++案例实战十二<图像全景拼接> 前言 一.OpenCV Stitcher 1.功能源码 2.效果 二.图像全景拼接 1.特征检测 2.计算单应性矩阵 3.透视变换 4.图 ...

  6. OpenCV C++案例实战十六《制作哈哈镜图像》

    OpenCV C++案例实战十六<制作哈哈镜图像> 前言 一.凸透镜 1.功能源码 2.效果显示 二.凹透镜 1.功能源码 2.效果显示 三.源码 总结 前言 本文将使用OpenCV C+ ...

  7. OpenCV C++案例实战三《二维码检测》

    OpenCV C++案例实战三<二维码检测> 前言 一.二维码检测 二.二维码识别 1.通过findContours找到轮廓层级关系 三.二维码绘制 四.源码 总结 前言 本文将使用Ope ...

  8. OpenCV C++案例实战三十二《字符识别》

    OpenCV C++案例实战三十二<字符识别> 前言 一.结果演示 二.制作数据集 三.字符识别 四.源码 总结 前言 本案例将使用OpenCV C++ 进行字符识别.主要包括制作数据集. ...

  9. OpenCV C++案例实战十八《抖音特效——“蓝线挑战”》

    OpenCV C++案例实战十八<抖音特效--"蓝线挑战"> 前言 一.图像扫描 二.生成定格图像 三.图像混合 四.效果显示 五.源码 总结 前言 本文将使用Open ...

最新文章

  1. CMPB 2021|U-Net:又一魔改U-Net应用于腹部肝脏分割任务!
  2. java break的用法_Java基础break、continue语句的用法
  3. C#趣味程序---真分数序列
  4. 将Jersey与Spring整合
  5. 【渝粤题库】陕西师范大学201001 教育管理学(高起本)作业
  6. BP神经网络反向传播手动推导
  7. 华语乐坛趋势报告(2022)
  8. 【AI视野·今日CV 计算机视觉论文速览 第216期】Wed, 9 Jun 2021
  9. ARM处理器与架构对应关系
  10. 连载三:RobotFramework+Selenium+Jenkins分布式构建
  11. Spring boot 集成mybatis 教程
  12. ext2.0中EditorGridPanel (8)
  13. 161张Menhera酱表情包 无水印汉化版
  14. CSS 布局案例:不会还有人不会布局吧
  15. 香港流行乐黄金二十年——经典歌手(音乐人)全面回顾 二
  16. Winform中datagridview显示数据时,不显示特殊符号,如下划线不显示问题
  17. php微信绑定银行卡_微信开发企业支付到银行卡PHP
  18. iPhone破解相关知识
  19. iOS15绕过激活锁,屏幕锁界面完美隐藏工具TiggerRamDisk3.7,支持最新iOS15.5系统
  20. 信号地和电源地的区别

热门文章

  1. ssm + redis
  2. HDCP @HMAC-SHA256[基于mbedtls]
  3. CSS实现核辐射警告标志
  4. js  计算是今天多少周
  5. 微信公众平台如何给粉丝分组打标签?
  6. 计算机网络中tx和fx,100Base-TX/T4/FX以太网含义及用法
  7. 系统防火墙阻止了加密狗服务器,批处理利用Windows防火墙阻止程序和服务联网!...
  8. 在C语言程序中 main函数的位置,在C语言程序中,main函数的位置是________。
  9. Outlook使用RTF格式发信出现Winmail.dat附件事宜
  10. 基于BLG7289的数码管显示