图像拉普拉斯金字塔融合(Laplacian Pyramid Blending)

转摘的,修改了下程序,图像融合看不太懂 。。。。http://blog.csdn.net/abcjennifer/article/details/7628655#comments


// 转摘的别人的程序
// #include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <opencv2/opencv.hpp>using namespace cv;// __func__ 和 __FUNCTION__ 一样的意思,描述当前所在的函数
#define ENABLE_DEBUG 1   //else, comment this line
#ifdef ENABLE_DEBUG
#define DEBUG_LOG(fmt,...) fprintf(stderr, "%s:%d: " fmt "\n",   \__FUNCTION__ , __LINE__, ## __VA_ARGS__)
#else
#define DEBUG_LOG(fmt, ...) do {} while (0)
#endif//
// disable stupid warning 4018 and etc...
#pragma warning(push)
#pragma warning(disable:4018)/************************************************************************/
/* 说明:
*金字塔从下到上依次为 [0,1,...,level-1] 层
*blendMask 为图像的掩模
*maskGaussianPyramid为金字塔每一层的掩模
*resultLapPyr 存放每层金字塔中直接用左右两图Laplacian变换拼成的图像
*/
/************************************************************************/
class LaplacianBlending {
private:Mat_<Vec3f> left;Mat_<Vec3f> right;Mat_<float> blendMask;vector<Mat_<Vec3f> > leftLapPyr,rightLapPyr,resultLapPyr;//Laplacian PyramidsMat leftHighestLevel, rightHighestLevel, resultHighestLevel;vector<Mat_<Vec3f> > maskGaussianPyramid; //masks are 3-channels for easier multiplication with RGBint levels;void buildPyramids() {buildLaplacianPyramid(left,leftLapPyr,leftHighestLevel);buildLaplacianPyramid(right,rightLapPyr,rightHighestLevel);buildGaussianPyramid();}void buildGaussianPyramid() {//金字塔内容为每一层的掩模assert(leftLapPyr.size()>0);maskGaussianPyramid.clear();Mat currentImg;cvtColor(blendMask, currentImg, CV_GRAY2BGR);//store color img of blend mask into maskGaussianPyramidmaskGaussianPyramid.push_back(currentImg); //0-levelcurrentImg = blendMask;for (int l=1; l<levels+1; l++) {Mat _down;if (leftLapPyr.size() > l)pyrDown(currentImg, _down, leftLapPyr[l].size());elsepyrDown(currentImg, _down, leftHighestLevel.size()); //lowest levelMat down;cvtColor(_down, down, CV_GRAY2BGR);maskGaussianPyramid.push_back(down);//add color blend mask into mask PyramidcurrentImg = _down;}}void buildLaplacianPyramid(const Mat& img, vector<Mat_<Vec3f> >& lapPyr, Mat& HighestLevel) {lapPyr.clear();Mat currentImg = img;for (int l=0; l<levels; l++) {Mat down,up;pyrDown(currentImg, down);pyrUp(down, up,currentImg.size());Mat lap = currentImg - up;lapPyr.push_back(lap);currentImg = down;}currentImg.copyTo(HighestLevel);}Mat_<Vec3f> reconstructImgFromLapPyramid() {//将左右laplacian图像拼成的resultLapPyr金字塔中每一层//从上到下插值放大并相加,即得blend图像结果Mat currentImg = resultHighestLevel;for (int l=levels-1; l>=0; l--) {Mat up;pyrUp(currentImg, up, resultLapPyr[l].size());currentImg = up + resultLapPyr[l];}return currentImg;}void blendLapPyrs() {//获得每层金字塔中直接用左右两图Laplacian变换拼成的图像resultLapPyrresultHighestLevel = leftHighestLevel.mul(maskGaussianPyramid.back()) +rightHighestLevel.mul(Scalar(1.0,1.0,1.0) - maskGaussianPyramid.back());for (int l=0; l<levels; l++) {Mat A = leftLapPyr[l].mul(maskGaussianPyramid[l]);Mat antiMask = Scalar(1.0,1.0,1.0) - maskGaussianPyramid[l];Mat B = rightLapPyr[l].mul(antiMask);Mat_<Vec3f> blendedLevel = A + B;resultLapPyr.push_back(blendedLevel);}}public:LaplacianBlending(const Mat_<Vec3f>& _left, const Mat_<Vec3f>& _right, const Mat_<float>& _blendMask, int _levels)://construct function, used in LaplacianBlending lb(l,r,m,4);left(_left),right(_right),blendMask(_blendMask),levels(_levels){assert(_left.size() == _right.size());assert(_left.size() == _blendMask.size());buildPyramids();	//construct Laplacian Pyramid and Gaussian PyramidblendLapPyrs();	//blend left & right Pyramids into one Pyramid};Mat_<Vec3f> blend() {return reconstructImgFromLapPyramid();//reconstruct Image from Laplacian Pyramid}
};Mat_<Vec3f> LaplacianBlend(const Mat_<Vec3f>& l, const Mat_<Vec3f>& r, const Mat_<float>& m) {LaplacianBlending lb(l,r,m,4);return lb.blend();
}// 图像融合处理
void process(char *sleft, char *sright, char *sresult/*结果保存*/)
{if (!sleft || !*sleft || !sright || !*sright){return;}Mat l8u = imread(sleft);Mat r8u = imread(sright);// check file sizeSize sz1 = l8u.size(),sz2 = r8u.size();if ( sz1 != sz2){DEBUG_LOG("left and the right image must be the same size");exit(0);}//imshow("left",l8u); imshow("right",r8u);Mat_<Vec3f> l; l8u.convertTo(l,CV_32F,1.0/255.0);//Vec3f表示有三个通道,即 l[row][column][depth]Mat_<Vec3f> r; r8u.convertTo(r,CV_32F,1.0/255.0);/*****************    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;******************//* Performs linear transformation on every source array element:dst(x,y,c) = scale*src(x,y,alpha)+beta.Arbitrary combination of input and output array depths are allowed(number of channels must be the same), thus the function can be usedfor type conversion *///create blend mask matrix mMat_<float> m(l.rows,l.cols,0.0);					//将m全部赋值为0m(Range::all(),Range(0,m.cols/2)) = 1.0;	//取m全部行&[0,m.cols/2]列,赋值为1.0Mat_<Vec3f> blend = LaplacianBlend(l, r, m);imshow("blended",blend);// save result to png filestd::vector<int> qualityType;qualityType.push_back(CV_IMWRITE_JPEG_QUALITY);qualityType.push_back(90);    //png格式下,默认的参数为3.if(sresult != NULL){//build file namechar filename[255] = {0};sprintf(filename, "%s.jpg", sresult);try {imwrite(filename, cv::Mat(blend), qualityType);}catch (std::runtime_error& ex) {DEBUG_LOG("Exception converting image to PNG format: %s\n", ex.what());exit(1);}DEBUG_LOG("Saved PNG file with alpha data...");}waitKey(0);
}/*******************************************************************************主函数*******************************************************************************/
int main( int argc, char * argv[] )
{// 调试程序,选择菜单->项目->属性->调试->命令参数, if ( argc < 3 ) {printf( "Usage:\n" );printf( "LaplacianBlending LeftImage RightImage\n" );exit( 0 );}DEBUG_LOG("\nleft image = %s\nright image=%s\n\n", argv[1], argv[2]);if ( argc == 3 )process( argv[1], argv[2], NULL );else  // argc >= 4process( argv[1], argv[2],argv[3]);return 0;
}//
#pragma warning(pop)



  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]GIS简介

************************************************** 最近论坛上经常有人讨论GIS&#xff0c;特意从别人的blog中转了一篇GIS简介的帖子************************************************** 地理信息系统(GIS,Geographic Information System)是一门用计算机来研究地理的学科…

debug设计

debug设计 会用到debug设计的阶段 (1)RTL级设计仿真 (2)实施后的设计模拟 (3)在系统调试 使用网表插入调试探测流动 (1)最高级别是一个简单的向导,用于创建和配置集成逻辑分析仪 (ILA)内核会根据选定的一组网络自动进行调试。 (2)下一级是主调试窗口,允许控制单个…

ASA 9.21 in Vmware Workstation 10

There is old post “ASA 8.02 in Vmware Workstation “ in this blog posted on Dec 2011. Anothe post “How to Make your own ASA 8.42 in VMware”. Here are all related posts in this blog: ASA 8.02 in Vmware WorkstationASA 8.42 in VMware WorkstationASA 9.21 i…

MMU及PTS说明

MMU与PTS表格 最近在FPGA上仿真调试Virgo&#xff08;基于ARM11的一款处理器&#xff09;芯片。MMU部分总是出错&#xff0c;具体的现象是查看物理地址和虚拟地址的映射时候芯片经常会挂掉。先是怀疑MMU的寄存器配置有问题&#xff0c;后来又怀疑MMU映射使用的PTS表格有问题&a…

bug?VS2010中CImageList::DrawIndirect总是返回失败

//VS2010 #if _MSC_VER > 1600pImageList->Draw(pDC, nImage, point, ILD_NORMAL); #elseSIZE size;size.cx rect.Width() < sizeImage.cx ? rect.Width() : sizeImage.cx;size.cy rect.Height() < sizeImage.cy ? rect.Height() : sizeImage.cy;pImageList-&g…

VHDL基本结构

VHDL基本结构 (1)实体(Entity):描述所设计的系统的外部接口信号,定义电路设计中得到所有的输入和输出端口。 (2)结构体(Architecture):描述系统内部的结构和行为 (3)包集合(Package):存放各设计模块能共享的数据类型、常数和子程序等; (4)配置(Configurat…

Source Code Collection for Reproducible Research

转自&#xff1a;http://www.csee.wvu.edu/~xinl/source.html “It doesnt matter how beautiful your theory is, it doesnt matter how smart you are. If it doesnt agree with experiment, its wrong” - Richard Feynman "As a method for finding things out, scien…

IClass与电源管理

IClass与电源管理 前段时间为J9项目上添加电源管理&#xff0c;中间走了一些弯路。之前错误的认为&#xff0c;IClass只是与电源状态的改变方法有关&#xff0c;也就是说IClass的正确与否只会影响到设备电源状态的正确与否&#xff0c;而不会造成设备是否可以支持设备电源状态的…

状态机在VHDL中的实现

状态机在VHDL中的实现 1、Moore状态机的VHDL描述 输出仅取决于所处的状态 LIBRARY IEEE; --库、程序包的说明调用 USE IEEE.STD_LOGIC_1164.ALL;ENTITY Moore IS PORT (RESET,CLOCK,DIN : IN STD_LOGIC;DOUT : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) ); END;ARCHITECTURE Mo…

Linux : find big file in the all directories

1. Juniper Firewall find . -type f -size 10000 -exec ls -lh {} ; Sample output: [email protected]% find . -type f -size 10000 -exec ls -lh {} ; -rw-r–r– 1 930 929 134M Jan 5 17:34 ./cf/packages/junos-11.4R6.6-domestic-rw-r–r– 1 root wheel 1…

VC++静态文本框/PICTURE控件的notify属性

RT&#xff0c;该属性对应的是SS_NOTIFY&#xff0c;但是很多人误以为是WM_NOTIFY 。该属性可以用ModifyStyle函数修改。

VHDL仿真

VHDL仿真 仿真(Simulation也称模拟),不接触具体的硬件系统利用计算机对电路设计的逻辑行为和运行功能进行模拟检测,较大规模的VHDL系统设计的最后完成必须经历多层次的仿真测试过程,包括针对系统的VHDL行为仿真、分模块的时序仿真和硬件仿真,直至最后系统级的硬件仿真测…

从Var Tick角度来对CE电源管理

从Var Tick角度来对CE电源管理 一&#xff0e;相关的基础知识如下 1&#xff0e;OAL中Timer相关函数说明 1> OALTimerInit 参数&#xff1a; msecPerSysTick: 每个系统调度Tick对应多少ms&#xff1b; countsPerMSec: Timer的Counter变化多少为1ms&#xff0c;其值为T…

变量初始化的确定性

变量初始化的确定性 SystemVerilog初始化顺序 SystemVerilog标准增强了变量的内嵌初始化。SystemVerilog规定所有内嵌初始化先于仿真时刻0执行的事件。这就保证了如果Initial或者always过程块读取具有内嵌初始值的变量时取得正确的初始值&#xff0c;这个确定行为消除了Verilo…

很好的Android论坛

需要的兄弟可以看一下 http://www.eoeandroid.com/?fromuid9379

用户自定义和枚举数据类型

用户自定义和枚举数据类型 用户自定义 1、typedef定义用户自定义类型 SystemVerilog同C一样&#xff0c;使用typedef关键字来建立用户自定义类型。用户自定义类型允许使用现有的数据类型建立新的数据类型。新的数据类型定义后&#xff0c;可以声明这个类型的变量 typedef int…

Keyboard驱动介绍

Keyboard驱动介绍 最近手里面没啥事&#xff0c;就想看看一些Driver的MDD层。 以前改过Keyboard Driver的PDD层&#xff0c;但是对它的MDD层还真是一片空白&#xff0c;这两天随便看了看Keyboard的MDD层&#xff0c;赶紧把东西记录下来&#xff0c;以防以过段时间忘记了。 很多…

GDI+不同的地方

研究了GDI处理图像的地方&#xff0c;发现它一些与众不同的地方&#xff0c;被它坑了一天。。。。。1、GDI的像素的原点默认你在左下角的&#xff0c;所以读取像素的顺序是从最低一行开始的(bottom-left)&#xff0c;其他一般的图像处理软件&#xff0c;像Photoshop&#xff0c…

关于结构体的内容

关于结构体的内容 结构体使用类似于C语言的语法来定义 结构体使用struct关键字声明。结构体内的成员可以是任何数据类型&#xff0c;包括用户自定义类型和其他的结构体类型。 struct{int a,b; //32位变量opcode_t opcode;//用户定义类型logic [23:0] adress;//24位变量bit er…

Pushing Policy Failed because Checkpoint Firewall “Load on module failed – no memory”

One day when pushing firewall policy from Checkpoint management server to UTM 272 cluster gateways, it failed and I got error message “Load on module failed – no memory” on one of cluster members. “Network Security Policy ‘Montreal_DMZ’ was prepared …