1、算法原理如下:

(1)、首先建立两幅图像高斯金字塔,然后建立一定层数的拉普拉斯金字塔。拉普拉斯金字塔的层数越高,融合效果越好。层数N作为一个参数。 (2)、传入一个mask掩膜,代表了融合的位置。比如说想在两图的中间进行融合,那么掩膜图像的左半为255,右半为0,反过来是一样的。根据这个mask建立一个高斯金字塔,用于后续融合,层数为N+1。 (3)、根据mask将两幅图像的拉普拉斯金字塔的图像进行相加,mask为权值。相加的结果即为一个新的金字塔。同时,两幅图像的高斯金字塔的N+1层也进行这个操作,记这个图像为IMG1。 (4)、根据这个新的金字塔重建出最终的图像,重建的过程跟一般的拉普拉斯金字塔一样。首先对IMG1上采样,然后跟新金字塔的顶层相加,得到IMG2。IMG2进行上采样后跟下一层相加,得到IMG3。重复这个过程,最终得到的结果就是拉普拉斯金字塔融合算法的结果。因为mask建立金字塔的过程中使用了高斯模糊,所以融合的边缘是比较平滑的。

2、算法实现(VS2010 + opencv2.4.10)

#include #include #include

using namespace std; using namespace cv;

class LaplacianBlending? {

private: ? ? Mat m_matLeft; ? ? Mat m_matRight; ? ? Mat m_matBlend;

? ? //Laplacian Pyr

C++:

?void?

Mat::

copyTo

(OutputArray?

m

)

?const

C++:

?void?

Mat::

copyTo

(OutputArray?

m, InputArray?

mask

)

?const

这个函数可以复制图像到另一个图像或矩阵上,可选参数是掩码

由于叠加的图像大小不一定相等,比如我们这里把一张小照片加到一张大照片上

我们可以在大照片上设置一个和小照片一样大的感兴趣区域

不使用掩码的时候,我们载入2张jpg

经过三种处理之后

原先在png里面是透明的地方,现在成了黑色,可见原来是透明的地方被认为是值0。

我们使用掩码来看看效果,掩码就使用png图片,掩码只能是一个通道的,我们载入灰度图像作为掩码

这样能看出差别了吧。

再来看看另一个函数

C++:

?void?

addWeighted

(InputArray?

src1, double?

alpha, InputArray?

src2, double?

beta, double?

gamma, OutputArray?

dst, int?

dtype=-1

)

转换成数学表达式就是

代码如下:

#include

#include

#include

#include

#include

#include

using namespace cv;

int main(){

cv::Mat image = cv::imread("lena.jpg");

cv::Mat image1 = cv::imread("lena.jpg");

cv::Mat image2 = cv::imread("lena.jpg");

cv::namedWindow("image");

cv::imshow("image",image);

cv::Mat logo = cv::imread("xidian.jpg");

cv::Mat mask = cv::imread("xidian.jpg",0);

cv::namedWindow("xidian");

cv::imshow("xidian",logo);

cv::namedWindow("mask");

cv::imshow("mask",mask);

cv::Mat imageROI;

cv::Mat imageROI1;

cv::Mat imageROI2;

imageROI = image(cv::Rect(100,100,logo.cols,logo.rows));

logo.copyTo(imageROI);

imageROI1 = image1(cv::Rect(100,100,logo.cols,logo.rows));

logo.copyTo(imageROI1,mask);

imageROI2 =image2(cv::Rect(100,100,logo.cols,logo.rows));

cv::addWeighted(imageROI2, 1.0, logo, 0.3, 0, imageROI2);

cv::namedWindow("result");

cv::imshow("result",image);

cv::namedWindow("result1");

cv::imshow("result1",image1);

cv::namedWindow("result2");

cv::imshow("result2",image2);

cv::waitKey();

return 0;

}

一、静态库生成

1.CxImage 7.02下载:点击下载2.解压到比如:E:\\cximage702_full\目录下3.解决方案的组织结构

???????? 直接打开CxImageFull_vc10.sln,打开后发现共有该解决方案下共有14个项目,

?????????????????? a.cximage,jasper,jbig,jpeg,libdcr,libpsd,mng,png,tiff,zlib这10个项目是生成静态库文件的,对应的静态库文件分别是cximage.lib,jasper.lib,jbig.lib,jpeg.lib,libdcr.lib,libpsd.lib,mng.lib,png.lib,tiff.lib,zlib.lib;

?????????????????? b.CxImageCrtDll和cximagemfcdll这两个项目是生成动态库的;

?????????????????? c.另外有demo和demodll这两个项目是演示用的,生成demo.exe和demodll.exe两个应用程序(在E:\\cximage702_full\bin目录下),两者之间的差别可能是一个使用的是静态库(demo),一个使用的是动态库(demodll)4.整个解决方案项目之间的依赖关系是

? 10个静态库文件不依赖任何其他项目

? CxImageCrtDll和cximagemfcdll这两个项目依赖于除cximage外的其它静态库项目,

? demo依赖于10个静态库项目

? demodll不依赖任何项目,但在链接器->输入->附加依赖项的时候发现,该项目依赖于10个静态库项目生成的对应lib文件,这些文件必须在此之前生成

5.库文件的生成

? 根据依赖关系,在CxImageCrtDll,cximagemfcdll,demo任意一个项目上上右键生成,都会在相应的E:\\cximage702_full\Debug目录或者E:\\cximage702_full\Release\目录下得到静态库文件

二、调用库前的准备工作

? 建立E:\\cximage文件夹(任意)

o 组织结构如下

o E:\\cximage

o |-----include

o |-----lib

o |--debug

o |---release

? 将E:\\cximage702_full\CxImage文件夹下的所有头文件和源文件拷贝到E://cximage/include文件夹下

? 静态库的准备

o 将debug模式下生成的静态库文件E:\\cximage702_full\CxImage\CxImageDLL\Debug拷贝到E:\\cximage\lib\debug目录下

o 将release模式下生成的静态库文件E:\\cximage702_full\CxImage\CxImageDLL\Release拷贝到E:\\cximage\lib\release目录下

三、调用库的具体操作

新建一个win32控制台项目,其配置如下:

项目配置(静态调用)

新建一个win32控制台项目,其配置如下:

项目配置(静态调用)

a.项目-->属性-->配置属性-->常规里按如下配置

o选择“在共享DLL中使用MFC”,

o使用“多字节字符集”

o选择“在共享DLL中使用MFC”,

o使用“多字节字符集”

www.sxzhongrui.com++目录

o包含目录设置:

o包含目录设置:E:\\cximage\include\

o库目录设置:

o库目录设置:E:\\cximage\lib\debug或者release(具体设置)

c.链接器->输入->附加依赖项

o以分号或者回车为间隔,填入lib文件夹中的库文件,即生成的十个静态库文件

ocximage.lib,jasper.lib,jbig.lib,jpeg.lib,libdcr.lib,libpsd.lib,mng.lib,png.lib,tiff.lib,zlib.lib

o以分号或者回车为间隔,填入lib文件夹中的库文件,即生成的十个静态库文件

ocximage.lib,jasper.lib,jbig.lib,jpeg.lib,libdcr.lib,libpsd.lib,mng.lib,png.lib,tiff.lib,zlib.lib

d.C/C++代码生成

o结构成员对齐:16字节

o预编译头:不使用

o结构成员对齐:16字节

o预编译头:不使用

四、测试程序

#include

void main()

{

CxImage image;

// bmp -> jpg

image.Load(_T("lena.bmp"), CXIMAGE_FORMAT_BMP);

if (image.IsValid())

{

if(!image.IsGrayScale())

image.IncreaseBpp(24);

image.SetJpegQuality(80);

www.sxzhongrui.com(_T("lena.jpg"),CXIMAGE_FORMAT_JPG);

}

}

0条大神的评论

发表评论