汪 沛
(北京林業(yè)大學(xué)電子信息科學(xué)與技術(shù)系,北京 100083)
傳統(tǒng)的C語(yǔ)言教學(xué)偏重于讓學(xué)生從熟悉基本概念和規(guī)則開(kāi)始,逐漸過(guò)渡到簡(jiǎn)單算法的編程實(shí)現(xiàn)和程序設(shè)計(jì)開(kāi)發(fā),最終熟悉和掌握C語(yǔ)言程序設(shè)計(jì)的技巧。這種教學(xué)方法從基礎(chǔ)的知識(shí)元素開(kāi)始學(xué)習(xí),然后將這些元素組合開(kāi)發(fā)出具有特定功能的程序。其特點(diǎn)是由點(diǎn)及面,但由于最初較長(zhǎng)時(shí)間的基礎(chǔ)規(guī)則學(xué)習(xí),學(xué)生會(huì)感覺(jué)比較枯燥。
由于圖像處理具有直觀、形象和生動(dòng)的特點(diǎn),因此筆者提出在“高級(jí)語(yǔ)言程序設(shè)計(jì)”的授課中基于OpenCV庫(kù)開(kāi)發(fā)程序,先讓學(xué)生感受C語(yǔ)言編程的強(qiáng)大功能,以提高學(xué)生的興趣,然后再剖析程序,向?qū)W生解釋講授各個(gè)知識(shí)點(diǎn)。OpenCV是Intel公司開(kāi)發(fā)的開(kāi)源計(jì)算機(jī)視覺(jué)庫(kù),包含了大量的圖像處理、結(jié)構(gòu)分析、運(yùn)動(dòng)分析和目標(biāo)跟蹤等相關(guān)函數(shù)[1]。學(xué)生能夠基于OpenCV庫(kù)中的函數(shù),較快進(jìn)行相關(guān)領(lǐng)域的二次開(kāi)發(fā)。
為增強(qiáng)教學(xué)過(guò)程中學(xué)生的興趣,筆者選取一張功夫熊貓的圖片作為實(shí)驗(yàn)中所用的處理圖像。為了方便后續(xù)處理,利用OpenCV庫(kù)中的cvCvtColor函數(shù)將彩色圖像轉(zhuǎn)換為灰度圖像。
在本次教學(xué)中,擬基于OpenCV庫(kù)中的函數(shù)實(shí)現(xiàn)兩類圖像處理操作:圖像翻轉(zhuǎn)操作和圖像邊緣檢測(cè)操作。通過(guò)向?qū)W生展示兩類操作所得到的處理結(jié)果,進(jìn)一步提高學(xué)習(xí)興趣,同時(shí)向?qū)W生強(qiáng)調(diào)C語(yǔ)言中如下一些關(guān)鍵概念并深化理解:①數(shù)組的操作;②函數(shù)的操作;③指針作為函數(shù)參量的應(yīng)用;④結(jié)構(gòu)體變量的使用及成員訪問(wèn)。
在C語(yǔ)言中,圖像大多用數(shù)組來(lái)表示,灰度圖像是用二維數(shù)組表示,彩色圖像是用三維數(shù)組來(lái)表示。圖像的翻轉(zhuǎn)則可以看成是數(shù)組元素的位置調(diào)換;而圖像邊緣檢測(cè)則是依照一定的規(guī)律尋找數(shù)組元素中的特定信息。
由于采用了OpenCV庫(kù),因此圖像處理的整個(gè)過(guò)程中更是貫穿函數(shù)的概念。彩色圖像至灰度圖像的轉(zhuǎn)換、圖像垂直或者水平翻轉(zhuǎn)、以及圖像邊緣檢測(cè)都是用函數(shù)來(lái)完成。函數(shù)的調(diào)用使主函數(shù)的結(jié)構(gòu)清晰,各個(gè)部分一目了然。
在C語(yǔ)言中,有多種方法可以在主函數(shù)和圖像操作函數(shù)之間傳遞數(shù)組元素信息,OpenCV庫(kù)函數(shù)中采用的是指針的方式。指針的訪問(wèn)方式具有形式靈活和效率高的特點(diǎn)。
在OpenCV中最重要的結(jié)構(gòu)體是IplImage結(jié)構(gòu),主要用于圖像處理方面。IplImage結(jié)構(gòu)來(lái)自于Intel Image Processing Library,OpenCV只支持其中的一個(gè)子集[2]。IplImage結(jié)構(gòu)中包含了圖像大小、寬度、高度和像素位深度等信息,這些成員信息都可以在程序中進(jìn)行訪問(wèn)和輸出。
由上述分析不難發(fā)現(xiàn),這些C語(yǔ)言中的關(guān)鍵概念在本次教學(xué)方案中都有所涉及。通過(guò)上述形象生動(dòng)的圖像變換操作,學(xué)生會(huì)對(duì)這些概念有非常深的印象,這時(shí)輔以說(shuō)明和引導(dǎo)可以使學(xué)生加深理解。
利用OpenCV庫(kù)中的cvFlip函數(shù),圖像可以非常容易實(shí)現(xiàn)垂直翻轉(zhuǎn)、水平翻轉(zhuǎn)和垂直又水平翻轉(zhuǎn)。cvFlip函數(shù)的具體說(shuō)明如下:
其中,src代表原數(shù)組;dst是目標(biāo)數(shù)組,如果dst=NULL表示翻轉(zhuǎn)是在內(nèi)部替換;flip_mode是指定如何翻轉(zhuǎn)數(shù)組,flip_mode=0表示沿X軸翻轉(zhuǎn),flip_mode>0表示沿Y軸翻轉(zhuǎn),flip_mode<0表示沿X軸后沿Y軸翻轉(zhuǎn)。
利用cvFlip函數(shù)實(shí)現(xiàn)圖像垂直翻轉(zhuǎn)結(jié)果見(jiàn)圖1,其中(a)為原始圖像,(b)為垂直翻轉(zhuǎn)后的圖像。
圖1 原始圖像和翻轉(zhuǎn)圖像
同樣,我們利用OpenCV庫(kù)中的cvSobel函數(shù)、cvCanny函數(shù)和cvLaplace函數(shù),可以在圖像中分別實(shí)現(xiàn)Sobel、Canny和Laplacian三種算子的邊緣檢測(cè),三個(gè)函數(shù)說(shuō)明如下:
圖2是三種不同算子的邊緣檢測(cè)結(jié)果。由結(jié)果可以很容易知道,當(dāng)采用不同的邊緣檢測(cè)方法時(shí),所得到的結(jié)果是迥然不同的。而OpenCV的輔助文檔中有對(duì)這三個(gè)函數(shù)的具體使用說(shuō)明和三種算子的具體描述。三種邊緣檢測(cè)方法都不復(fù)雜,因此可以引導(dǎo)學(xué)生自己查詢文檔和研究算法,并嘗試讓學(xué)生自己編寫三種邊緣檢測(cè)方法的函數(shù)。
圖2 邊緣檢測(cè)結(jié)果
通過(guò)對(duì)指向原始圖像和各處理結(jié)果的IplImage結(jié)構(gòu)體指針變量中的各成員變量進(jìn)行訪問(wèn),可以在程序中實(shí)時(shí)獲取各個(gè)圖像的相關(guān)信息[3]。如通過(guò)下述語(yǔ)句輸出原圖像的幾個(gè)重要信息:
在上述這段程序中,首先通過(guò)cvLoadImage函數(shù)打開(kāi)名為gongfupanda的jpg格式彩色圖片。隨后通過(guò)IplImage結(jié)構(gòu)體中的成員變量輸出相關(guān)信息。在程序中,對(duì)成員變量的訪問(wèn)采用了兩種形式,需要讓學(xué)生注意兩種形式的差異和特點(diǎn)。
除了前文中所談及的函數(shù),程序中還使用cvCreateImage函數(shù)創(chuàng)建頭并分配數(shù)據(jù);使用cvN-amedWindow函數(shù)創(chuàng)建顯示窗口;使用cvShowImage函數(shù)在指定窗口中顯示圖像;使用cvReleaseImage函數(shù)釋放頭和圖像數(shù)據(jù)。此處,舉例顯示原始圖像的相關(guān)代碼如下:
其中,CV_WINDOW_AUTOSIZE表示用戶不能手動(dòng)改變窗口大小,窗口大小會(huì)自動(dòng)調(diào)整以適合要顯示的圖像。顯然,基于OpenCV庫(kù)函數(shù)的程序結(jié)構(gòu)非常簡(jiǎn)潔。針對(duì)程序特點(diǎn)可以推薦學(xué)生采用函數(shù)完成特定功能,實(shí)現(xiàn)模塊化設(shè)計(jì)的編程思維。
由于OpenCV的開(kāi)源特性,學(xué)生可以查詢到其中很多庫(kù)函數(shù)的實(shí)現(xiàn)算法甚至源碼,比較適合學(xué)生在課程結(jié)束之后進(jìn)一步自學(xué)。OpenCV的開(kāi)源特性也使得其在工業(yè)界得到了廣泛的青睞,因此學(xué)生對(duì)OpenCV的學(xué)習(xí)也可以直接提高實(shí)戰(zhàn)能力、縮短與企業(yè)用人需求的對(duì)接時(shí)間。
本文通過(guò)采用開(kāi)源的OpenCV庫(kù)函數(shù)來(lái)實(shí)現(xiàn)對(duì)圖像的翻轉(zhuǎn)以及邊緣檢測(cè)操作,能夠增加學(xué)生對(duì)學(xué)習(xí)C語(yǔ)言的興趣,同時(shí)又將C語(yǔ)言的多種關(guān)鍵知識(shí)點(diǎn)融入其中,從而達(dá)到寓教于樂(lè)的目的。此外,OpenCV具有非常強(qiáng)的實(shí)用性,能夠提升學(xué)生解決實(shí)際問(wèn)題的能力,有效增強(qiáng)編程實(shí)力,為以后的繼續(xù)學(xué)習(xí)深造和就業(yè)夯實(shí)C語(yǔ)言編程基礎(chǔ)。
[1]Gary Bradski,Adrian Kaebler.Learning OpenCV[M].南京:東南大學(xué)出版社,2009年
[2]劉瑞禎,于仕琪.OpenCV教程[M].北京:北京航空航天大學(xué)出版社,2007年
[3]陳勝勇,劉盛.基于OpenCV的計(jì)算機(jī)視覺(jué)技術(shù)實(shí)現(xiàn)[M].北京:科學(xué)出版社,2008年.