OpenCV混合(融合)两张图像
- 一、学习目标
- 二、图像的线性混合
- 三、两种方法实现图像的线性混合
- 四、完整代码示例
- 五、致谢
一、学习目标
- 理解什么是两张图像的混合(融合)
- 使用两种方法实现图像的混合
二、图像的线性混合
在之前的笔记中,我们已经学会了一些基于像素的基本操作。今天来了解一个有趣的二元(双输入)运算符:图像的线性混合运算符。
α从0→1变化,这个运算可以用于在两个图像或视频之间执行交叉融合,就像幻灯片和电影制作中看到的那样。
注意:执行线性混合的两张图像必须具有同样的尺寸和数据类型。
三、两种方法实现图像的线性混合
1、基于像素点遍历的融合
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22status addImageByPixel(Mat& src1, Mat& src2, Mat& dst, double alpha, double beta) { CV_Assert(src1.depth() == CV_8U); CV_Assert(src2.depth() == CV_8U); if (src1.rows != src2.rows || src1.cols != src2.cols || src1.channels() != src2.channels()) { return FALSE; } int channels = src1.channels(); for (int row = 0; row < src1.rows; ++row) { uchar* p1 = src1.ptr<uchar>(row); uchar* p2 = src2.ptr<uchar>(row); uchar* p3 = dst.ptr<uchar>(row); for (int col = 0; col < src1.cols * src1.channels(); ++col) { p3[col] = saturate_cast<uchar>(alpha * p1[col] + beta * p2[col]); } } return TRUE; }
使用像素点遍历的逻辑很简单,即取得两张对应图片的像素套用公式即可。注意在调用公式之前判断两张源图片的尺寸是否相等。
2、使用addWeighted() 函数
复制代码
1
2addWeighted(src1, alpha, src2, 1 - alpha, 0, dst2);
addWeighted() 函数的原型为:
复制代码
1
2
3
4
5
6
7
8
9void cv::addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1)
- 参数 src1: 线性混合的第一张图片
- 参数 alpha: 对应公式中的α
- 参数 src2: 线性混合的第二张图片
- 参数 beta: 对应公式中的1-α ,这儿的参数比公式中的设置更灵活
- 参数 dst: 线性混合后的输出图像
- 参数 dtype: 可选的输出数组的深度;当两个输入数组具有相同的深度时,dtype可以设置为-1,相当于src1.depth()
四、完整代码示例
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90#include<opencv2/opencv.hpp> using namespace cv; using namespace std; typedef int status; #define TRUE 1 #define FALSE 0 status addImageByPixel(Mat& src1, Mat& src2, Mat& dst, double alpha, double beta); int main(int argc, char** argv) { Mat src1, src2; string fileName1 = "O:\CSDN\2.jpg"; string fileName2 = "O:\CSDN\3.jpg"; // 分别读入两张图片,判断是否读入成功 src1 = imread(fileName1, IMREAD_COLOR); if (!src1.data) { cerr << "failed to load image :" << fileName1 << "!" << endl; system("pause"); return EXIT_FAILURE; } src2 = imread(fileName2, IMREAD_COLOR); if (src2.empty()) { fprintf(stderr, "failed to load image :%s!n", fileName2); system("pause"); return EXIT_FAILURE; } // 初始化输出图像对象 Mat dst1, dst2; dst1.create(src1.size(), src1.type()); dst2.create(src1.size(), src1.type()); double alpha = 0.5; // 调用基于像素遍历的方法,统计处理时间 double t1 = (double)getTickCount(); if (!addImageByPixel(src1, src2, dst1, alpha, 1 - alpha)) { cout << "two images have different size!n"; system("pause"); return EXIT_FAILURE; } double time1 = ((double)getTickCount() - t1) / getTickFrequency(); cout << "Method pixel take time:" << time1 << "(ms)" << endl; // 调用基于addWeighted函数的方法,统计处理时间 double t2 = (double)getTickCount(); addWeighted(src1, alpha, src2, 1 - alpha, 0, dst2); double time2 = ((double)getTickCount() - t2) / getTickFrequency(); cout << "Method addWeighted take time:" << time2 << "(ms)" << endl; // 显示混合前和混合后的图像 imshow("src1", src1); imshow("src2", src2); imshow("add by pixel", dst1); imshow("add by addWeighted", dst2); waitKey(0); system("pause"); return EXIT_SUCCESS; } status addImageByPixel(Mat& src1, Mat& src2, Mat& dst, double alpha, double beta) { CV_Assert(src1.depth() == CV_8U); CV_Assert(src2.depth() == CV_8U); // 判断两张图片的size是否一致 if (src1.rows != src2.rows || src1.cols != src2.cols || src1.channels() != src2.channels()) { return FALSE; } int channels = src1.channels(); // 依次处理每一行像素,这儿不需要区分是单通道图像还是多通道图像 for (int row = 0; row < src1.rows; ++row) { uchar* p1 = src1.ptr<uchar>(row); uchar* p2 = src2.ptr<uchar>(row); uchar* p3 = dst.ptr<uchar>(row); // 对每一个像素应用公式计算 for (int col = 0; col < src1.cols * src1.channels(); ++col) { p3[col] = saturate_cast<uchar>(alpha * p1[col] + beta * p2[col]); } } return TRUE; }
线性混合的效果和效率对比如下。
五、致谢
1、感谢OpenCV官方给出的学习案例,感谢大家的支持
2、感兴趣的小伙伴一起学习讨论。入群飞机票
最后
以上就是稳重音响最近收集整理的关于7、OpenCV混合(融合)两张图像的全部内容,更多相关7、OpenCV混合(融合)两张图像内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复