使用 OpenCV 添加(混合)两个图像

返回:OpenCV系列文章目录(持续更新中......)

上一篇:OpenCV4.9的是如何进行图像操作

下一篇:

引言:

我们将学习如何混合两个图像!

目标

在本教程中,您将学习:

  • 什么是线性混合以及它为什么有用;
  • 如何使用 **addWeighted()**添加两张图片

理论

注意

下面的解释属于 Richard Szeliski 的《计算机视觉:算法和应用》一书

从我们之前的教程中,我们已经了解了一些 Pixel 运算符 。一个有趣的二元(双输入)运算符是线性混合运算符

通过参数x从0到 1,该运算符可用于在两个图像或视频之间执行时间交叉溶解,如幻灯片和电影制作中所示(很酷,嗯)

源代码

这里下载源代码。

C++:

cpp 复制代码
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream> 
using namespace cv; 
// we're NOT "using namespace std;" here, to avoid collisions between the beta variable and std::beta in c++17
using std::cin;
using std::cout;
using std::endl; 
int main( void )
{
 double alpha = 0.5; double beta; double input; 
 Mat src1, src2, dst; 
 cout << " Simple Linear Blender " << endl;
 cout << "-----------------------" << endl;
 cout << "* Enter alpha [0.0-1.0]: ";
 cin >> input; 
 // We use the alpha provided by the user if it is between 0 and 1
 if( input >= 0 && input <= 1 )
 { alpha = input; } 
 src1 = imread( samples::findFile("LinuxLogo.jpg") );
 src2 = imread( samples::findFile("WindowsLogo.jpg") ); 
 if( src1.empty() ) { cout << "Error loading src1" << endl; return EXIT_FAILURE; }
 if( src2.empty() ) { cout << "Error loading src2" << endl; return EXIT_FAILURE; } 
 beta = ( 1.0 - alpha );
 addWeighted( src1, alpha, src2, beta, 0.0, dst); 
 imshow( "Linear Blend", dst );
 waitKey(0); 
 return 0;
}

Java:

java 复制代码
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs; 
import java.util.Locale;
import java.util.Scanner; 
class AddingImagesRun{
 public void run() {
 double alpha = 0.5; double beta; double input; 
 Mat src1, src2, dst = new Mat(); 
 System.out.println(" Simple Linear Blender ");
 System.out.println("-----------------------");
 System.out.println("* Enter alpha [0.0-1.0]: ");
 Scanner scan = new Scanner( System.in ).useLocale(Locale.US);
 input = scan.nextDouble(); 
 if( input >= 0.0 && input <= 1.0 )
 alpha = input; 
 src1 = Imgcodecs.imread("../../images/LinuxLogo.jpg");
 src2 = Imgcodecs.imread("../../images/WindowsLogo.jpg"); 
 if( src1.empty() == true ){ System.out.println("Error loading src1"); return;}
 if( src2.empty() == true ){ System.out.println("Error loading src2"); return;} 
 beta = ( 1.0 - alpha );
 Core.addWeighted( src1, alpha, src2, beta, 0.0, dst); 
 HighGui.imshow("Linear Blend", dst);
 HighGui.waitKey(0); 
 System.exit(0);
 }
} 
public class AddingImages {
 public static void main(String[] args) {
 // Load the native library.
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
 new AddingImagesRun().run();
 }
}

Python:

python 复制代码
from __future__ import print_function 
import cv2 as cv 
alpha = 0.5 
try:
 raw_input # Python 2
except NameError:
 raw_input = input # Python 3 
print(''' Simple Linear Blender
-----------------------
* Enter alpha [0.0-1.0]: ''')
input_alpha = float(raw_input().strip())
if 0 <= alpha <= 1:
 alpha = input_alpha
# [load]
src1 = cv.imread(cv.samples.findFile('LinuxLogo.jpg'))
src2 = cv.imread(cv.samples.findFile('WindowsLogo.jpg'))
# [load]
if src1 is None:
 print("Error loading src1")
 exit(-1)
elif src2 is None:
 print("Error loading src2")
 exit(-1)
# [blend_images]
beta = (1.0 - alpha)
dst = cv.addWeighted(src1, alpha, src2, beta, 0.0)
# [blend_images]
# [display]
cv.imshow('dst', dst)
cv.waitKey(0)
# [display]
cv.destroyAllWindows()

解释

由于我们要执行:

通过以下代码加载图像:

C++:

cpp 复制代码
src1 = imread( samples::findFile("LinuxLogo.jpg") );
src2 = imread( samples::findFile("WindowsLogo.jpg") );

Java:

java 复制代码
src1 = Imgcodecs.imread("../../images/LinuxLogo.jpg");
src2 = Imgcodecs.imread("../../images/WindowsLogo.jpg");

Python:

python 复制代码
src1 = cv.imread(cv.samples.findFile('LinuxLogo.jpg'))
src2 = cv.imread(cv.samples.findFile('WindowsLogo.jpg'))

我们使用了以下图像:LinuxLogo.jpgWindowsLogo.jpg

警告

由于我们添加了 src1src2,因此它们必须具有相同的大小(宽度和高度)和类型。

现在我们需要生成图像g(x)。为此,**函数 addWeighted()**非常方便:

C++:

cpp 复制代码
 beta = ( 1.0 - alpha );
 addWeighted( src1, alpha, src2, beta, 0.0, dst);

Java:

java 复制代码
 beta = ( 1.0 - alpha );
 Core.addWeighted( src1, alpha, src2, beta, 0.0, dst);

Python:

python 复制代码
beta = (1.0 - alpha)
dst = cv.addWeighted(src1, alpha, src2, beta, 0.0)

上面行的Python版本(但cv功能快了大约 2 倍):

python 复制代码
dst = np.uint8(alpha*(img1)+beta*(img2))

因为addWeighted() 产生:

在本例中,是上面代码中argument 0.0的参数

创建窗口,显示图像并等待用户结束程序。

C++:

cpp 复制代码
 imshow( "Linear Blend", dst );
 waitKey(0);

Java:

java 复制代码
 HighGui.imshow("Linear Blend", dst);
 HighGui.waitKey(0);

Pytthon:

python 复制代码
cv.imshow('dst', dst)
cv.waitKey(0)

参考文献:

1、《Adding (blending) two images using OpenCV》---Ana Huamán

相关推荐
wx7408513263 分钟前
小琳AI课堂:机器学习
人工智能·机器学习
FL162386312911 分钟前
[数据集][目标检测]车油口挡板开关闭合检测数据集VOC+YOLO格式138张2类别
人工智能·yolo·目标检测
YesPMP平台官方13 分钟前
AI+教育|拥抱AI智能科技,让课堂更生动高效
人工智能·科技·ai·数据分析·软件开发·教育
FL162386312938 分钟前
AI健身体能测试之基于paddlehub实现引体向上计数个数统计
人工智能
黑客-雨41 分钟前
构建你的AI职业生涯:从基础知识到专业实践的路线图
人工智能·产品经理·ai大模型·ai产品经理·大模型学习·大模型入门·大模型教程
子午43 分钟前
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
人工智能·python·cnn
AlexMercer10121 小时前
【C++】二、数据类型 (同C)
c语言·开发语言·数据结构·c++·笔记·算法
大耳朵爱学习1 小时前
掌握Transformer之注意力为什么有效
人工智能·深度学习·自然语言处理·大模型·llm·transformer·大语言模型
TAICHIFEI1 小时前
目标检测-数据集
人工智能·目标检测·目标跟踪
qq_15321452641 小时前
【2023工业异常检测文献】SimpleNet
图像处理·人工智能·深度学习·神经网络·机器学习·计算机视觉·视觉检测