李振江
摘 要:為了更好地開展數(shù)字圖像處理課程的教學(xué),教師應(yīng)在分析課程實際需求以及語言特點的基礎(chǔ)上,將Python選為課程實踐語言,在引入Python數(shù)字圖像處理基本知識的基礎(chǔ)上,對一些最基本的圖像處理算法進(jìn)行實現(xiàn)。文章就此對Python在數(shù)字圖像處理課程教學(xué)中的應(yīng)用進(jìn)行了分析。
一、引言
數(shù)字圖像處理是一門綜合性多領(lǐng)域交叉的學(xué)科,經(jīng)過多年的發(fā)展,已經(jīng)在機器視覺、自動控制、虛擬現(xiàn)實等領(lǐng)域取得了長足的發(fā)展。很多院校都在本科階段開設(shè)了相關(guān)課程,其教學(xué)目的在于讓學(xué)生了解數(shù)字圖像處理的一般概念,掌握該領(lǐng)域最基本的算法原理以及實現(xiàn)方法,為進(jìn)一步的學(xué)習(xí)打下基礎(chǔ)。
在該課程的教學(xué)實踐中,教師選擇一門合適的語言工具進(jìn)行授課尤為重要。語言工具的選擇要注意這樣幾個問題;首先,語言要易于上手,這樣才能讓學(xué)生較快進(jìn)入圖像處理知識的學(xué)習(xí)而不是在一些編程細(xì)節(jié)上占用過多時間;其次,選擇的語言要與當(dāng)前新技術(shù)有較好的結(jié)合,這樣在學(xué)習(xí)過程中才有助于開拓學(xué)生視野;最后,語言的擴展性要強,便于學(xué)生日后快速在其他相關(guān)領(lǐng)域展開學(xué)習(xí)應(yīng)用。
二、Python語言的特點
1.簡單易用
Python是一種面向?qū)ο蟮慕忉屝驼Z言,在其豐富外部庫的支持下,實現(xiàn)數(shù)字圖像處理的基本算法,通常都只需要不多的幾行代碼,非常方便。一方面,編程能力較低的本科學(xué)生使用Python語言也可以對課程內(nèi)容進(jìn)行實現(xiàn);另一方面,在具體實踐中能讓學(xué)生從煩瑣的底層邏輯(如IO操作、顯示等)中擺脫出來,專注于圖像處理的方法層面。從培養(yǎng)學(xué)生學(xué)習(xí)興趣的角度講,與早期選擇使用的C++等語言相比,大部分學(xué)生都能使用Python完成基本算法的實現(xiàn)并將結(jié)果圖像進(jìn)行顯示,這在初期對學(xué)生的學(xué)習(xí)興趣是一種極大的鼓舞。
2.應(yīng)用廣泛
Python自20世紀(jì)90年代初誕生到現(xiàn)在,在各個領(lǐng)域都得到了廣泛的應(yīng)用。最初它的應(yīng)用較為局限,大都以系統(tǒng)管理和web編程這兩個方面為主。在該語言誕生之初,其一個核心的思想就是開放和開源,在眾多開源社區(qū)的支持下,自2004年以來,Python的使用率有一個明顯的增長。2017年IEEE Spectrum發(fā)布了第四屆頂級編程語言交互排行榜,Python高居排行榜榜首,說明時下Python語言又成為業(yè)界應(yīng)用的熱點。尤其是在科學(xué)計算領(lǐng)域,隨著深度學(xué)習(xí)技術(shù)引發(fā)的人工智能新一輪熱潮,眾多的代碼都是基于Python語言進(jìn)行發(fā)布,給這一領(lǐng)域傳統(tǒng)的霸主MATLAB帶了來巨大的挑戰(zhàn)。
3.擴展性強
Python語言功能強大,有“膠水語言”的別稱,能夠方便地對其他語言實現(xiàn)的功能模塊進(jìn)行調(diào)用。對于某一具體問題,可以使用Python搭建整體框架,然后在不同的位置調(diào)用已有的成熟模塊進(jìn)行實現(xiàn),是一種快速的軟件實現(xiàn)方法。同時Python語言的擴展庫數(shù)目繁多,在很多不同的應(yīng)用領(lǐng)域,都有相應(yīng)的庫與之配合,如數(shù)學(xué)工具庫NumPy、圖形庫Tkinter或者PIL、多媒體封裝庫PyOpenGL、數(shù)據(jù)庫接口MySQLdb、機器學(xué)習(xí)庫scikit-learn等。
結(jié)合數(shù)字圖像處理課程本身的需求以及Python語言的自身特點,選擇Python作為課程講授的語言是較為符合實際需求的。同時,為了便于以后在數(shù)字圖像處理方面的進(jìn)一步學(xué)習(xí),使用了OpenCV的Python庫作為主要的圖像處理工具,同時使用NumPy作為基礎(chǔ)的數(shù)學(xué)庫。
三、Python數(shù)字圖像處理基礎(chǔ)
1.Python的安裝和庫的導(dǎo)入
有兩種方式對Python進(jìn)行安裝,使用第一種方式,在官網(wǎng)下載相應(yīng)操作系統(tǒng)的安裝包對語言本體進(jìn)行安裝,之后根據(jù)應(yīng)用的需求下載相應(yīng)的庫,手工對其進(jìn)行安裝配置。第二種方式則是直接選用第三方的集成安裝管理環(huán)境對其進(jìn)行安裝。由于Python功能庫數(shù)目較多,且很多庫與庫之間還存在依賴關(guān)系,對于初學(xué)者建議使用第二種方式進(jìn)行安裝,推薦使用的安裝工具為Anaconda,該工具可以一鍵式安裝Python并對功能庫進(jìn)行集成化管理。在熟悉使用后,還可以使用第一種方式重新安裝一次,以便進(jìn)一步加深對Python開發(fā)中使用到各種工具以及庫的理解。預(yù)裝好的Anaconda中沒有OpenCV,還需要在Anaconda的庫管理工具中對OpenCV進(jìn)行安裝。安裝完成后,在代碼中使用import命令導(dǎo)入相應(yīng)的庫,就可以方便地使用庫的相關(guān)功能。
2.圖像的讀取、顯示以及保存
載入、顯示并保存圖像是數(shù)字圖像處理的最基本操作,對于常見的各種圖像格式,Python的OpenCV庫都能對其進(jìn)行較好的支持,其代碼如下所示:
import cv2
img = cv2.imread('d:/1.bmp')
cv2.imshow('title', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('d:/1.jpg',img)
第一行代碼為引入OpenCV庫,后空一行,開始對圖像進(jìn)行讀取以及顯示。第三行中,使用imread方法讀取了一幅圖像,將該圖像賦值給變量img。第四行調(diào)用imshow方法繪制窗口并顯示圖像。第五行是對窗口的阻塞式顯示,第六行銷毀了所有窗口。第七行調(diào)用imwrite方法保存圖像,這里的文件后綴由原始的bmp變?yōu)閖pg,該方法可以根據(jù)文件后綴自動判別所需要保存的文件類型。
3.圖像的像素操作
圖像基本的像素操作包括像素值的讀取與寫入,在OpenCV中,一幅圖像被看作一個數(shù)值矩陣,矩陣中點的值就是對應(yīng)位置像素的值,所有和矩陣相關(guān)的操作都是調(diào)用NumPy庫來進(jìn)行處理的,其代碼如下所示:
img = cv2.imread('d:/1.bmp')endprint
pixel = img[1,1,0]
print (pixel)
pixel = 10
img[1,1,0] = 10
print (img[1,1,0])
首先讀取一幅圖像,之后使用方括號索引對指定位置的像素進(jìn)行讀取,在上述代碼中,索引位置為“[1,1,0]”,表示要讀取的像素坐標(biāo)為“1,1”,顏色通道為第0號通道。之后將數(shù)值10重新賦給這個坐標(biāo)位置,同時將數(shù)值進(jìn)行控制臺輸出,以便觀察變化。除了以單個的方式對像素進(jìn)行讀寫外,還可以以某一坐標(biāo)范圍對像素進(jìn)行批量處理。
四、基本的圖像處理算法
1.直方圖處理
灰度直方圖是圖像不同灰度級出現(xiàn)概率的統(tǒng)計,通過直方圖可以非常直觀地了解一幅圖像的明暗程度以及色彩均勻程度,是多種空間域處理技術(shù)的基礎(chǔ)。我們可以調(diào)用calcHist方法來計算一幅圖像的灰度直方圖,并調(diào)用matplotlib庫的相關(guān)方法對其進(jìn)行顯示。同時,對于灰度級分布不均勻的圖像,可以使用直方圖均衡化方法對圖像進(jìn)行增強,調(diào)用equalizeHist方法即可實現(xiàn)該操作。相關(guān)代碼如下:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('d:/1.jpg',0) # 直接讀為灰度圖像
hist_cv = cv2.calcHist([img],[0],None,[256],[0,256]) # 計算灰度直方圖
plt.plot(hist_cv) # 使用matplotlib顯示直方圖
res = cv2.equalizeHist(img) # 對原始圖像進(jìn)行直方圖均衡化計算
plt.subplot(121),plt.imshow(img,'gray') # 對比顯示均衡化前后的圖像
plt.subplot(122),plt.imshow(res,'gray')
plt.show
2.空間濾波
空間濾波是由一個鄰域模板對原始圖像進(jìn)行卷積操作,將卷積的結(jié)果代替該位置的像素,以達(dá)到某種處理的效果。最常見的濾波方式有兩種,一種是空間平滑濾波,常用于模糊處理和降噪處理;還有一種是空間銳化濾波,常用于突出邊緣操作。以下代碼演示了使用均值濾波器進(jìn)行平滑濾波以及使用Sobel濾波器進(jìn)行銳化濾波。
import cv2
img = cv2.imread(d:/1.jpg',0) # 直接讀為灰度圖像
blur = cv2.blur(img,(5,5)) # 使用5*5的模板對圖像進(jìn)行中值濾波
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0) # 分別沿著x和y方向計算sobel圖像
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1)
sobelx = numpy.uint8(numpy.absolute(sobelx)) # 將計算得到的圖像轉(zhuǎn)換為uint8類型
sobely = numpy.uint8(numpy.absolute(sobely))
sobelcombine = cv2.bitwise_or(sobelx, sobely) # 合并兩個方向的圖像 得到最終的濾波結(jié)果
3.圖像分割
圖像分割是將圖像的前景或感興趣區(qū)域從背景中提取出來的一種技術(shù)手段,是從圖像中提取相關(guān)語義信息的必要步驟。目前圖像分割的技術(shù)手段多種多樣,最基本的圖像分割即圖像的二值化處理,將整個圖像劃分為前景和背景兩個部分。我們可以使用手工閾值方法對圖像進(jìn)行二值化處理,還可以使用自動閾值方法對其二值化。以下代碼演示了使用手工閾值方法以及經(jīng)典的自動閾值方法Otsu對圖像進(jìn)行二值化分割。
import cv2
img = cv2.imread('d:/dd.jpg', 0) # 讀取灰度圖像
ret1, bwimg1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) # 手工閾值進(jìn)行二值化
ret2,bwimg2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) # Otsu二值化
五、小結(jié)
在數(shù)字圖像處理課程的教學(xué)過程中,選擇Python作為實踐教學(xué)使用的程序語言,一方面,降低了數(shù)字圖像處理編程的學(xué)習(xí)門檻,提高了學(xué)生的學(xué)習(xí)積極性;另一方面,該語言與目前熱門技術(shù)結(jié)合緊密,擴展性強,為以后的相關(guān)學(xué)習(xí)打下基礎(chǔ)。本文簡單介紹了該語言在教學(xué)過程中的基本應(yīng)用手段,如何在此基礎(chǔ)上進(jìn)一步進(jìn)行學(xué)習(xí)還有待研究。
參考文獻(xiàn):
[1]周海芳.“數(shù)字圖像處理”課程研討式教學(xué)[J].計算機教育,2010(24).
[2]李國軍.數(shù)字圖像處理的一種新方法[J].鞍山師范學(xué)院學(xué)報,2016(18).endprint