盧 興, 陳曉勇
(1.東華理工大學測繪工程學院,江西 南昌 330013;2.流域生態(tài)與地理環(huán)境監(jiān)測國家測繪地理信息局重點實驗室,江西 南昌 330013)
1984年,美國 MathWorks 公司首次推出MATLAB軟件,MATLAB擁有國際公認的最優(yōu)秀的數(shù)值計算和仿真分析能力,其科學計算與可視化功能強大,它提供了一個功能完善的程序設計和數(shù)據(jù)處理集成環(huán)境(李雯,2016)。MATLAB是一個高度集成的模塊化系統(tǒng),集科學計算 、圖象處理等于一體,使用解釋性語言,具有極高的編程效率(Shen et al.,2005)。MATLAB雖然有眾多優(yōu)點,但缺點也不少:其提供的M語言需要逐行解釋執(zhí)行,效率較低,界面開發(fā)能力差,十分依賴MATLAB運行環(huán)境(朱艷平,2016)。
C#(C sharp)是微軟于2000年推出的一種以面向對象為編程理念的高級編程語言。C#與C/C++語言相比,C#編程更加簡易、安全,而且是以面向對象為編程思想的獨特編程語言。因為這種繼承關系,C#與C/C++具有極大的相似性,熟悉類似語言的開發(fā)者可以很快的轉向C#( Roberto et al.,2003)。
C#擁有優(yōu)良的用戶應用界面設計與開發(fā)能力,具備許多種類的界面高級設置。而MATLAB則擁有優(yōu)秀的數(shù)值計算能力。MATLAB中的函數(shù)儲存在.m腳本文件中,并對用戶完全開放,用戶可以隨時修改文件中的內(nèi)容。利用MATLAB中提供的函數(shù)和算法實現(xiàn)某些功能的編寫,而主體軟件和界面用C#.NET進行開發(fā)(王文斌等,2015)。充分結合兩者的優(yōu)點,可以更加高效地設計出優(yōu)秀的應用軟件,用途廣泛,前景廣闊。
混合編程即在一個軟件的開發(fā)過程中,將不同方面,不同階段的編程、算法或數(shù)據(jù)處理分別由相應方面能力更強的軟件去執(zhí)行,最后完成優(yōu)勢互補,開發(fā)成效率更高的軟件。
在混合編程研究方面,許多專業(yè)人員取得了良好的研究成果。張燕等(2008)利用M函數(shù)文件編譯成C共享庫的方法實現(xiàn)了C#與MATLAB混編;Bistak(2013)利用C#與MATLAB/Simulink混合編程開發(fā)遠程控制實驗室系統(tǒng),并介紹了該系統(tǒng)在磁懸浮與液壓系統(tǒng)中的應用;許茂增等(2015)運用C#與MATLAB混合編程設計并實現(xiàn)了物流需求預測系統(tǒng),并在實例中表現(xiàn)出該系統(tǒng)良好的適用性與高預測精度。
(1)C#直接調(diào)用MATLAB程序文件。MATLAB以自身為引擎,提供了一系列可供其他程序調(diào)用的函數(shù),其他編程軟件可以通過這些函數(shù)來調(diào)用MATLAB程序。該引擎提供的3個常用接口為:Execute、PutFullMatrix、GetFullMatrix。其功能分別是:執(zhí)行腳本命令、從MATLAB Server中添加矩陣和讀取矩陣(曹洪濤等,2015)。
(2)C#調(diào)用MATLAB編譯器生成的C語言共享庫。MATLAB編譯器模塊能夠生成多種共享庫,其中便包括C語言共享庫。C語言共享庫是可與外界程序鏈接的函數(shù)接口庫。
(3)使用MATLAB DeployTool生成.Net組件或.com組件。COM(組件對象模型,Componet Object Model)是以組件為發(fā)布單元的對象模型,該模型有利于各個軟件組件之間采用統(tǒng)一的格式相互通訊,使得不同語言程序之間可以相互調(diào)用(朱峰等,2011)。由MATLAB編譯器生成的.Net獨立組件是動態(tài)鏈接庫dll文件,可以脫離MATLAB環(huán)境與其他任何支持集成開發(fā)的程序相結合,并在沒有安裝MATLAB的計算機中運行。
在以上三種方法中,第一種方法操作簡單、易行,但是執(zhí)行效率太低,無法脫離MATLAB獨立運行。利用MATLAB生成C語言共享庫的方法使速度明顯提升,但程序不穩(wěn)定,易出錯。利用.com或.Net組件的方法生成的動態(tài)鏈接庫dll文件可脫離MATLAB環(huán)境,較好的與其他程序結合,且生成和編譯過程較簡單,效率頗高。綜上所述,實際應用過程中采用C#調(diào)用.Net組件或.com組件的方法最為合適。
20世紀中期,人們對數(shù)字圖像處理的研究步入正軌。數(shù)字圖像處理(Digital Image Processing)是利用計算機的強大能力處理數(shù)字圖像,從而增強數(shù)字圖像的識別度、信息量或專題化等等的方法和技術。圖像處理的目的是恢復圖像的本來面目,改善人的視覺效果,突出圖像中目標物的某些特征,提取目標物的特征參數(shù)(李俊山等,2006)。常見的處理有圖像數(shù)字化、圖像增強、圖像復原、圖像分割、圖像分析等(陳汗青等,2013)。
圖像可能由于各類原因導致圖像數(shù)據(jù)破壞,通常利用圖像增強來改善圖像數(shù)據(jù)質(zhì)量。圖像增強是利用各種數(shù)學方法和變換手段來提高圖像的對比度和清晰度(劉治群等,2010)。濾波是圖像增強的常用方法,圖像濾波可以去除圖像中的噪聲或突出特征以恢復或提升圖像質(zhì)量。
圖像分割:即把圖像劃分為幾個特定部分,從中提取出對人類有用的對象。圖像分割是計算機視覺和圖像處理領域具有挑戰(zhàn)的重要問題,它在圖像檢索、目標識別和圖像分析等更高級的任務中充當著基本的,也是關鍵的一步(何斌等,2001)。分割方法大致分為三種:基于閾值的分割方法、基于區(qū)域的分割方法、基于邊緣的分割方法(殷國軍等,2009)。
MATLAB提供的圖像處理工具箱(Image Processing Toolbox),是利用MATLAB強大的數(shù)學計算能力,提供可參照的標準算法和圖形工具給用戶,并實現(xiàn)廣泛的圖像處理操作(楊保華等,2016)。MATLAB中的部分圖像處理函數(shù)如下:
rgb2gray():該函數(shù)能實現(xiàn)圖像的灰度化,向該函數(shù)輸入圖像矩陣即可得相應圖像的灰度圖。
imhist():該函數(shù)可計算輸入圖像的灰度值信息,并顯示相應直方圖。
histeq():該函數(shù)可實現(xiàn)直方圖的均衡化處理。
imnoise():該函數(shù)可向圖像中加入噪聲,輸入值可自定義噪聲類型與參數(shù)。
imfilter():該函數(shù)能對多位圖像進行濾波處理,輸入值中可自定義模版與參數(shù)。
medfilt2():該函數(shù)用于圖像的中值濾波處理。輸入值中可自定義模版與參數(shù)。
fspecial():該函數(shù)可創(chuàng)建自定義的濾波算子。輸入值中可自定義算子類型與參數(shù)。
edge():該函數(shù)用于邊緣檢測。輸入值中包括6種算法類型:Sobel,Prewitt,Roberts,Laplacian,均值(zero-cross),Canny。
在混合編程前,設計程序的界面與框架。程序中包含多種經(jīng)典圖像處理功能以及必要的基礎功能。程序的框架如圖1所示。
圖1 混合編程程序框架Fig.1 Mixed programming framework
(1)MATLAB函數(shù)編譯工作。C#與MATLAB混合編程需要用到MATLAB中的圖像處理函數(shù),因此在混編之前,需要運用MATLAB提供的編譯工具(DeployTool)將這類函數(shù)編譯成.NET組件。
研究中所使用的MATLAB版本號為R2015b。編譯過程為:打開MATLAB,在主窗體Command Window中輸入Deploy指令,打開Deployment Project窗口,輸入自定義的文件名稱,存儲位置以及編譯類型,編譯類型選擇.Net Assembly。
在生成的.Net組件內(nèi)容構筑中,加入自定義的類名并向類中添加要編譯的 MATLAB函數(shù).m文件。最后選擇Build完成.Net組件的生成。
(2)C#調(diào)用.Net組件。在混合編程項目的引用中添加.Net組件,MWArray.dll和CsharpMATLABMix.dll文件,并添加到相應的命名空間,主要代碼如下:
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using CsharpMATLABMix;
(3)C#與MATLAB數(shù)據(jù)傳遞。因為C#與MATLAB之間的語言思路與計算方式不同,數(shù)據(jù)間無法直接傳遞。因此,.Net組件中運用MWArray類型作為中間類型,使得C#中數(shù)據(jù)的類型與MATLAB中數(shù)據(jù)的類型皆可轉換至MWArray類型,從而達到相互轉換的目的。.Net數(shù)據(jù)類型、MATLAB類型與MWArray類三者間的轉換表如下(表1)。
(4)C#圖像處理。C#編程過程中,需要用到C#的圖像處理方法。C#中常用的三種圖像處理方法分別是:像素法、內(nèi)存法與指針法。其中像素法最簡單,核心思想是利用Bitmap類中的GetPixel與SetPixel方法獲取與設置圖像中一個指定的像素的顏色。使用像素法需要對每一個像素進行提取和重新設置顏色,方法簡單,操作方便,但效率太慢,導致性能大大降低,運行時間太長,在實際項目中是不可取的。
表1 MATLAB類型、.Net類型與MWArray類轉換表
內(nèi)存法的核心思想是利用鎖定位圖的方式將圖像鎖定并復制于內(nèi)存中,然后對內(nèi)存中的圖像數(shù)據(jù)直接進行處理。內(nèi)存法的圖像處理效率比像素法明顯有極大的提高,代碼難度較為一般,不難編寫。內(nèi)存法的關鍵代碼如下:
Bitmap bitImage = new Bitmap(image);
Rectangle rt = new Rectangle(0, 0, bitImage.Width, bitImage.Height);
//鎖定位圖并設置相關屬性
BitmapData bmpData = bitImage.LockBits (rt,ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
指針法直接運用指針的特殊性能來進行圖像的處理,運行速度比內(nèi)存法更快,但其不足是編碼較難,不易掌握,而且使用不安全代碼需要承擔風險,一旦代碼有誤,可能引發(fā)安全性問題,造成更多損失。
通過以上分析,本文程序中主要運用內(nèi)存法編寫圖像處理代碼,內(nèi)存法處理效率遠遠高于像素法,處理速度上稍慢于指針法,但代碼安全度高,不易出現(xiàn)安全性錯誤,是相對合理的一種方法。
(5)C#與MATLAB混編函數(shù)應用。使用內(nèi)存法加載圖像數(shù)據(jù)后,將其加入編譯函數(shù)中處理,最后輸出處理完成的圖像數(shù)據(jù)。且在C#編寫中,函數(shù)的使用與MATLAB中對應函數(shù)的使用是幾乎一致的。以函數(shù)filter2()為例:
函數(shù)filter2()的調(diào)用格式如下:
Y=filter2(B,X),參數(shù)說明:filter2()使用矩陣B中的二維FIR濾波器對數(shù)據(jù)X進行濾波,如果Y是通過二維互相關計算出來的,其大小與X一樣。
在C#中實際應用代碼如下:
ImageSmoothingSharpening iss = new ImageSmoothingSharpening();
MWArray smoothingDate = iss.filter2(iss.fspecial("average", 3), mwDate);
其中,mwDate為待處理的圖像數(shù)據(jù)。函數(shù)fspecial()的作用是依據(jù)輸入?yún)?shù)輸出相應模版,用于圖像的濾波處理。函數(shù)fspecial()的調(diào)用格式如下:
h=fspecial(type)
h=fspecial(type,para)
參數(shù)說明:type:指定算子的類型;para指定相應的參數(shù);h:返回的模版。
運用C#與MATLAB混合編程實現(xiàn)的圖像處理程序中實現(xiàn)了多項功能,其中除了基本功能外,所有圖像處理功能都是基于C#與MATLAB混合編寫的。在函數(shù)的使用方面,C#與MATLAB的混合編程具有較高的兼容性,這使得編程人員可以更方便地使用混合編程中的函數(shù)。而基于C#與MATLAB混合編程的圖像處理效果也較為理想。在程序編寫過程中,使用東華理工大學南昌校區(qū)高分影像作為程序的實驗圖像(圖2)。處理成果見圖3至圖5。
圖2 程序界面與原圖Fig.2 program interface master map
圖3 均值濾波處理后的圖像Fig.3 Image processed by mean filter
圖4 Sobel算子邊緣檢測圖Fig.4 Edge detection graph of Sobel operator
圖5 迭代分割效果圖Fig.5 Iterative segmentation effect diagram
本文針對580*800的8位圖像,分別使用C#語言、MATLAB語言與混合編程方法,在CPU為i3-2310,內(nèi)存為4G的PC機進行線性濾波和迭代分割,其結果如表2、表3所示。
表2 三種編程方法實現(xiàn)圖像線性濾波
表3 三種編程方法實現(xiàn)圖像迭代分割
從以上兩個實驗中可以看出,MATLAB擁有良好的科學計算能力,能夠用較簡短的代碼實現(xiàn)圖像處理方法,缺點是運行較長;C#語言編寫的方法運行時間較快,且越好的代碼運行速度越快,但代碼長度也越長,需要更久的編寫時間;C#與MATLAB混編編寫的所有方法中,其代碼基本都保持在較短的長度,比前兩者方法更加簡化。在運行速度方面, MATLAB運行時間最長,C#編寫方法速度通常最快,C#與MATLAB混編方法能夠保持較快速度,并且個別代碼運行速度快于C#編寫方法。
由此分析可以得出,C#與MATLAB混編方法在代碼長度上比MATLAB編寫方法和C#編寫方法都更加簡化,能用較短代碼實現(xiàn)圖像處理方法?;炀幏椒ㄔ谶\行時間上保持著較快速度,遠快于MATLAB編寫方法。
本文用C#與MATLAB混合編程的方法處理圖像,達到了令人滿意的結果。從上節(jié)分析中可以看出,混編方法極大的縮短了代碼長度,減少了編程工作量,提高了軟件開發(fā)的效率?;旌暇幊谭椒ǔ浞掷昧薓ATLAB強大的計算能力與高效的圖像處理能力,高度結合C#優(yōu)秀的用戶界面開發(fā)能力與C#語言優(yōu)勢,彌補了MATLAB界面開發(fā)能力不足與C#代碼冗長的缺點。以C#與MATLAB混合編程為基礎,可以進一步擴展其他軟件的結合開發(fā),如MATLAB與ArcEngine結合等?;炀幏椒閳D像處理提供了一種提高效率的思路,也為軟件開發(fā)提供了更多的可能。