【OpenCV C++20 学习笔记】图片融合
创始人
2024-11-18 22:37:43
0

图片融合

  • 原理
  • 实现
  • 结果展示
  • 完整代码

原理

关于OpenCV的配置和基础用法,请参阅本专栏的其他文章:垚武田的OpenCV合集

这里采用的图片熔合的算法来自Richard Szeliski的书《Computer Vision: Algorithms and Applications》(《计算机视觉:算法和应用》)。
该算法使用了一个两参的线性熔合算子来操作图片的像素:
g ( x ) = ( 1 − α ) f 0 ( x ) + α f 1 ( x ) g(x) = (1-\alpha)f_0(x)+\alpha f_1(x) g(x)=(1−α)f0​(x)+αf1​(x)
α \alpha α的值从0-1不等。利用这个 α \alpha α值,该算法可以对两个图片或者视频执行一个临时的交叉溶解(criss-dissolve),就像在幻灯片或胶片中那样(很酷是不是?)cool, eh?

实现

在OpenCV中使用addWeighted()函数来实现上述的线性熔合的方法。
首先导入要熔合的两张图片。这两张图片是OpenCV库中自带的,可以在安装目录的子路径...\opencv\sources\samples\data中找到它们:LinuxLogo.jpgWindowsLogo.jpg。将它们复制进项目文件夹,导入语句如下:

Mat src1 { imread("LinuxLogo.jpg") }; Mat src2 { imread("WindowsLogo.jpg") }; 

注意:被熔合的两张图片必须大小(长和宽)一致,类型也必须一致
接着确定 α \alpha α值,并使用线性熔合算法:

double alpha{ 0.5 }; double beta{ 1.0 - alpha }; Mat dst; addWeighted( src1, alpha, src2, beta, 0.0, dst); 

这里将 α \alpha α设为0.5; β \beta β其实是算法中的 1 − α 1- \alpha 1−α。这里再回到算法公式:
g ( x ) = ( 1 − α ) f 0 ( x ) + α f 1 ( x ) g(x) = (1-\alpha)f_0(x)+\alpha f_1(x) g(x)=(1−α)f0​(x)+αf1​(x)

  • 两张图片中的每个像素值,分别就是公式中的 f 0 ( x ) f_0(x) f0​(x)和 f 1 ( x ) f_1(x) f1​(x)
  • g ( x ) g(x) g(x)就是熔合后的像素值
  • 1 − α 1- \alpha 1−α(即代码中的 β \beta β)和 α \alpha α分别是两张图片的权重

然后我们来看一下在addWeighted()函数中,是怎样用各个参数来确定线性熔合算法的——
addWeighted( src1, alpha, src2, beta, 0.0, dst);

  • src1src2分别是要熔合的两张图片的Mat对象
  • alpha是公式中的 α \alpha α,即src1所代表的图片的权重
  • beta是公式中的 1 − α 1- \alpha 1−α,即src2所代表的图片的权重
  • 0.0是公式中没有的一个常数 γ \gamma γ,用来对熔合后的像素值进行偏移
  • dst为储存熔合结果的Mat对象
    这样,addWeighted()函数的实际算法可以用以下公式表示:
    d s t = α ∗ s r c 1 + β ∗ s r c 2 + γ dst = \alpha *src1 + \beta *src2 + \gamma dst=α∗src1+β∗src2+γ
    代码中的 γ \gamma γ为0.0,说明不对熔合后的像素进行任何偏移。

结果展示

创建窗口,展示图片熔合的结果

imshow("线性熔合", dst); waitKey(0); 

输出结果如下:
线性熔合结果

完整代码

注意:

  • 因为C++中也有std::beta,所以为了避免名称冲突,这里没有使用整个std命名空间
  • 完整代码需要用户自己输入 α \alpha α参数的值
  • 完整代码对图片的导入进行了检测
#include  #include  #include   import ;  using namespace cv;  //因为C++中有std::beta,为了避免名称冲突,这里没有使用整个std命名空间 using std::cin; using std::cout; using std::endl;  int main() { 	double alpha{ 0.5 }; double beta, input;  	Mat src1, src2, dst;  	cout << "简单线性混合" << endl; 	cout << "-----------" << endl; 	cout << "* 输入α值 [0.0-1.0]"; 	cin >> input;  	if (input >= 0 && input <= 1) 		alpha = input;  	src1 = imread("LinuxLogo.jpg"); 	src2 = imread("WindowsLogo.jpg");  	if (src1.empty()) { 		cout << "图片1导入错误" << endl; 		return EXIT_FAILURE; 	} 	if (src2.empty()) { 		cout << "图片2导入错误" << endl; 		return EXIT_FAILURE; 	}  	beta = 1.0 - alpha; 	addWeighted(src1, alpha, src2, beta, 0.0, dst);  	imshow("线性混合", dst); 	waitKey(0);  	return 0; }  

相关内容

热门资讯

invincea是什么 Invincea是一个网络安全公司,专注于提供先进的威胁检测和响应解决方案,以保护企业免受网络攻击和...
淘宝幻想岛总动员怎么退队-20... 在淘宝幻想岛总动员活动中,如需退队,请先确保活动未结束。通常可在活动页面找到“退出队伍”按钮,点击后...
video是什么? video是视频的英文单词,指的是一种通过连续播放一系列静止图像来模拟运动和声音的媒体形式。Vide...
大话西游2手机版官网 大话西游2手机版官网是网易公司推出的一款以西游记为背景的角色扮演游戏,玩家可以在游戏中体验到丰富的剧...
eternalblue是什么 InternalBlue是一种颜色名称,通常用于描述一种深蓝色或海军蓝。它可能在不同的上下文中有不同...
米侠浏览器怎么创建脚本-新建脚... 米侠浏览器创建脚本的步骤如下:打开米侠浏览器,点击菜单栏中的“工具”选项,选择“新建脚本”,在弹出的...
王者荣耀 甄姬 连招 甄姬连招:1技能控制,2技能减速,3技能爆发。先用1技能命中敌人,然后迅速接2技能减速,最后用3技能...
1、hadoop环境搭建 1、环境配置ip(/etc/sysconfig/network-scripts) # 网卡1 DEV...
kwservice.exe是什... kwservice.exe是科大讯飞输入法的一个后台程序,用于支持输入法的正常运行和相关服务。KwS...
cobaltstrike什么软... Cobalt Strike是一款基于Java的渗透测试工具,主要用于模拟高级持续性威胁(APT)攻击...