網頁

搜尋此網誌

2010年6月30日 星期三

Collections and Generics in C Sharp C#的集合和泛型

談談C#程式語言中好用的資料類型:集合(Collections)泛型(Generics),這兩個資料類型簡單來說跟陣列(Array類別System命名空間)功能相同,都是用來表示「一組聚集在一起相同類型的物件資料」,但是集合和泛型提供更多好用的功能,因此撰寫程式時會更加方便,比方說:可以任意擴充大小的資料容量、可以放置不同類型的物件...這些魔法。

集合和泛型的所屬命名空間是:
  • System.Collections
    包含介面和類別,定義各種集合的物件,例如清單、佇列、位元陣列、雜湊表和字典。簡單集合是強型別 (Strongly Typed),不需要轉型(Cast)。
  • System.Collections.Generic
    包含定義了泛型集合的介面和類別,可讓使用者建立強型別 (Strongly Typed) 的泛型集合,以提供比非泛型強型別集合更好的型別安全 (Type Safety) 和效能。
泛型是在C#與.NET Framework 2.0 版和更新版本才有的功能,泛型比集合有更好的效能和安全性,因此建議撰寫程式都使用泛型!主要是因為泛型(Generics)沒有型別的Boxing和Unboxing動作,因此效率與安全性都比較好。

集合(Collections)中常用的類別有:ArrayListQueueStack這幾個類別,而要建立自己的集合類別,則可以使用CollectionBaseDictionaryBase兩個類別繼承擴充。

在System.Collections命名空間中定義幾個常用的介面:
  • ICollection
    定義所有非泛型集合的大小、列舉值和同步方法。
  • IEnumerable
    公開能逐一查看非泛型集合內容一次的列舉值。
  • IList
    表示可以個別由索引存取之物件的非泛型集合。
  • IDictionary
    表示索引鍵/值組的非泛型集合。
CollectionBase繼承介面有ICollection、IEnumerable和IList,而DictionaryBase繼承的介面則有ICollection、IEnumerable和IDictionary,看到差異差異了嗎!由於集合都有繼承IEnumerable介面,因此都可以使用foreach陳述式操作。

泛型(Generics)的功能則是更強更好用!常用的類別有:Dictionary(Of TKey, TValue)LinkedList(Of T)List(Of T)Queue(Of T)Stack(Of T)。在System.Collections.Generic命名空間中也提供很多結構和介面可以使用,如果要自己定義泛型,通常是使用<T>這樣的方式,詳細請參閱泛型 (C# 程式設計手冊),泛型功能很強大,比較複雜所以要花時間仔細閱讀。

對於C++的程式設計人員,C#的泛型相當於C++中的樣板(Template)

2010年6月29日 星期二

Morphological Image Processing 形態學影像處理

形態學影像處理(Morphological Image Processing),依據 Gonzalez與Woods的書本上說明\:影像處理的形態學是依據數學形態學(Mathematical Morphology, MM)的應用之一,並且是以數學理論為運算的基礎(集合理論,Set Theory)。

使用形態學處理影像,其輸入是影像,而輸出是影像所擷取的特徵和屬性,有點算是影像分析。運算中,通常會定義一個結構元素(Structuring Element, SE),結構元素是一個小集合或子影像,其大小通常是3X3像素且原點在中心。

形態學影像處理的基本運算有兩個基礎:
  • Erosion侵蝕
    集合A被結構元素B侵蝕,記為A⊝B
  • Dilation擴張(膨脹)
    集合A被結構元素B擴張,記為A⊕B
形態學的其他運算(基於DilationErosion):
  • Opening斷開
    集合A被結構元素B斷開,記為A∘B
  • Closing閉合
    集合A被結構元素B閉合,記為A∙B
  • The Hit-or-Miss Transformation交離轉換
    B=(B1, B2),A⊛B=(A⊝B1)⋂[AC⊝B2)]
  • Boundary Extraction邊界抽取
    β(A)=A-(A⊝B)
  • Hole Filling填洞
  • Extraction of Connected Components連通成分抽取
  • Convex Hull凸形封包
  • Thinning細線化
    集合A被結構元素B細線化,A⊗B=A-(A⊛B)=A⋂(A⊛B)C
  • Thickening厚化
    集合A被結構元素B厚化,A⊙B=A⋃(A⊛B)
  • Skeletons骨架
  • Pruning剪除
  • Morphological Reconstruction形態學的重建
基本上來說,形態學影像處理是影像分析(Image Analysis)的基礎,利用更進一步的運算處理,我們可以分析影像中的資訊。持續研究Image Processing...

2010年6月24日 星期四

Graphics Device Interface 繪圖裝置介面

談談Windows的繪圖裝置介面(Graphics Device Interface, GDI),當我們要呈現影像在Windows中,一定會撰寫GDI的程式。

根據MSDN上的解釋:http://msdn.microsoft.com/en-us/library/ms536380%28v=VS.85%29.aspx
「As its name suggests, GDI+ is the successor to Windows Graphics Device Interface (GDI), the graphics device interface included with earlier versions of Windows. Windows XP or Windows Server 2003 supports GDI for compatibility with existing applications, but programmers of new applications should use GDI+ for all their graphics needs because GDI+ optimizes many of the capabilities of GDI and also provides additional features.


就目前而言,Windows作業系統都是使用XP以後的版本,因此現在多使用也建議以GDI+的API開發,而在.NET Framework中相關GDI+元件的命名空間有:
我們在撰寫GDI的程式上有一個觀念很重要:Windows作業系統不會記憶任何視窗上面顯示的內容。換句話說,內容必須由我們的應用程式負責處理,這通常是OnPaint()事件處理常式在做的事情。

利用Graphics類別,我們可以操作GDI+繪圖介面去做我們想要做的事情,也就是在視窗上繪圖,這裡要特別注意,使用Graphics必須呼叫Dispose()釋放所使用的所有資源,不然就是使用using 陳述式。一般來說,在OnPaint()事件處理常式中使用Graphics物件對視窗繪圖,這樣視窗每次收到Paint事件時,就會保持視窗內容的樣子,而不會是一片空白(因為Windows作業系統不會幫你繪圖)。

取得Graphics物件的方式有兩個方法:
  1. 一個是前述的OnPaint()事件處理常式中,利用PaintEventArgs參數取得所需要繪製的Graphics物件,也可以使用ClipRectangle屬性取得要繪製的矩形Rectangle結構
  2. 呼叫視窗(控制項)的CreateGraphics()方法取得。
另外,常用的影像物件是Bitmap物件(點陣圖),Bitmap可以讀取和存檔的類型有:BMP、GIF、EXIG、JPG、PNG 及 TIFF(對於一般程式撰寫已經夠用了),你可以使用GetPixelSetPixel方法為影像重新上色,這裡不建議使用這種方式,GetPixel和 SetPixel方法的效能不好,建議使用BitmapData的操作方式,效能上可以加速一個數量級左右

重點在於:使用.NET Framework的影像處理,你要用Array運算,處理之後將Array的資料轉換至BitmapData,影像處理用Array,而影像呈現還是用Bitmap,如此就能解決效能瓶頸的問題。

使用BitmapData的方式如下,注意到要使用Bitmap類別的LockBitsUnlockBits方法。參考http://msdn.microsoft.com/zh-tw/library/5ey6h79d%28v=VS.90%29.aspx
// Create a new bitmap.
Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

// Lock the bitmap's bits.  
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
    bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
    bmp.PixelFormat);

// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;

// Declare an array to hold the bytes of the bitmap.
int bytes  = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];

// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

// Set every third value to 255. A 24bpp bitmap will look red.  
for (int counter = 2; counter < rgbValues.Length; counter += 3)
    rgbValues[counter] = 255;

// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

// Unlock the bits.
bmp.UnlockBits(bmpData);

另外,Bitmap的PixelFormat建議使用Format32bppArgb的格式,也就是每像素 32 位元,各有 8位元用於 Alpha、Red、Green和Blue,雖然大多數的影像都24位元的Format24bppRgb,但是在使用BitmapData複製記憶體時,最好每個Stride(掃描寬度)是4bytes的倍數,避免記憶體對映到Bitmap發生影像的移位錯誤。

2010年6月12日 星期六

Digital Image Processing 數位影像處理

One picture is worth more than ten thousand words.
(A picture is worth a thousand words.)

今天介紹數位影像處理(Digital Image Processing)的聖經,這本書是在念碩士班的時候,三位研究影像處理的同學介紹的參考書籍。當時我覺得數位影像處理很有趣,不過因為和自己研究的Web方向不同,我一直遲遲沒有去研究,現在因為需要而自修數位影像處理,順便和大家分享入門的知識。


Rafael C. Gonzalez, Richard E. Woods原著,繆紹綱譯,數位影像處理,台北縣:普林斯頓國際,2009。
http://www.prenhall.com/gonzalezwoods/

首先,關於「玩影像」這件事可以分成三個層次,如下:
  • 電腦視覺(Computer Vision)
    高階,輸入資料是影像,輸出資料是理解影像的資訊,目標是電腦模仿人類視覺的能力。電腦視覺的應用則稱為機器視覺(Machine Vision),通常是用在製造業的工廠自動化上。
  • 影像分析(Image Analysis)
    中階,輸入資料是影像,輸出資料是萃取影像的特徵。
  • 影像處理(Image Processing)
    低階,輸入資料是影像,輸出資料也是影像,兩者差異在於影像經過運算處理。
關於影像的成因不外乎就是「光線」,廣義為電磁波,在這個電磁波頻譜上可以區分為(依照能量大至小排列):

Gamma射線 > X光 > 紫外線 > 可見光 > 紅外線 > 微波 > 無線電波

也有其他可以做為成像的來源,例如超音波、電子顯微鏡和電腦合成的抽象影像等,所以我們研究影像時不要僅限於我們眼睛所看到的影像而已,影像處理的技術可以用在許多面向。

影像處理的步驟有:
  1. 影像擷取(image acquisition)
  2. 影像濾波與增強(image filtering and enhancement)
  3. 影像復原(image restoration)
  4. 彩色影像處理(color image processing)
  5. 小波與多解析度處理(wavelet and multiresolution processing)
  6. 壓縮(compression)
  7. 形態學處理(morphological processing)
  8. 分割(segmentation)
  9. 表示與描述(representation and description)
  10. 識別(recognition)
還有支持影像處理與分析所需要的「知識庫」,研究中...

熱門文章