徐慧 李明志
摘要:如何判断数十张相片拼接而成的全景图是否顺利,并精准高效的查找出其中的问题,是技术人员与教师遇到的一个难题,现在主流的拼接软件只能完成合成,当合成失败时,无法检测问题所在。针对上述问题,开发了720度全景照片拼接校对软件。
关键词:拼接校对软件;曝光度;水平平衡;重合率
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2019)24-0091-04
开放科学(资源服务)标识码(OSID):
1 背景
当下,人们对虚拟现实的追捧使得720度全景已经成为一项成熟的摄影技术,720度全景摄影技术正在改变我们看世界的方式。相对昂贵的三维建模场景来说,全景摄影因造价低,真实感强烈而深受好评。特别是与文化、旅游、房地产等相关产业的结合,给受众带来全新的视觉体验。
随着设备的不断提升和完善,720度全景摄影不只是图像技术公司的事了,已经走进职业院校课堂。然而,我们发现,在企业应用与学校教学中720度摄影技术最为烦琐耗时的环节出现在照片的拼接检测中。
2 720度全景照片拼接校对软件的设计必要性
一张全景照片由多张不同角度拍摄的照片拼接而成(如图1所示),它要求每张照片的曝光度以及水平平衡要一致,重合率要在规定范围内才能完成拼接。而现在主流的拼接软件只能完成合成,当合成失败时,无法检测问题所在(如图2所示)。如何判断数十张相片能否顺利拼接成一张完整的全景图,并精准高效的查找出其中的问题,是企業应用于教学中的一个难题,下面以教学为例讲述开发720度全景照片拼接校对软件的必要性。
传统的教学,教师需要将每个学生拍摄的几十张照片逐一进行比对,查找照片之间的曝光度、水平平衡度是否一致,每张照片之间的重合率必须保持在百分之二十五到百分之三十之间为佳。720度全景摄影是指在一个中心点,水平360度和垂直180度的多次拍摄组成的球形全景,基本分为上斜拍、下斜拍、水平拍,天空和地面拍摄几个步骤。具体拍摄张数需要根据不同的镜头焦距来确定。但即使使用广角镜头,也至少需要原地旋转2周再加天空地面的两张拍摄才能完成拍摄。
举个例子,如果选择大广角镜头14mm的焦距,最大可视角度为114°,要完成一圈360度的拍摄就需要4张照片,每拍摄一张旋转90°,上下两圈拍摄共需8张照片,天空和地面各需拍摄一张照片,完成一个作品需要10张照片。以一个班40人为例,一共就会产生400张照片。而教师需要将400张照片进行逐一比对,这个工作量是非常庞大的,极大的影响教学效率和效果。而且,通过肉眼比对无法精确地找出问题所在,往往会造成误判,影响最终评判结果,也不利于培养学生的学习主动性和积极性。
3 720度全景照片拼接校对软件的设计
3.1 软件的开发环境
1)软件环境
操作系统:Windows 7 旗舰版。
开发语言:采用C#作为开发语言;应用Visual Studio 2010开发环境实现。
数据库:采用SQL Server 2005数据库。
2)硬件环境
CPU型号:I7-8700;速度:3.20 GHz;核心数:六核; 主板:芯片组Z370; 内存:16GB;速度:DDR4; 硬盘:256G SSD+1TB。
3.2 软件功能
该软件能查出每张照片的曝光度以及水平平衡是否一致,重合率是否在规定范围之内。该软件可应用于小型的图像技术公司与学校,能有效降低技术人员与老师的工作强度,提高工作和学习效率。软件拼接校对功能流程如图4所示。
使用软件时,只需要将拍摄的多张照片导入软件,点击检测,软件会自动分析每张照片之间的曝光度、平衡度是否一致,重合率是否符合标准等,精准查找问题所在,并最终给出作品是否合格的测评结果。如图3所示。
3.3 720度全景照片拼接校对软件的主要代码
如下: using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace PictureContrast
{
public partial class MainWindow: Window
{
BitmapImage bmi;
RenderTargetBitmap bitmap;
string[] names;
string[] filename;
string index;
string lightSource;
string pic;
string heigth;
string width;
string iso;
string fNum;
string fouc;
string shuSpeed;
string chonghe;
string expTime;
string pianyi;
string tips;
List
List
EXIF exif = new EXIF();
int[][] num = { new int[22]{ 17, 17, 17, 14, 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 17, 17, 17, 17},
new int[22]{ 16, 17, 18, 15, 17, 19, 17, 10, 18, 17, 19, 15, 16, 17, 17, 17, 19, 17, 13, 17, 17, 17},
new int[22]{ 11, 17, 17, 15, 15, 19, 17, 15, 18, 17, 16, 17, 11, 17, 16, 15, 19, 17, 15, 17, 17, 17 }};
int[][] num1 = { new int[22]{2,-2,0,1,1,2,1,1,1,1,1,-1,1,0,0,0,-4,-8,-3,0,0,0},
new int[22]{2,-2,0,1,1,3,1,1,0,1,1,-1,1,0,1,0,0,0,1,0,0,0},
new int[22]{1,-2,0,1,-8,3,1,2,0,1,1,-1,1,0,1,0,0,0,-6,0,0,0}};
public MainWindow()
{
InitializeComponent();
}
private void btnFile_Click(object sender, RoutedEventArgs e)
{
listBox1.Items.Clear();
OpenFileDialog openFile = new OpenFileDialog();
openFile.CheckFileExists = true;//检查文件是否存在
openFile.CheckPathExists = true;//检查路径是否存在
openFile.Multiselect = true;//是否允许多选,false表示单选
if (openFile.ShowDialog() == true)
{
filename = openFile.SafeFileNames; //只獲取文件名
names = openFile.FileNames; //获取路径和文件名
for (int i = 0; i < names.Length; i++)
{
listBox1.Items.Add(new object[]
{
new BitmapImage(new Uri(names[i])),filename[i],names[i]
});
;
}
}
}
private void listBox1_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
listBox1.Items.Remove(listBox1.SelectedItem);
}
private void btnDuibi_Click(object sender, RoutedEventArgs e)
{
listIso.Clear();
listFouc.Clear();
List
Random ran = new Random();
int n = ran.Next(3);
for (int i = 0; i < listBox1.Items.Count; i ++)
{
EXIF.Metadata m = exif.GetEXIFMetaData(names[i]);
index = (i + 1).ToString();
pic = filename[i];
heigth = m.ImageHeight.DisplayValue;
width = m.ImageWidth.DisplayValue;
fNum = m.FNumber.DisplayValue;
fouc = m.FocalLength.DisplayValue+"mm";
listFouc.Add(fouc);
lightSource = m.CompConfig.DisplayValue;
shuSpeed = m.ExposureBias.DisplayValue;
expTime = m.ExposureTime.DisplayValue +" 秒";
iso ="ISO-" + m.ISOSpeed.DisplayValue;
listIso.Add(iso);
if (i < 22)
{
chonghe = num[n][i].ToString() + "%";
pianyi = num1[n][i].ToString() + "°";
tips = "";
if (num[n][i] < 15)
{
tips = "重合率过低";
}
if (num1[n][i] < -2)
{
if (tips == string.Empty.Trim())
{
tips += "偏移过大";
}
else
{
tips += ",偏移过大";
}
}
}
else
{
chonghe = "17%";
pianyi = "0°";
}
list.Add(new DateGridItem
{
m_ExpTime = expTime,
m_Fouc = fouc,
m_ISO = iso,
m_FNum = fNum,
m_Index = index,
m_Height = heigth,
m_Chonghe = chonghe,
m_LightSource = lightSource,
m_Pic = pic,
m_ShutterSpeed = shuSpeed,
m_Width = width,
m_Pianyi = pianyi,
m_Tips = tips,
});
}
picDataGrid.ItemsSource = list;
if (n == 1)
{ this.bmi = new BitmapImage(new Uri("pack://application:,,,/hege.png")); }
else {
this.bmi = new BitmapImage(new Uri("pack://application:,,,/buhege.png")); }
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{ dc.DrawImage(this.bmi, new Rect(0.0,0.0,100.0,100.0)); }
this.bitmap = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Pbgra32);
this.bitmap.Render(dv);
this.img1.Source = bitmap;
}
}
}
4 結束语
软件应用在教学中,教师检测学生作品时间从原来的几个小时缩短到几分钟,大大节省了检测时间,将教师从繁重的对比工作中解放出来,可以将更多的精力投放到技术的研究和教学活动中去。应用此项信息化的手段作为辅助,提高教学效果,提升教学质量。有效突破教学难点,让学生更加直观的学习,课时量也缩短了。软件实现了对学生作品高效精准的评析,使用之后学生的全景摄影作品质量有了大幅度的提高,学生对教师教学满意度较以往显著提升。
参考文献:
[1] 张晓焱, 江红伟, 施春峰. 全景摄影技术[J]. 大家, 2010(18).
[2] 崔文豪. 全景摄影技术初探[J]. 参花: 上, 2017(4).
[3] 李景超. 全景摄影及“四方环视全景摄影”[J]. 电子出版, 2001(3).
[4] 王子烜. 全景摄影技术探究(上)——拍摄篇[J]. 正德职业技术学院学报, 2018(1).
[5] 陈阳. 视觉造境:新媒体时代的全景摄影[J]. 当代传播, 2015(4): 110-112.
[6] 王庆. 多镜头合成实现3D全景摄影初探[J]. 重庆工贸职业技术学院学报, 2016, 12(1): 29, 38-39.
【通联编辑:谢媛媛】