C++之OpenCV入门到提高006:图像混合

一、介绍
    今天是这个系列《C++之 Opencv 入门到提高》的第六篇文章。这篇文章也不难,介绍如何图像的混合操作。图像本质上也是数据,既然是数据,我们就可以针对两张或者多张图片进行加、减、乘、除的操作,这些操作太生硬了,这种混和并不是我们想要的,针对混合有专门的接口实现,我们可以对比一下之间的差异。这都是基础,为以后的学习做好铺垫。虽然操作很简单,但是背后有很多东西需要我们深究,才能做到知其然知其所以然。OpenCV 具体的简介内容,我就不多说了,网上很多,大家可以自行脑补。
    OpenCV 的官网地址:https://opencv.org/,组件下载地址:https://opencv.org/releases/
    OpenCV 官网学习网站:https://docs.opencv.ac.cn/4.10.0/index.html

我需要进行说明,以防大家不清楚,具体情况我已经罗列出来。
        操作系统:Windows Professional 10(64位)
        开发组件:OpenCV -- 4.10.0
        开发工具:Microsoft Visual Studio Community 2022 (64 位) - Current版本 17.8.3
        开发语言:C++(VC16)

二、知识学习
    接口很简单,不用多说,仔细研究一下原理更有用。

复制代码
 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 #include <math.h>
 4 
 5 using namespace std;
 6 using namespace cv;
 7 
 8 /// <summary>
 9 /// 图像混合
10 /// 1、理论介绍
11 /// 2、相关API(addWeighted)
12 /// </summary>
13 /// <returns></returns>
14 int main6()
15 {
16     //1、理论介绍
17     //线性混合操作:g(x)=(1-a)f0(x)+af1(x)    其中 a 的取值范围 0-1 之间。
18     // f0(x) 表示第一幅输入图像,f1(x) 表示第二幅输入图像,a 表示权重,表示第一幅图占的权重,或者是第二幅图占的权重,g(x)表示生成后的图像。
19     // Mat 图像是一个二维矩阵,就是具有行和列的数据数组,如果我们针对两张图片的每个像素点进行上述操作,最后就会得到混合后的图像。
20 
21     //2、void addWeighted(InputArray src1, double alpha, InputArray src2,double beta, double gamma, OutputArray dst, int dtype = -1)
22     /*
23         函数 addWeighted 计算两个数组的加权和,如下所示:
24     \f[\texttt{ dst } (I) = \texttt{ saturate } (\texttt{ src1 } (I) * \texttt{ alpha } + \texttt{ src2 } (I) * \texttt{ beta } + \texttt{ gamma })\f]
25         其中 I 是数组元素的多维索引。对于多通道数组,每个通道都是独立处理的。
26         该函数可以替换为矩阵表达式:dst = src1*alpha + src2*beta + gamma;
27 
28             @note Saturation is not applied when the output array has the depth CV_32S.You may even get
29             result of an incorrect sign in the case of overflow.
30             @param src1 第一张输入的图像数组.
31             @param alpha 第一张输入图像的 alpha 值.
32             @param src2 第二个输入图像数组的大小和通道号与 src1 相同。
33             @param beta 第二个输入图像的 alpha 权重。
34             @param gamma 添加到每个 sum 的标量。
35             @param dst 输出图像数组,该数组具有与 Input 图像数组相同的大小和通道数.
36             @param dtype 输出图像的可选深度:当两个输入图像具有相同的深度时,可以将 dtype 设置为-1,这相当于src1.depth()。
37             @sa  add, subtract, scaleAdd, Mat::convertTo
38             */
39 
40 
41     //注意:图像大小和类型必须一致。
42     Mat src1,src2;
43     src1 = imread("D:\\360MoveData\\Users\\Administrator\\Desktop\\TestImage\\guanyu.jpg",IMREAD_COLOR);
44     src2 = imread("D:\\360MoveData\\Users\\Administrator\\Desktop\\TestImage\\guanyu2.jpg", IMREAD_COLOR);
45     if (src1.empty())
46     {
47         cout << "图像1加载失败!!!" << endl;
48         return -1;
49     }
50     if (!src2.data)
51     {
52         cout << "图像2加载失败!!!" << endl;
53         return -1;
54     }
55 
56     if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type())
57     {
58         Mat dst = Mat::zeros(src1.size(),src1.type());
59         double alpha = 0.1;
60         addWeighted(src1, alpha, src2, (1 - alpha), 0, dst);
61         //add(src1, src2, dst);
62         //multiply(src1, src2, dst);
63 
64         imshow("原图1", src1);
65         imshow("原图2", src2);
66         namedWindow("混合窗口", WINDOW_AUTOSIZE);
67         imshow("混合窗口", dst);
68     }
69     else
70     {
71         cout << "图像1和图像2不同!!!" << endl;
72     }
73 
74     waitKey(0);
75 
76     return 0;
77 }

图像混合的效果:

原图1:

原图2:

混合图:

仔细看背景,是有另外一张图的。

图像相加的效果:

图像相乘的效果:

没法看了,太亮了,相乘的结果就是接近255最大值,也就是接近白色了。

三、总结
    这是 C++ 使用 OpenCV 的第六篇文章,其实也没那么难,感觉是不是还是很好入门的,那就继续。初见成效,继续努力。皇天不负有心人,不忘初心,继续努力,做自己喜欢做的,开心就好。

相关推荐
小王爱吃月亮糖26 分钟前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
小哈龙2 小时前
c++ 类似与c# 线程 AutoResetEvent 和 ManualResetEvent的实现
c++·c#·多线程
yuanbenshidiaos3 小时前
C++--------------树
java·数据库·c++
海螺姑娘的小魏3 小时前
Effective C++ 条款 15:在资源管理类中提供对原始资源的访问
开发语言·c++
青青丘比特5 小时前
STL.string(下)
开发语言·c++
jjjxxxhhh1235 小时前
C++ 模板是为了解决啥问题
开发语言·c++·算法
c++初学者ABC5 小时前
GESP2级2403 小杨的日字矩阵
c++·算法
代码小将6 小时前
PTA数据结构编程题7-1最大子列和问题
数据结构·c++·笔记·学习·算法
HackKong6 小时前
高校网络安全_网络安全之道
java·网络·c++·python·学习·web安全·黑客技术
BUG制造机.6 小时前
修炼之道 ---其四
linux·c++