徐慧 李明志



摘要:如何判斷數十張相片拼接而成的全景圖是否順利,并精準高效的查找出其中的問題,是技術人員與教師遇到的一個難題,現在主流的拼接軟件只能完成合成,當合成失敗時,無法檢測問題所在。針對上述問題,開發了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.
【通聯編輯:謝媛媛】