1 案例背景

为了获得超宽视角、大视野、高分辨率的图像,传统的方式为采用价格高昂的特殊摄像器材来进行拍摄,采集图像并进行处理。近年来,随着数码相机、智能手机等经济适用型手持成像硬件设备的普及,人们可以对某些场景方便地获得离散图像序列,再通过适当的图像处理方法改善图像的质量,最终实现图像序列的自动拼接,同样可以获得具有超宽视角、大视野、高分辨率的图像。这里提到的图像拼接就是基于图像绘制技术的全景图拼接方法。图像拼接技术是一种将从真实世界采集的离散化图像序列合成一个宽视角的场景图像技术。假设有两幅具有重叠相关的图像,则图像拼接就是将这两幅图像拼接成一幅图像,因此,图像拼接的关键是能够快速高效地寻找到两幅不同图像的重叠部分,实现宽视角成像",其中,重叠部分的寻找方法有很多,如像素查询、块匹配等。通过不同方法找到重
叠部分后就可以进行图像叠加融合,从而完成图像的拼接过程。

2 理论基础
目前全景图根据实现类型可分为柱面、球面、立方体等形式,柱面全景图像因其数据存储结构简单、易于实现而被普遍采用。全景图的拼接一般有以下步骤.
2.1 空间投影
从真实世界中采集的一组相关图像以一定的方式投影到统一的空间面,其中可能存在立方体、圆柱体和球面体表面等。因此,这组图像就具有统一的参数空间坐标。

2.2 匹配定位
对投影到统一的空间面中的相邻图像进行比对,确定可匹配的区域位置。

2.3 叠加融合

根据匹配结果,将图像重叠区域进行融合处理,拼接成全景图,因此,图像拼接技术是全景图技术的关键和核心,通常可以分为两步:图像匹配和图像融合,本案例选择图像块匹配和加权融合。其拼接流程如图所示,图像块匹配过程,如图所示。

opencv 全景拼接测试用图_matlab


图像拼接流程图 图像块匹配过程

3 图像匹配

图像匹配通过计算相似性度量来决定图像间的变换参数,应用于从不同传感器、不同视角、不同时间采集的同一场景的两幅或多幅图像,将其变换到同一坐标系下,并在像素层上实现最佳匹配的效果。根据相似性度量计算的对象,图像匹配的方法大致可以划分为4类:基于灰度的匹配、基于模板的匹配、基于变换域的匹配和基于特征的匹配。

3.1 基于灰度的匹配

基于灰度的匹配以图像灰度信息为处理对象,通过计算优化极值的思想来进行匹配,其基本步骤如下所示。

(1)几何变换。将待匹配的图像进行几何变换。

(2)目标函数。以图像的灰度信息统计特性为基础定义一个目标函数,如互信息、最小均方差等,并将其作为参考图像与变换图像的相似性度量。

(3)极值优化。通过对目标函数计算极值来获取配准参数,将其作为配准的判决准则,通过对配准参数求最优化,可以将配准问题转化为某多元函数的极值问题。

(4)变换参数。采用某种最优化方法计算正确的几何变换参数。通过以上步骤可以看出,基于灰度的匹配方法不涉及图像的分割和特征提取过程,所以具有精度高、鲁棒性强的特点。但是这种匹配方法对灰度变换十分敏感,未能充分利用灰度统计特性,对每一点的灰度信息都具有较强的依赖性,使得匹配结果容易受到干扰。

3.2 基于模板的匹配

基于模板的匹配通过在图像的已知重叠区域中选择一块矩形区域作为模板,应用于扫描被匹配图像中同样大小的区域进行比对,计算其相似性度量,确定最佳的匹配位置,因

⛄二、部分源代码

function varargout = Gui_Main(varargin)
 % GUI_MAIN MATLAB code for Gui_Main.fig
 % GUI_MAIN, by itself, creates a new GUI_MAIN or raises the existing
 % singleton*.
 %
 % H = GUI_MAIN returns the handle to a new GUI_MAIN or the handle to
 % the existing singleton*.
 %
 % GUI_MAIN(‘CALLBACK’,hObject,eventData,handles,…) calls the local
 % function named CALLBACK in GUI_MAIN.M with the given input arguments.
 %
 % GUI_MAIN(‘Property’,‘Value’,…) creates a new GUI_MAIN or raises the
 % existing singleton*. Starting from the left, property value pairs are
 % applied to the GUI before Gui_Main_OpeningFcn gets called. An
 % unrecognized property name or invalid value makes property application
 % stop. All inputs are passed to Gui_Main_OpeningFcn via varargin.
 %
 % *See GUI Options on GUIDE’s Tools menu. Choose “GUI allows only one
 % instance to run (singleton)”.
 %
 % See also: GUIDE, GUIDATA, GUIHANDLES% Edit the above text to modify the response to help Gui_Main
% Last Modified by GUIDE v2.5 27-Apr-2011 09:29:29
% Begin initialization code - DO NOT EDIT
 gui_Singleton = 1;
 gui_State = struct(‘gui_Name’, mfilename, …
 ‘gui_Singleton’, gui_Singleton, …
 ‘gui_OpeningFcn’, @Gui_Main_OpeningFcn, …
 ‘gui_OutputFcn’, @Gui_Main_OutputFcn, …
 ‘gui_LayoutFcn’, [] , …
 ‘gui_Callback’, []);
 if nargin && ischar(varargin{1})
 gui_State.gui_Callback = str2func(varargin{1});
 endif nargout
 [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
 else
 gui_mainfcn(gui_State, varargin{:});
 end
 % End initialization code - DO NOT EDIT% — Executes just before Gui_Main is made visible.
 function Gui_Main_OpeningFcn(hObject, eventdata, handles, varargin)
 % This function has no output args, see OutputFcn.
 % hObject handle to figure
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)
 % varargin command line arguments to Gui_Main (see VARARGIN)% Choose default command line output for Gui_Main
 clc; warning off all;
 axes(handles.axes1); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes2); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes3); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes4); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);handles.output = hObject;
 handles.file = [];
 handles.MStitch = [];
 handles.grayResult = [];
 handles.RGBResult = [];
 handles.grayListResult = [];
 handles.RGBListResult = [];% Update handles structure
 guidata(hObject, handles);% UIWAIT makes Gui_Main wait for user response (see UIRESUME)
 % uiwait(handles.figure1);% — Outputs from this function are returned to the command line.
 function varargout = Gui_Main_OutputFcn(hObject, eventdata, handles)
 % varargout cell array for returning output args (see VARARGOUT);
 % hObject handle to figure
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structure
 varargout{1} = handles.output;% --------------------------------------------------------------------
 function uipushtool1_ClickedCallback(hObject, eventdata, handles)
 % hObject handle to uipushtool1 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)
 [filename, pathname] = uiputfile({‘.jpg;.tif;.png;.gif’,‘All Image Files’;…
 ‘.’,‘All Files’ }, ‘保存结果’, …
 ‘Result\result_gui.jpg’);
 if isempty(filename)
 return;
 end
 file = fullfile(pathname, filename);
 f = getframe(gcf);
 f = frame2im(f);
 imwrite(f, file);
 msgbox(‘保存GUI结果图像成功!’, ‘提示信息’, ‘modal’);% --------------------------------------------------------------------
 function uipushtool2_ClickedCallback(hObject, eventdata, handles)
 % hObject handle to uipushtool2 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)axes(handles.axes1); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes2); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes3); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes4); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);handles.file = [];
 handles.MStitch = [];
 handles.grayResult = [];
 handles.RGBResult = [];
 handles.grayListResult = [];
 handles.RGBListResult = [];[filename, pathname, filterindex] = uigetfile({‘.jpg;.tif;.png;.gif;.bmp’,‘All Image Files’;…
 '.*’,‘All Files’ }, ‘选择待处理图像’, …
 ‘.\images\’, ‘MultiSelect’, ‘on’);
 if ~isa(filename, ‘cell’) && isequal(filename, 0)
 return;
 endfile = File_Process(filename, pathname);
 if length(file) < 2
 msgbox(‘请选择至少两幅图像!’, ‘提示信息’, ‘modal’);
 return;
 end
 Img1 = imread(file{1});
 Img2 = ImageList(file);
 axes(handles.axes1);
 imshow(Img1); title(‘图像序列1’, ‘FontWeight’, ‘Bold’);
 axes(handles.axes2);
 imshow(Img2); title(‘图像序列2’, ‘FontWeight’, ‘Bold’);handles.Img1 = Img1;
 handles.Img2 = Img2;
 handles.file = file;
 guidata(hObject, handles);% — Executes on button press in pushbutton1.
 function pushbutton1_Callback(hObject, eventdata, handles)
 % hObject handle to pushbutton1 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)
 axes(handles.axes1); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes2); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes3); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);
 axes(handles.axes4); cla reset; box on; set(gca, ‘XTickLabel’, [], ‘YTickLabel’, []);handles.file = [];
 handles.MStitch = [];
 handles.grayResult = [];
 handles.RGBResult = [];dname = uigetdir(‘.\images\风景图像’, ‘请选择待处理图像文件夹:’);
 if dname == 0
 return;
 end
 df = ls(dname);
 if length(df) > 2
 for i = 1 : size(df, 1)
 if strfind(df(i, 😃, ‘.db’);
 df(i, 😃 = [];
 break;
 end
 end
 if length(df) > 2
 filename = fullfile(dname, df(end, 😃);
 pathname = [dname ‘’];
 else
 msgbox(‘请选择至少两幅图像!’, ‘提示信息’, ‘modal’);
 return;
 end
 else
 msgbox(‘请选择至少两幅图像!’, ‘提示信息’, ‘modal’);
 return;
 end
 file = File_Process(filename, pathname);
 if length(file) < 2
 msgbox(‘请选择至少两幅图像!’, ‘提示信息’, ‘modal’);
 return;
 end
 Img1 = imread(file{1});
 Img2 = ImageList(file);
 axes(handles.axes1);
 imshow(Img1); title(‘图像序列1’, ‘FontWeight’, ‘Bold’);
 axes(handles.axes2);
 imshow(Img2); title(‘图像序列2’, ‘FontWeight’, ‘Bold’);handles.Img1 = Img1;
 handles.Img2 = Img2;
 handles.file = file;
 guidata(hObject, handles);% — If Enable == ‘on’, executes on mouse press in 5 pixel border.
 % — Otherwise, executes on mouse press in 5 pixel border or over pushbutton1.
 function pushbutton1_ButtonDownFcn(hObject, eventdata, handles)
 % hObject handle to pushbutton1 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% — Executes on mouse press over axes background.
 function axes1_ButtonDownFcn(hObject, eventdata, handles)
 % hObject handle to axes1 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% — Executes on mouse press over axes background.
 function axes2_ButtonDownFcn(hObject, eventdata, handles)
 % hObject handle to axes2 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% — Executes on mouse press over axes background.
 function axes3_ButtonDownFcn(hObject, eventdata, handles)
 % hObject handle to axes3 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% — Executes on mouse press over axes background.
 function axes4_ButtonDownFcn(hObject, eventdata, handles)
 % hObject handle to axes4 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)% — Executes on button press in pushbutton2.
 function pushbutton2_Callback(hObject, eventdata, handles)
 % hObject handle to pushbutton2 (see GCBO)
 % eventdata reserved - to be defined in a future version of MATLAB
 % handles structure with handles and user data (see GUIDATA)if isempty(handles.file)
 msgbox(‘请先载入图像!’, ‘提示信息’, ‘modal’);
 return;
 end
 if isempty(handles.MStitch)
 msgbox(‘请先进行图像匹配!’, ‘提示信息’, ‘modal’);
 return;
 end
 if ~isempty(handles.grayResult)
 msgbox(‘灰度拼接图像已完成!’, ‘提示信息’, ‘modal’);
 return;
 end
 if length(handles.file)
 [MStitch, result] = GrayMain_Process(handles.MStitch, …
 handles.W_box, handles.H_box, handles.bdown);
 end

⛄三、运行结果

opencv 全景拼接测试用图_matlab_02

⛄四、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
[1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020.

3 备注
简介此部分摘自互联网,仅供参考,若侵权,联系删除

🍅 仿真咨询
1 各类智能优化算法改进及应用

生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化

2 机器学习和深度学习方面
卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断

3 图像处理方面
图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知

4 路径规划方面
旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化

5 无人机应用方面
无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配

6 无线传感器定位及布局方面
传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化

7 信号处理方面
信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化

8 电力系统方面
微电网优化、无功优化、配电网重构、储能配置

9 元胞自动机方面
交通流 人群疏散 病毒扩散 晶体生长

10 雷达方面
卡尔曼滤波跟踪、航迹关联、航迹融合