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 的第六篇文章,其实也没那么难,感觉是不是还是很好入门的,那就继续。初见成效,继续努力。皇天不负有心人,不忘初心,继续努力,做自己喜欢做的,开心就好。

相关推荐
在路上看风景2 小时前
19. 成员初始化列表和初始化对象
c++
zmzb01032 小时前
C++课后习题训练记录Day98
开发语言·c++
念风零壹2 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
智驱力人工智能3 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥3 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
sali-tec4 小时前
C# 基于OpenCv的视觉工作流-章22-Harris角点
图像处理·人工智能·opencv·算法·计算机视觉
MZ_ZXD0015 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
A星空1236 小时前
一、Linux嵌入式的I2C驱动开发
linux·c++·驱动开发·i2c
光羽隹衡6 小时前
计算机视觉——Opencv(图像拼接)
人工智能·opencv·计算机视觉
凡人叶枫6 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发