使用openCV来完成图像的叠加

在openCV中我们可以使用以下函数来进行图像的叠加:

addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst);

接下来让我们来好好分析一下这个函数:

src1:需要叠加的第一个图像

alpha:src1图像在叠加时所占的权重

src2:需要叠加的另一个图像

beta:src2图像在叠加式所占的权重

gamma:叠加完后加的常数,你可以增加gamma的值让图片更亮

dst:叠加完后输出的图像

示例

#include<opencv2/opencv.hpp>
#include<stdc++.h>
using namespace cv;
using namespace std;

int main() {

  Mat a,b,c;
  /*读取图片*/
  a = imread("D:\\壁纸\\带带大师兄.jpg");
  if (!a.data) {
    printf("没有找到图片");
    return -1;
  }
  b = imread("D:\\壁纸\\星空.jpg");
  if (!b.data) {
    printf("没有找到图片");
    return -1;
  }	
  /*当大小一致时直接进行叠加*/
  if (a.size() == b.size()) {
    addWeighted(a, 0.4, b, 0.6,0, c);
    imshow("jun", c);
  }
  /*当大小不一致时先改变大小至一致再进行叠加*/
  else 
  {
    Mat bnew;
    int row, col;
    row = a.rows;
    col = a.cols;
    resize(b, bnew, Size(col, row));			
    addWeighted(a, 0.2, bnew, 0.8, 0, c);
    imshow("jun", c);		
  }
  
  waitKey(0);
  return 0;
}

在使用addWeighted()函数时要注意两张图片的大小必须相等,所以我们在进行叠加图片前要判断两者大小是否相等。这里介绍下resize()函数:

resize( InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR )

我们来分析一下这个函数:

src:输入图像

dst:输出图像

dsize:改变后图像的大小,如果选择填写此参数那么我们就要填写精确的数值,如Size(30,30),这就代表改变后的图像大小为30*30。如果你不选择填写此参数你可以填写0,那么你就需要填写fx、fy参数。

fx、fy:如果你无法确定被改变大小的图像要改变的确切数值你可以填写此参数,此参数会根据你填写的数值进行放大或缩小,如:

resize(jun,bian,Size(),2,2,INTER_LINEAR);

这样我们就能把jun这个图像按x轴放到2倍,按y轴放大2倍,并得到新的图像bian。

interpolation:此参数是用来选择使用什么插值法来进行变换图片大小。不论是放大或是缩小图像都需要插值运算,缩小图像时,目标图像的像素会映射为源图像中的多个像素,放大图像时,目标图形上的像素可能无法在源图像中找到精确对应的像素,都需要进行插值运算。

当然了,你可以将此参数空着,这样就会选择默认的双线性插值法。

以下为你可以选择的插值法:

1)INTER_NEAREST – 最近邻插值法
2)INTER_LINEAR – 双线性插值法(默认)
3)INTER_AREA – 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
4)INTER_CUBIC – 基于4×4像素邻域的3次插值法
5)INTER_LANCZOS4 – 基于8×8像素邻域的Lanczos插值

使用resize()函数我们就能让a图像和b图像大小一致了,接下来就是使用addWeighted()函数进行叠加操作了。

让我们来运行一下试试:

我们可以看到两幅图片叠加到一起了!是不是觉得很儒雅随和呢?