使用liner、feather、multiband对已经拼接的数据进行融合(下)

理解mulitband。所谓的mulitband,其实就是一种多尺度的样条融合,其实现的主要方法就是laplace金字塔。

高斯金字塔是向下采样,而laplace金字塔式向上采样(也就是恢复),采用的都是差值的方法。如何能够在金字塔各个层次上面进行图像的融合,结果证明是相当不错的。网络上面流传的一个类解释了这个问题,并且能够拿来用:

// GOImage.cpp : 定义? DLL 的?初?始?化例y程。

//

#include "stdafx.h"

#include <iostream>

#include <vector>

#include <opencv2/core/core.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/features2d/features2d.hpp>

#include <opencv2/calib3d/calib3d.hpp>

using namespace cv;

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

#define DllExport _declspec (dllexport)

/*

1.设计?一?个?mask(一?半?全?1,?一?半?全?0)?,?并计?算?level层?的?gaussion_mask[i];?

2.计?算?两?幅图?像?每?一?层?的?Laplacian[i],?并与?gaussion_mask[i]相乘?,?合?成一?幅result_lapacian[i];?

3.对?两?幅图?像?不?断?求prydown,?并把?最?高?层?保存?在gaussion[i],与?gaussion_mask[i]相乘?,?合?成一?幅result_gaussion;

4,对?result_gaussion不?断?求pryup,?每?一?层?都?与?result_lapacian[i]合?成,?最?后得?到?原-图?像?大小?的?融合?图?像?。

*/

class LaplacianBlending {

private:

Mat_<Vec3f> top;

Mat_<Vec3f> down;

Mat_< float> blendMask;

vector<Mat_<Vec3f> > topLapPyr,downLapPyr,resultLapPyr; //Laplacian Pyramids

Mat topHighestLevel, downHighestLevel, resultHighestLevel;

vector<Mat_<Vec3f> > maskGaussianPyramid; //masks are 3-channels for easier multiplication with RGB

int levels;

//创建金e字?塔t

void buildPyramids() {

//参?数y的?解a释 top就是?top ,topLapPyr就是?top的?laplacian的?pyr,而?topHighestLevel保存?的?是?最?高?端?的?高?斯1金e字?塔t

buildLaplacianPyramid(top,topLapPyr,topHighestLevel);

buildLaplacianPyramid(down,downLapPyr,downHighestLevel);

buildGaussianPyramid();

}

//创建gauss金e字?塔t

void buildGaussianPyramid() {//金e字?塔t内容Y为a每?一?层?的?掩模

assert(topLapPyr.size()>0);

maskGaussianPyramid.clear();

Mat currentImg;

//blendMask就是?掩码?

cvtColor(blendMask, currentImg, CV_GRAY2BGR); //store color img of blend mask into maskGaussianPyramid

maskGaussianPyramid.push_back(currentImg); //0-level

currentImg = blendMask;

for (int l=1; l<levels+1; l++) {

Mat _down;

if (topLapPyr.size() > l)

pyrDown(currentImg, _down, topLapPyr[l].size());

else

pyrDown(currentImg, _down, topHighestLevel.size()); //lowest level

Mat down;

cvtColor(_down, down, CV_GRAY2BGR);

maskGaussianPyramid.push_back(down); //add color blend mask into mask Pyramid

currentImg = _down;

}

}

//创建laplacian金e字?塔t

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;  //存?储的?就是?残D差?

lapPyr.push_back(lap);

currentImg = down;

}

currentImg.copyTo(HighestLevel);

}

Mat_<Vec3f> reconstructImgFromLapPyramid() {

//将?左右laplacian图?像?拼成的?resultLapPyr金e字?塔t中D每?一?层?

//从上?到?下?插?值放?大并相加,?即得?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() {

//获?得?每?层?金e字?塔t中D直接用?左右两?图?Laplacian变?换?拼成的?图?像?resultLapPyr

//一?半?的?一?半?就是?在这a个?地?方?计?算?的?。 是?基于掩模的?方?式?进?行D的?.

resultHighestLevel = topHighestLevel.mul(maskGaussianPyramid.back()) +

downHighestLevel.mul(Scalar(1.0,1.0,1.0) - maskGaussianPyramid.back());

for (int l=0; l<levels; l++) {

Mat A = topLapPyr[l].mul(maskGaussianPyramid[l]);

Mat antiMask = Scalar(1.0,1.0,1.0) - maskGaussianPyramid[l];

Mat B = downLapPyr[l].mul(antiMask);

Mat_<Vec3f> blendedLevel = A + B;

resultLapPyr.push_back(blendedLevel);

}

}

public:

LaplacianBlending( const Mat_<Vec3f>& _top, const Mat_<Vec3f>& _down, const Mat_< float>& _blendMask, int _levels)://缺省?数y据Y,?使1用? LaplacianBlending lb(l,r,m,4);

top(_top),down(_down),blendMask(_blendMask),levels(_levels)

{

assert(_top.size() == _down.size());

assert(_top.size() == _blendMask.size());

buildPyramids();  //创建laplacian金e字?塔t和gauss金e字?塔t

blendLapPyrs();   //将?左右金e字?塔t融合?成为a一?个?图?片?

};

Mat_<Vec3f> blend() {

return reconstructImgFromLapPyramid();//reconstruct Image from Laplacian Pyramid

}

};

Mat_<Vec3f> LaplacianBlend( const Mat_<Vec3f>& t, const Mat_<Vec3f>& d, const Mat_< float>& m) {

LaplacianBlending lb(t,d,m,4);

return lb.blend();

}

DllExport double aValue =1.5;

DllExport int dlladd()

{

return 5;

}

DllExport int dlladd( int a,int b)

{

return a+b;

}

DllExport cv::Mat imagetest()

{

cv::Mat image1= cv::imread( "C:\\apple.png",1);

cv::Mat image2= cv::imread( "C:\\orange.png",1);

Mat_<Vec3f> t; image1.convertTo(t,CV_32F,1.0/255.0); //Vec3f表示?有D三y个?通道,?即 l[row][column][depth]

Mat_<Vec3f> d; image2.convertTo(d,CV_32F,1.0/255.0);

Mat_< float> m(t.rows,d.cols,0.0);                 //将?m全?部?赋3值为a0

//m(Range::all(),Range(0,m.cols/2)) = 1.0;    //原-来初?始?的?掩码?是?在这a里?!?!?

m(Range(0,m.rows/2),Range::all())=1.0;

Mat_<Vec3f> blend = LaplacianBlend(t,d, m);

imshow( "blended",blend);

return blend;

}

需要注意的是, m(Range(0,m.rows/2),Range::all())=1.0表明了原始图像的掩码,这个掩码就是那个分界的地方

使用liner、feather、multiband对已经拼接的数据进行融合(下)

时间: 2024-08-27 03:09:48

使用liner、feather、multiband对已经拼接的数据进行融合(下)的相关文章

使用liner、feather、multiband对已经拼接的数据进行融合

所谓"blend",英文解释为“vt. 混合vi. 混合:协调n. 混合:掺合物”这里应该理解为是图像数据的融合.这是“识别->对准->融合”的最后一步.融合是决定拼接质量的关键一步,一方面它决定于图像对准的质量,一方面它本身的也直接对拼接的最终结果负责. 最简单和便于理解的融合为liner,正好借这个例子来说明说明是融合,简单的说,就是在融合的区域……(这个地方引用相关资料)liner在opencv中没有实现,但是本身简单有效,对于要求不是很高的情况可以使用,这里给出函数

004.原始套接字,拼接UDP数据包,通信

大致流程: 建立一个client端,一个server端,自己构建IP头和UDP头,写入数据(hello,world!)后通过原始套接字(SOCK_RAW)将包发出去. server端收到数据后,打印UDP数据并发送确认消息(yes),client收到yes后将其打印. 其中: client端IP:192.168.11.104 端口:8600 server端IP:192.168.11.105 端口:8686 注意事项: 1.运行原始套接字socket需要有root权限. 2.注意主机字节序和网络字

使用concat做字符串拼接和数据迁移

作用: 解决一开始数据库建立不合理造成的字段冗余,从而提取部分字段,数据迁移.拼接字符串的功能. 格式: concat(字段1,'间隔符',字段2....) concat_ws('间隔符',字段1,字段2) 数据准备: #创建表 create table employee( id int not null unique auto_increment, name varchar(20) not null, sex enum('male','female') not null default 'ma

Python接口测试-以&amp;连接拼接字典数据(get中url请求数据)

get请求的utl数据是这样的,例如:/banner/findBanner?bannerType=1&_=1556107073181 ''' 1-banner图-banner/findBanner ''' str1=parse.urlencode(data1) url1='{0}/banner/findBanner?bannerType=1&_=1556107073181'.format(yuming) headers ={'Content-Type':'application/json;

拼接JSON数据

//根据记录表IDRecordID查找所有文件                IList<Model.FILECHANGE_FILE> listFile = cFile.GetList(" where t.RecordID", "");                if (listFile.Count > 0)                {                    //返回JSON数据                    _s

mysql 拼接列数据

SELECT IF(@ids=w.contract_id,@num:[email protected],@num:[email protected]+1) AS num,@ids:=w.contract_id,w.* FROM (SELECT (SELECT GROUP_CONCAT(project_name) FROM production_income_data WHERE contract_id = a.contract_id) AS `names`, (SELECT GROUP_CONC

基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)

一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiDU全景"这样的全部的或者部分的实际场景的重新回放. 对于图像拼接的流程有很多定义方式,本教程中主要介绍实现主流方法,总结梳理如下: 图像采集->投影变换->特征点匹配->拼接对准->融合->反投影 图像采集不仅仅指的是普通的图像数据的获取.为了能够拼接过程能够顺利进行.

全景视频拼接(二)--OpenCV源码解析

本文参考:http://blog.csdn.net/skeeee/article/details/19480693,做了一定修改和补充. 一.stitching_detail程序运行流程 1.命令行调用程序,输入源图像以及程序的参数 2.特征点检测,判断是使用surf还是orb,默认是surf. 3.对图像的特征点进行匹配,使用最近邻和次近邻方法,将两个最优的匹配的置信度保存下来. 4.对图像进行排序以及将置信度高的图像保存到同一个集合中,删除置信度比较低的图像间的匹配,得到能正确匹配的图像序列

拼接字符串,生成tree格式的JSON数组

之前做的执法文书的工作,现在需要从C#版本移植到网页版,从Thrift接口获取数据,加载到对应的控件中 之前用的easyui的Tree插件,通过<ul><li><span></span></li></ul>标签的方式生成node树,条理清晰,虽然麻烦点,但是用循环写几行代码就能搞定,但是,在Ajax的函数里面,tree的样式加载不上,显示的格式就是元素自带的含义,<ul>和<li>,无法点击,下面的工作也就无法