圖像處理,顧名思義,,可以簡(jiǎn)單地定義為利用計(jì)算機(jī)算法(通過(guò)代碼)對(duì)圖像進(jìn)行分析,、操作的處理。它包括如下不同的幾個(gè)方面:圖像的存儲(chǔ),、表示,、信息提取、操作,、增強(qiáng),、恢復(fù)和解釋。本章將對(duì)圖像處理技術(shù)的各個(gè)方面進(jìn)行基本介紹,,并介紹使用Python庫(kù)進(jìn)行圖像處理實(shí)踐編程,。本書(shū)中的所有示例代碼都基于Python 3編寫(xiě)。 本章首先定義什么是圖像處理以及圖像處理的應(yīng)用是什么,;其次介紹圖像處理的基本流程,,即在計(jì)算機(jī)上處理圖像的一般步驟;再次介紹用于圖像處理的不同Python庫(kù)及如何在Python 3下安裝它們,;接下來(lái)介紹如何使用不同的庫(kù)編寫(xiě)Python代碼讀寫(xiě)(存儲(chǔ))圖像,;之后介紹基于Python表示圖像的數(shù)據(jù)結(jié)構(gòu)以及如何顯示圖像,;最后介紹不同的圖像類(lèi)型和不同的圖像文件格式以及如何由Python執(zhí)行基本的圖像操作。 在本章的最后,,要求讀者能夠概念化圖像處理,、圖像處理步驟和圖像處理應(yīng)用;要求掌握能夠從不同的Python圖像處理庫(kù)導(dǎo)入和調(diào)用函數(shù),;要求能夠理解Python中存儲(chǔ)不同圖像類(lèi)型的數(shù)據(jù)結(jié)構(gòu),,使用不同的Python庫(kù)讀寫(xiě)圖像文件,以及利用Python庫(kù)編寫(xiě)Python代碼來(lái)執(zhí)行基本圖像操作,。 本章主要包括以下內(nèi)容:
1.1 什么是圖像處理及圖像處理的應(yīng)用什么是圖像?它是如何存儲(chǔ)在計(jì)算機(jī)里的,?用Python編程如何處理,? 1.1.1 什么是圖像以及圖像是如何存儲(chǔ)的從概念上講,形式最簡(jiǎn)單的圖像(單通道,,例如二值或單色,,灰度或黑白圖像)是一個(gè)二維函數(shù)f(x,y),即將坐標(biāo)點(diǎn)映射到表示亮度/顏色相關(guān)的整數(shù)/實(shí)數(shù),。點(diǎn)稱(chēng)為像素或圖像基本單位(圖像元素),。一幅圖像可以有多個(gè)通道(例如,對(duì)于彩色RGB圖像,,可以使用顏色表示三通道——紅,、綠、藍(lán)),。彩色RGB圖像的像素點(diǎn)(x,y)可以表示為三元組(rx,y, gx,y, bx,y),。 為了能夠在計(jì)算機(jī)上描述圖像,對(duì)于圖像f(x,y),,必須在空間和振幅兩方面進(jìn)行數(shù)字化,。空間坐標(biāo)(x,y)的數(shù)字化稱(chēng)為圖像抽樣,,振幅數(shù)字化稱(chēng)為灰度量化,。在計(jì)算機(jī)中,通常將像素通道所對(duì)應(yīng)的值表示為整數(shù)(0~255)或浮點(diǎn)數(shù)(0~1),??梢詫D像存儲(chǔ)為不同類(lèi)型(格式)的文件,。每個(gè)文件通常包括元數(shù)據(jù)和多維數(shù)組的數(shù)據(jù)(例如,二值或灰度圖像的二維數(shù)組,,RGB和YUV彩色圖像的三維數(shù)組),。圖1-1描述了如何將圖像數(shù)據(jù)存儲(chǔ)為不同類(lèi)型圖像的數(shù)組,正如圖中所示,,對(duì)于灰度圖像,,用“寬度×高度”(二維數(shù)組)的模式足以存儲(chǔ),而對(duì)于RGB圖像,,則需要用“寬度×高度×3”(三維數(shù)組)的模式存儲(chǔ),。 圖1-1 圖像的存儲(chǔ) 二值、灰度和RGB圖像如圖1-2所示,。 圖1-2 二值,、灰度和RGB圖像 本書(shū)重點(diǎn)討論圖像數(shù)據(jù)的處理,用Python庫(kù)實(shí)現(xiàn)從圖像中提取數(shù)據(jù),,并運(yùn)用算法進(jìn)行圖像處理,。樣本圖像均取自互聯(lián)網(wǎng)——伯克利圖像分割數(shù)據(jù)集、基準(zhǔn)數(shù)據(jù)集,,以及USC-SIPI圖像數(shù)據(jù)庫(kù),,其中大多都是用于圖像處理的標(biāo)準(zhǔn)圖像。 1.1.2 什么是圖像處理圖像處理是指在計(jì)算機(jī)上使用算法和代碼自動(dòng)處理,、操作,、分析和解釋圖像,它廣泛應(yīng)用于諸多學(xué)科和領(lǐng)域,,如電視,、攝影、機(jī)器人,、遙感,、醫(yī)學(xué)診斷和工業(yè)檢驗(yàn)。像大眾所熟知的Facebook和Instagram社交網(wǎng)站,,面臨用戶(hù)每天都會(huì)上傳大量圖片的情況,,它們是行業(yè)的典型案例,需要使用圖像處理算法或?qū)D像處理算法進(jìn)行創(chuàng)新來(lái)處理上傳的圖片,。 在本書(shū)中,,我們用Python包來(lái)處理圖像:首先,用一組庫(kù)來(lái)做經(jīng)典的圖像處理——提取圖像數(shù)據(jù),,用庫(kù)函數(shù)的算法將數(shù)據(jù)轉(zhuǎn)換為預(yù)處理,、增強(qiáng)、復(fù)原、表示(用描述符),、分割,、分類(lèi)、檢測(cè)和識(shí)別(對(duì)象),,從而更好地分析,、理解和解釋數(shù)據(jù);其次,,我們用另一組庫(kù)進(jìn)行基于深度學(xué)習(xí)的圖像處理——這種技術(shù)近年來(lái)變得非常熱門(mén),。 1.1.3 圖像處理的應(yīng)用圖像處理的典型應(yīng)用包括醫(yī)學(xué)/生物領(lǐng)域(如X射線和CT掃描)、計(jì)算攝影(Photoshop),、指紋認(rèn)證,、人臉識(shí)別等。 1.2 圖像處理流程圖像處理流程的基本步驟如下,。 (1)圖像的獲取與存儲(chǔ),。獲取圖像(如使用相機(jī)獲取),,并以文件的形式(如JPEG文件)存儲(chǔ)在某些設(shè)備(如硬盤(pán))上,。 (2)加載至內(nèi)存并存盤(pán)。從磁盤(pán)讀取圖像數(shù)據(jù)至內(nèi)存,,使用某種數(shù)據(jù)結(jié)構(gòu)(如numpy ndarray)作為存儲(chǔ)結(jié)構(gòu),之后將數(shù)據(jù)結(jié)構(gòu)序列化到一個(gè)圖像文件中,,也可能是對(duì)圖像上運(yùn)行了算法之后,。 (3)操作、增強(qiáng)和復(fù)原,。需運(yùn)行預(yù)處理算法完成如下任務(wù),。 ① 圖像轉(zhuǎn)換(采樣和操作,如灰度轉(zhuǎn)換),; ② 圖像質(zhì)量增強(qiáng)(濾波,,如圖像由模糊變清晰); ③ 圖像降噪,,圖像復(fù)原,。 (4)圖像分割。為了提取感興趣的對(duì)象,,需要對(duì)圖像進(jìn)行分割,。 (5)信息提取/表示。圖像需以其他形式表示,,如表示為以下幾項(xiàng),。 ① 一些可從圖像中計(jì)算出來(lái)的手工標(biāo)識(shí)的特征描述符(如HOG描述符、經(jīng)典圖像處理),。 ② 一些可自動(dòng)從圖像中學(xué)習(xí)的功能(例如,,在深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)的隱藏層中學(xué)到權(quán)重和偏差值),。 ③ 以另一種表示方法表示圖像。 (6)圖像理解/圖像解釋,。以下表示形式可用于更好地理解圖像,。 ① 圖像分類(lèi)(例如,圖像是否包含人類(lèi)對(duì)象),。 ② 對(duì)象識(shí)別(例如,,在帶有邊框的圖像中查找car對(duì)象的位置)。 圖像處理流程如圖1-3所示,。 圖1-3 圖像處理流程 用于各種圖像處理任務(wù)的不同模塊如 圖1-4所示,。除此之外,還會(huì)用到以下圖像處理模塊:
圖1-4 用于圖像處理任務(wù)的不同模塊 1.3 在Python中安裝不同的圖像處理庫(kù)后續(xù)將介紹如何安裝不同的圖像處理庫(kù),,并為用Python經(jīng)典圖像處理技術(shù)進(jìn)行圖像處理編程設(shè)置環(huán)境,。在本書(shū)的最后一些章節(jié)使用基于深度學(xué)習(xí)的方法時(shí),需要使用不同的設(shè)置,。 1.3.1 安裝pip用pip(或pip3)工具安裝圖像處理庫(kù),。因此,如果還沒(méi)安裝它,,先安裝pip,。如果使用從python.org下載的Python 3 >=3.4,或者已工作在由virtualenv或pyvenv創(chuàng)建的虛擬環(huán)境中,,則說(shuō)明pip已經(jīng)安裝好了,,只需要確保pip升級(jí)即可。 1.3.2 在Python中安裝圖像處理庫(kù)Python有許多庫(kù)可用于圖像處理,,如numpy,、scipy、scikit-image,、PIL(Pillow),、OpenCV、scikit-learn,、SimpleITK和matplotlib,。 matplotlib庫(kù)主要用于圖像顯示,而numpy主要用于圖像存儲(chǔ),,scikit-learn庫(kù)構(gòu)建用于圖像處理的機(jī)器學(xué)習(xí)模型,,scipy主要用于圖像增強(qiáng),scikit-image、mahotas和opencv庫(kù)用于不同的圖像處理算法,。 以下代碼展示了通過(guò)Python提示符(交互模式),,如何下載安裝所需的庫(kù): >>> pip install numpy>>> pip install scipy>>> pip install scikit-image>>> pip install scikit-learn>>> pip install pillow>>> pip install SimpleITK>>> pip install opencv-python>>> pip install matplotlib 如果操作系統(tǒng)平臺(tái)不同,可能還會(huì)用到一些附加的安裝說(shuō)明,。讀者應(yīng)該瀏覽文檔站點(diǎn)來(lái)獲取每個(gè)庫(kù)在特定平臺(tái)詳細(xì)安裝庫(kù)的說(shuō)明,。此外,讀者應(yīng)該熟悉stack overflow等網(wǎng)站,,以解決不同平臺(tái)依賴(lài)安裝庫(kù)的問(wèn)題,。 最后,可以通過(guò)Python提示符導(dǎo)入庫(kù)來(lái)驗(yàn)證庫(kù)是否安裝正確,。如果庫(kù)成功導(dǎo)入(沒(méi)有拋出錯(cuò)誤消息),,那么安裝沒(méi)有問(wèn)題??梢詫惭b的庫(kù)的版本打印到控制臺(tái),。 scikit-image和PIL Python庫(kù)的版本如下面的代碼所示: >>> import skimage, PIL, numpy>>> print(skimage.__version__)# 0.14.0>>> PIL.__version__# 5.1.0>>> numpy.__version__# 1.14.5 要確保所有庫(kù)為最新版本。 1.3.3 安裝Anaconda發(fā)行版請(qǐng)下載并安裝最新版本的Anaconda發(fā)行版,,以免去直接安裝眾多的Python包的麻煩,。 1.3.4 安裝Jupyter筆記本如果用Jupyter筆記本來(lái)編寫(xiě)Python代碼,需要先通過(guò)python提示符安裝jupyter包,,即首先使用>>>pip install jupyter,,然后使用>>>jupyter notebook,在瀏覽器中啟動(dòng)Jupyter Notebook應(yīng)用程序,。在應(yīng)用程序中就可以創(chuàng)建新的Python筆記本并選擇內(nèi)核了,。如果使用的是Anaconda,就不需要顯式安裝Jupyter,,因?yàn)樽钚碌腁naconda發(fā)行版本附帶了Jupyter。 1.4 使用Python進(jìn)行圖像輸入/輸出和顯示由于圖像是作為文件存儲(chǔ)在磁盤(pán)上的,,因此從文件中讀取和寫(xiě)入圖像是磁盤(pán)輸入/輸出操作,。可以通過(guò)多種方式使用不同的庫(kù)完成這些任務(wù),,本節(jié)給出了其中一些方式,。從導(dǎo)入所有必需的包開(kāi)始,代碼如下,。 # for inline image display inside notebook# % matplotlib inlineimport numpy as npfrom PIL import Image, ImageFont, ImageDrawfrom PIL.ImageChops import add, subtract, multiply, difference, screenimport PIL.ImageStat as statfrom skimage.io import imread, imsave, imshow, show, imread_collection,imshow_collectionfrom skimage import color, viewer, exposure, img_as_float, datafrom skimage.transform import SimilarityTransform, warp, swirlfrom skimage.util import invert, random_noise, montageimport matplotlib.image as mpimgimport matplotlib.pylab as pltfrom scipy.ndimage import affine_transform, zoomfrom scipy import misc 1.4.1 使用PIL讀取,、保存和顯示圖像PIL的open() 函數(shù)用于從Image對(duì)象的磁盤(pán)讀取圖像,如下面的代碼所示,。圖像作為PIL.PngImagePlugin.PngImageFile類(lèi)的對(duì)象加載,,讀者可以用寬度、高度和模式等屬性來(lái)查找圖像的大小[寬度×高度(像素)或分辨率]和模式。 im = Image.open('../images/parrot.png') # read the image, provide the correct pathprint(im.width, im.height, im.mode, im.format, type(im))# 453 340 RGB PNG <class 'PIL.PngImagePlugin.PngImageFile'>im.show() # display the image 運(yùn)行上述代碼,,輸出結(jié)果如圖1-5所示,,從文件中讀取圖像,然后再將圖像顯示在屏幕上,。 圖1-5 讀取的鸚鵡圖像 用PIL函數(shù)convert()將彩色RGB圖像轉(zhuǎn)換為灰度圖像,,代碼如下: im_g = im.convert('L') # convert the RGB color image to a grayscale imageim_g.save('../images/parrot_gray.png') # save the image to diskImage.open('../images/parrot_gray.png').show() # read the grayscale image from disk and show 運(yùn)行上述代碼,結(jié)果如圖1-6所示,,輸出的是鸚鵡的灰度圖像,。 圖1-6 輸出鸚鵡的灰度圖像 提供磁盤(pán)上圖像的正確路徑建議創(chuàng)建一個(gè)文件夾(子目錄)來(lái)存儲(chǔ)要處理的圖像(例如,對(duì)于Python代碼示例,,建議讀者使用名為images的文件夾來(lái)存儲(chǔ)圖像),,然后提供文件夾的路徑以訪問(wèn)圖像,以免出現(xiàn)“找不到文件”的異常,。 1.4.2 使用matplotlib讀取,、保存和顯示圖像接下來(lái)演示如何使用matplotlib.image中的imread()函數(shù)來(lái)讀取浮點(diǎn)numpy ndarray中的圖像,其中,,像素值表示為介于0和1之間的真值,。代碼如下: im = mpimg.imread('../images/hill.png') # read the image from disk as anumpy ndarrayprint(im.shape, im.dtype, type(im)) # this image contains anαchannel, hence num_channels= 4# (960, 1280, 4) float32 <class 'numpy.ndarray'>plt.figure(figsize=(10,10))plt.imshow(im) # display the imageplt.axis('off')plt.show() 運(yùn)行上述代碼,輸出結(jié)果如圖1-7所示,。 圖1-7 用imread()函數(shù)讀取的山峰圖像 接下來(lái)展示如何將圖像更改為較暗的圖像,。首先將所有像素值設(shè)置為0~0.5之間的數(shù),然后將numpy ndarray保存到磁盤(pán),。保存的圖像將重新加載并顯示,。代碼如下: im1 = imim1[im1 < 0.5] = 0 # make the image look darkerplt.imshow(im1)plt.axis('off')plt.tight_layout()plt.savefig('../images/hill_dark.png') # save the dark imageim = mpimg.imread('../images/hill_dark.png') # read the dark imageplt.figure(figsize=(10,10))plt.imshow(im)plt.axis('off') # no axis ticksplt.tight_layout()plt.show() 運(yùn)行上述代碼,輸出結(jié)果為較暗的山峰圖像,,如圖1-8所示,。 圖1-8 較暗的山峰圖像 使用matplotlib imshow()在顯示時(shí)插值matplotlib中的imshow()函數(shù)提供了多種不同類(lèi)型的插值方法用以對(duì)圖像進(jìn)行繪制。當(dāng)被繪制的圖像很小時(shí),,這些方法特別有用,。通過(guò)圖1-9所示的尺寸為50×50的Lena圖像來(lái)查看用不同插值方法繪制圖像的效果。 圖1-9 Lena圖像 如下代碼演示了如何通過(guò)imshow()使用不同的插值方法: im = mpimg.imread('../images/lena_small.jpg') # read the image from disk asa numpy ndarraymethods = ['none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'lanczos']fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 30),subplot_kw={'xticks': [], 'yticks': []})fig.subplots_adjust(hspace=0.05, wspace=0.05)for ax, interp_method in zip(axes.flat, methods):ax.imshow(im, interpolation=interp_method)ax.set_title(str(interp_method), size=20)plt.tight_layout()plt.show() 運(yùn)行上述代碼,,輸出結(jié)果如圖1-10所示,。 圖1-10 使用不同插值方法對(duì)Lena圖像進(jìn)行處理的效果 1.4.3 使用scikit-image讀取、保存和顯示圖像以下代碼演示了如何用scikit-image中的imread()函數(shù)讀取numpy ndarray中的圖像,。圖像類(lèi)型為uint8(8位無(wú)符號(hào)整數(shù)),,因此圖像像素值是介于0和255之間的數(shù)。然后,,用hsv2rgb()函數(shù)從Image.color模塊將彩色RGB圖像轉(zhuǎn)換為HSV圖像(更改圖像類(lèi)型或模式,,本書(shū)稍后討論),。接下來(lái),將所有像素點(diǎn)的飽和度(色彩)更改為常量值,,但色調(diào)和值通道保持不變,。這樣,圖像就被rgb2hsv()函數(shù)轉(zhuǎn)換回了RGB模式,,以創(chuàng)建新圖像,,并保存和顯示圖像。 im = imread('../images/parrot.png') # read image from disk, provide thecorrect pathprint(im.shape, im.dtype, type(im))# (362, 486, 3) uint8 <class 'numpy.ndarray'>hsv = color.rgb2hsv(im) # from RGB to HSV color spacehsv[:, :, 1] = 0.5 # change the saturationim1 = color.hsv2rgb(hsv) # from HSV back to RGBimsave('../images/parrot_hsv.png', im1) # save image to diskim = imread('../images/parrot_hsv.png')plt.axis('off'), imshow(im), show() 運(yùn)行上述代碼,,輸出結(jié)果如圖1-11所示,,這是一張飽和度發(fā)生變化的鸚鵡新圖像。 圖1-11 飽和度發(fā)生了變化的鸚鵡新圖像 還可以用scikit-image的viewer模塊在彈出窗口中顯示圖像,,代碼如下: viewer = viewer.ImageViewer(im)viewer.show() 使用scikit-image的astronaut數(shù)據(jù)集以下代碼顯示了如何使用data模塊從scikit-image庫(kù)的圖像數(shù)據(jù)集中加載(宇航員astronaut)圖像,。該模塊包含一些其他流行的數(shù)據(jù)集,如cameraman數(shù)據(jù)集,,可以用類(lèi)似的方法加載,。 im = data.astronaut()imshow(im), show() 運(yùn)行上述代碼,輸出結(jié)果如圖1-12所示,。 圖1-12 使用data模塊加載宇航員圖像 一次性同時(shí)讀取和顯示多個(gè)圖像可以用scikit-image的io模塊中的imread_collection()函數(shù)將文件名中具有特定模式的所有圖像加載到一個(gè)文件夾中,,并用imshow_collection()函數(shù)同時(shí)顯示它們。具體代碼實(shí)現(xiàn)留給讀者作為練習(xí),。 1.4.4 使用SciPy的misc模塊讀取,、保存和顯示圖像SciPy的misc模塊也可用于圖像的輸入/輸出和顯示。下面將演示如何使用misc模塊的函數(shù),。 使用misc的face數(shù)據(jù)集以下代碼展示了如何顯示misc模塊的face數(shù)據(jù)集: im = misc.face() # load the raccoon's face imagemisc.imsave('face.png', im) # uses the Image module (PIL)plt.imshow(im), plt.axis('off'), plt.show() 運(yùn)行上述代碼,,輸出結(jié)果如圖1-13所示,即顯示了misc模塊的face圖像,。 圖1-13 浣熊臉部圖像 讀者可以使用misc.imread()從磁盤(pán)讀取圖像,,代碼如下: im = misc.imread('../images/pepper.jpg')print(type(im), im.shape, im.dtype)# <class 'numpy.ndarray'> (225, 225, 3) uint8 由于I/O函數(shù)的imread()在SciPy 1.0.0中已被棄用,在1.2.0中也即將刪除,,因此文檔建議使用imageio庫(kù)代替,。代碼展示了如何使用imageio.imread()函數(shù)讀取圖像,以及如何使用matplotlib顯示圖像,。 import imageioim = imageio.imread('../images/pepper.jpg')print(type(im), im.shape, im.dtype)# <class 'imageio.core.util.Image'> (225, 225, 3)uint8plt.imshow(im), plt.axis('off'), plt.show() 運(yùn)行上述代碼,輸出結(jié)果如圖1-14所示,。 圖1-14 讀取與顯示的辣椒圖像 1.5 處理不同的文件格式和圖像類(lèi)型并執(zhí)行基本的圖像操作(略)1.6 小結(jié)本章首先介紹了圖像處理的入門(mén)知識(shí),,以及圖像處理中欲解決問(wèn)題的相關(guān)基本概念;接著討論了圖像處理的不同任務(wù)要求和流程,,以及Python中的主要圖像處理庫(kù),,書(shū)中將使用這些庫(kù)進(jìn)行代碼編寫(xiě),;接下來(lái)說(shuō)明了如何在Python中安裝不同的圖像處理庫(kù),以及如何導(dǎo)入它們并從模塊中調(diào)用函數(shù),;還介紹了有關(guān)圖像類(lèi)型,、文件格式和數(shù)據(jù)結(jié)構(gòu)的基本概念,以使用不同的Python庫(kù)存儲(chǔ)圖像數(shù)據(jù),;討論了在Python中如何使用不同的庫(kù)進(jìn)行圖像輸入/輸出和顯示,;最后討論了如何使用不同的Python庫(kù)執(zhí)行基本的圖像操作。在第2章中,,我們將深入研究圖像的采樣,、量化、卷積,、傅里葉變換和頻域?yàn)V波,。 本文摘自《Python圖像處理實(shí)戰(zhàn)》
本書(shū)介紹如何用流行的Python 圖像處理庫(kù)、機(jī)器學(xué)習(xí)庫(kù)和深度學(xué)習(xí)庫(kù)解決圖像處理問(wèn)題,。先介紹經(jīng)典的圖像處理技術(shù),,然后探索圖像處理算法的演變歷程,始終緊扣圖像處理以及計(jì)算機(jī)視覺(jué)與深度學(xué)習(xí)方面的**進(jìn)展,。全書(shū)共12 章,,涵蓋圖像處理入門(mén)基礎(chǔ)知識(shí)、應(yīng)用導(dǎo)數(shù)方法實(shí)現(xiàn)圖像增強(qiáng),、形態(tài)學(xué)圖像處理,、圖像特征提取與描述符、圖像分割,,以及圖像處理中的經(jīng)典機(jī)器學(xué)習(xí)方法等內(nèi)容,。 |
|