天天看點

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.1 PIL-Python圖像庫

PIL (Python Imaging Library)圖像庫提供了很多常用的圖像處理及很多有用的圖像基本操作。PIL庫下載下傳位址[www.pythonware.com/products/pil/]。下面示範原書P001-Fig1-1讀入一幅圖檔的例子:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)figure()pil_im = Image.open('../data/empire.jpg')gray()subplot(121)title(u'原圖',fontproperties=font)axis('off')imshow(pil_im)pil_im = Image.open('../data/empire.jpg').convert('L')subplot(122)title(u'灰階圖',fontproperties=font)axis('off')imshow(pil_im)show()

運作上面的代碼,可以得出原書P002-Fig1-1中的前兩幅圖檔,如下:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

更多關于PIL的執行個體,可以參閱PIL線上文檔[www .pythonware.com/library/pil/handbook/index.htm./]。

1.1.1 對圖檔進行格式轉換

利用save()方法,PIL可以将圖檔儲存問很多不同的圖像格式。下面示範原書P002中對圖檔進行轉換的例子。# -*- coding: utf-8 -*-from PCV.tools.imtools import get_imlist #導入原書的PCV子產品from PIL import Imageimport osimport picklefilelist = get_imlist('../data/convert_images_format_test/') #擷取convert_images_format_test檔案夾下的圖檔檔案名(包括字尾名)imlist = file('../data/convert_images_format_test/imlist.txt','w') #将擷取的圖檔檔案清單儲存到imlist.txt中pickle.dump(filelist,imlist) #序列化imlist.close()for infile in filelist:

outfile = os.path.splitext(infile)[0] + ".png" #分離檔案名與擴充名

if infile != outfile:

try:

Image.open(infile).save(outfile)

except IOError:

print "cannot convert", infile

上面convertimagesformat_test檔案夾是譯者放的測試圖檔,共24幅圖像,如下圖示,測試圖檔全部為.jpg格式的。譯者在源代碼中添加了部分代碼以便将擷取的圖像檔案名清單儲存下來,同時将原來的所有圖像轉化為.png格式的圖像。注意,在載入子產品時,載入了原書的PCV子產品,關于PCV子產品的安裝,詳見[PCV子產品的安裝]運作上面代碼,可以得到轉化格式後的圖像,運作結果為:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.1.2 建立縮略圖

利用PIL可以很容易的建立縮略圖,設定縮略圖的大小,并用元組儲存起來,調用thumnail()方法即可生成縮略圖。建立縮略圖的代碼見下面。

1.1.3 拷貝并粘貼區域

調用crop()方法即可從一幅圖像中進行區域拷貝,拷貝出區域後,可以對區域進行旋轉等變換。關于拷貝、旋轉粘貼的代碼見下面。

1.1.4 調整尺寸及旋轉

要對一幅圖像的尺寸進行調整,可以調用resize()方法,元組中放置的便是你要調整尺寸的大小。如果要對圖像進行旋轉變換的話,可以調用rotate()方法。

下面代碼顯示上面提到的所有的圖像處理操作,即原圖顯示、RGB圖像轉為灰階圖像、拷貝粘貼區域、生成縮略圖、調整圖像尺寸、圖像旋轉變換的執行個體代碼:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)figure()# 顯示原圖pil_im = Image.open('../data/empire.jpg')print pil_im.mode, pil_im.size, pil_im.formatsubplot(231)title(u'原圖', fontproperties=font)axis('off')imshow(pil_im)# 顯示灰階圖pil_im = Image.open('../data/empire.jpg').convert('L')gray()subplot(232)title(u'灰階圖', fontproperties=font)axis('off')imshow(pil_im)#拷貝粘貼區域pil_im = Image.open('../data/empire.jpg')box = (100,100,400,400)region = pil_im.crop(box)region = region.transpose(Image.ROTATE_180)pil_im.paste(region,box)subplot(233)title(u'拷貝粘貼區域', fontproperties=font)axis('off')imshow(pil_im)# 縮略圖pil_im = Image.open('../data/empire.jpg')size = 128, 128pil_im.thumbnail(size)print pil_im.sizesubplot(234)title(u'縮略圖', fontproperties=font)axis('off')imshow(pil_im)pil_im.save('../images/ch01/thumbnail.jpg') #儲存縮略圖# 調整圖像尺寸pil_im = Image.open('../data/empire.jpg')pil_im = pil_im.resize(size)print pil_im.sizesubplot(235)title(u'調整尺寸後的圖像', fontproperties=font)axis('off')imshow(pil_im)# 旋轉圖像45°pil_im = Image.open('../data/empire.jpg')pil_im = pil_im.rotate(45)subplot(236)title(u'旋轉45°後的圖像', fontproperties=font)axis('off')imshow(pil_im)show()

運作上面代碼,可得P002 Figure 1-1中出現的所有執行個體圖,結果如下:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.2 Matplotlib庫

當在處理數學及繪圖或在圖像上描點、畫直線、曲線時,Matplotlib是一個很好的繪圖庫,它比PIL庫提供了更有力的特性。Matplotlib是開源的,可以在[matplotlib.sourceforge.net]上下載下傳,并且它還提供了詳細的文檔及教程。這裡,會展示一些我們在本書後面會用到的函數的一些執行個體。

1.2.1 畫圖、描點和線

雖然Matplotlib可以建立漂亮的條狀圖、餅圖、散點圖等,但是在很多計算機視覺應用場合,其實隻用到了一些常用的指令。下面展示在一幅圖像上描一些點和畫一條直線的例子。# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('../data/empire.jpg'))figure()# 畫有坐标軸的subplot(121)imshow(im)x = [100, 100, 400, 400]y = [200, 500, 200, 500]plot(x, y, 'r*')plot(x[:2], y[:2])title(u'繪圖: "empire.jpg"', fontproperties=font)# 不顯示坐标軸subplot(122)imshow(im)x = [100, 100, 400, 400]y = [200, 500, 200, 500]plot(x, y, 'r*')plot(x[:2], y[:2])axis('off') #顯示坐标軸title(u'繪圖: "empire.jpg"', fontproperties=font)show()

運作上面代碼,即可得原書P005中 Figure 1-2中左邊的結果。去掉上面代碼中坐标軸的注釋,即可得 Figure 1-2中右邊的結果。運作結果如下:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.2.2 圖像輪廓和直方圖

下面我們看兩個特别的例子:圖像輪廓線和圖線等高線。在畫圖像輪廓前需要轉換為灰階圖像,因為輪廓需要擷取每個坐标[x,y]位置的像素值。下面是畫圖像輪廓和直方圖的代碼:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('../data/empire.jpg').convert('L')) # 打開圖像,并轉成灰階圖像figure()subplot(121)gray()contour(im, origin='image')axis('equal')axis('off')title(u'圖像輪廓', fontproperties=font)subplot(122)hist(im.flatten(), 128)title(u'圖像直方圖', fontproperties=font)plt.xlim([0,260])plt.ylim([0,11000])show()

運作上面代碼,可以得到書中的圖1-3所示的結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.2.4 互動注釋

有時,使用者需要和應用進行互動,比如在圖像中用點做辨別,或者在一些訓練資料中進行注釋。PyLab提供了一個很簡潔好用的函數ginput(),它可以完成該任務,下面是一個示範互動注釋的簡短示例:from PIL import Imagefrom pylab import *im = array(Image.open('../data/empire.jpg'))imshow(im)print 'Please click 3 points'imshow(im)x = ginput(3)print 'You clicked:', xshow()

上面代碼先讀取empire.jpg圖像,顯示讀取的圖像,然後用ginput()互動注釋,這裡設定的互動注釋資料點設定為3個,使用者在注釋後,會将注釋點的坐标列印出來。

1.3 NumPy庫

NumPy是Python一個流行的用于科學計算包。它包含了很多諸如矢量、矩陣、圖像等其他非常有用的對象和線性代數函數。在本書中幾乎所有的例子都用到了NumPy數組對象。NumPy可以在scipy.org/Download]下載下傳,線上文檔包含了很多常見問題的答案。

1.3.1 圖像數組表示

在前面載入圖像的示例中,我們将圖像用array()函數轉為NumPy數組對象,但是并沒有提到它表示的含義。數組就像清單一樣,隻不過它規定了數組中的所有元素必須是相同的類型。下面的例子用于說明圖像數組表示:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *im = array(Image.open('../data/empire.jpg'))print im.shape, im.dtypeim = array(Image.open('../data/empire.jpg').convert('L'),'f')print im.shape, im.dtype

運作上面代碼,會給出下面結果:(800, 569, 3) uint8

(800, 569) float32

數組可以通過索引通路和操作其中的元素。比如:value=im[i,j,k]。i,j是坐标,k是顔色通道。對于多個元素,可以用切片操作,如:im[i,:] = im[j,:] # set the values of row i with values from row j

im[:,i] = 100 # set all values in column i to 100

im[:100,:50].sum() # the sum of the values of the first 100 rows and 50 columns

im[50:100,50:100] # rows 50-100, columns 50-100 (100th not included)

im[i].mean() # average of row i

im[:,-1] # last column

im[-2,:] (or im[-2]) # second to last row

在使用數組時有很多操作和方式,我們會在後面介紹貫穿于本書所需要的操作。

1.3.2 灰階變換

在讀入圖像到NumPy數組後,就可以對它進行任何我們想要的操作了。對圖像進行灰階變換便是一個簡單的例子。這裡給出一些進行灰階變換的例子:# -*- coding: utf-8 -*-from PIL import Imagefrom numpy import *from pylab import *im = array(Image.open('../data/empire.jpg').convert('L'))print int(im.min()), int(im.max())im2 = 255 - im # invert imageprint int(im2.min()), int(im2.max())im3 = (100.0/255) * im + 100 # clamp to interval 100...200print int(im3.min()), int(im3.max())im4 = 255.0 * (im/255.0)**2 # squaredprint int(im4.min()), int(im4.max())figure()gray()subplot(1, 3, 1)imshow(im2)axis('off')title(r'$f(x)=255-x$')subplot(1, 3, 2)imshow(im3)axis('off')title(r'$f(x)=\frac{100}{255}x+100$')subplot(1, 3, 3)imshow(im4)axis('off')title(r'$f(x)=255(\frac{x}{255})^2$')show()

上面左邊灰階變換函數采用的是f(x)=255-x,中間采用的是f(x)=(100/255)x+100,右邊采用的是變換函數是f(x)=255(x/255)^2。運作上面代碼,可以得到P009 Fig1-5中的結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

正如上面代碼所示,你可以用通過下面指令檢查每幅圖像的最小值和最大值:print int(im.min()), int(im.max())

如果你對每幅圖像用到了列印最小像素值和最大像素值,你會得到下面的輸出結果:2 255

0 253

100 200

0 255

1.3-3 調整圖像尺寸

NumPy數組将成為我們對圖像及資料進行處理的最主要工具,但是調整矩陣大小并沒有一種簡單的方法。我們可以用PIL圖像對象轉換寫一個簡單的圖像尺寸調整函數:def imresize(im,sz):

""" Resize an image array using PIL. """

pil_im = Image.fromarray(uint8(im))

return array(pil_im.resize(sz))

上面定義的調整函數,在imtools.py中你可以找到它。

1.3.3 直方圖均衡化

一個極其有用的例子是灰階變換後進行直方圖均衡化。圖像均衡化作為預處理操作,在歸一化圖像強度時是一個很好的方式,并且通過直方圖均衡化可以增加圖像對比度。下面是對圖像直方圖進行均衡化處理的例子:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *from PCV.tools import imtools# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('../data/empire.jpg').convert('L')) # 打開圖像,并轉成灰階圖像#im = array(Image.open('../data/AquaTermi_lowcontrast.JPG').convert('L'))im2, cdf = imtools.histeq(im)figure()subplot(2, 2, 1)axis('off')gray()title(u'原始圖像', fontproperties=font)imshow(im)subplot(2, 2, 2)axis('off')title(u'直方圖均衡化後的圖像', fontproperties=font)imshow(im2)subplot(2, 2, 3)axis('off')title(u'原始直方圖', fontproperties=font)#hist(im.flatten(), 128, cumulative=True, normed=True)hist(im.flatten(), 128, normed=True)subplot(2, 2, 4)axis('off')title(u'均衡化後的直方圖', fontproperties=font)#hist(im2.flatten(), 128, cumulative=True, normed=True)hist(im2.flatten(), 128, normed=True)show()

運作上面代碼,可以得到書中的結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎
python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.3.4 圖像平均

對圖像取平均是一種圖像降噪的簡單方法,經常用于産生藝術效果。假設所有的圖像具有相同的尺寸,我們可以對圖像相同位置的像素相加取平均,下面是一個示範對圖像取平均的例子:# -*- coding: utf-8 -*-from PCV.tools.imtools import get_imlistfrom PIL import Imagefrom pylab import *from PCV.tools import imtools# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)filelist = get_imlist('../data/avg/') #擷取convert_images_format_test檔案夾下的圖檔檔案名(包括字尾名)avg = imtools.compute_average(filelist)for impath in filelist:

im1 = array(Image.open(impath))

subplot(2, 2, filelist.index(impath)+1)

imshow(im1)

imNum=str(filelist.index(impath)+1)

title(u'待平均圖像'+imNum, fontproperties=font)

axis('off')subplot(2, 2, 4)imshow(avg)title(u'平均後的圖像', fontproperties=font)axis('off')show()

運作上面代碼,可得對3幅圖像平均後的效果,如下圖:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.3.5 對圖像進行主成分分析

主成分分析是一項有用的降維技術。對于主成分分析的原理,這裡不做具體介紹。下面我們在字型圖像上進行降維處理。檔案fontimages.zip包含有字母"a"的縮略圖,共有2359個字型圖像,可以在[Images courtesy of Martin Solli]下載下傳。下面代碼是顯示原書P14頁對字型圖像進行主成分分析的執行個體代碼:# -*- coding: utf-8 -*-import picklefrom PIL import Imagefrom numpy import *from pylab import *from PCV.tools import imtools, pca# Uses sparse pca codepath.#imlist = imtools.get_imlist('../data/selectedfontimages/a_selected_thumbs')# 擷取圖像清單和他們的尺寸imlist = imtools.get_imlist('../data/fontimages/a_thumbs') # fontimages.zip is part of the book data setim = array(Image.open(imlist[0])) # open one image to get the sizem, n = im.shape[:2] # get the size of the imagesimnbr = len(imlist) # get the number of imagesprint "The number of images is %d" % imnbr# Create matrix to store all flattened imagesimmatrix = array([array(Image.open(imname)).flatten() for imname in imlist], 'f')# PCA降維V, S, immean = pca.pca(immatrix)# 儲存均值和主成分#f = open('../ch01/font_pca_modes.pkl', 'wb')#pickle.dump(immean,f)#pickle.dump(V,f)#f.close()# Show the images (mean and 7 first modes)# This gives figure 1-8 (p15) in the book.figure()gray()subplot(2, 4, 1)axis('off')imshow(immean.reshape(m, n))for i in range(7):

subplot(2, 4, i+2)

imshow(V[i].reshape(m, n))

axis('off')show()

注意,這些圖像在拉成一維表示後,必須用reshape()函數将它重新轉換回來。運作上面代碼,可得原書P15 Figure1-8中的結果,即:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

1.3.6 Pickle子產品

如果你想将結果儲存下來,或者将資料儲存下來以便後面使用,那麼pickle子產品是非常有用的。Pickle子產品能夠擷取幾乎所有的Python對象,并将它轉換成字元串表示,該過程稱為封裝;從字元串表示重構對象的過程為拆封。下面用一個例子對其進行說明。正如你在上面注釋部分看到的一樣,假設我們想将前一節字型圖像的平均值和主成分儲存起來,可以通過下面操作:f = open('../data/fontimages/font_pca_modes.pkl', 'wb')pickle.dump(immean,f)pickle.dump(V,f)f.close()

上面在使用封裝操作前,需要導入pickle子產品。如果要載入儲存的.pkl資料,可以通過load()方法,如下:# load mean and principal components

f = open('../data/fontimages/font_pca_modes.pkl', 'rb')

immean = pickle.load(f)

V = pickle.load(f)

f.close()

使用with()方法在這裡不介紹,具體的可以翻閱原書。關于pickle子產品的更多細節可以查閱線上文檔[[docs.python.org/library/pickle.html\]](http://docs.python.org/library/pickle.html)

1.4 SciPy子產品

SciPy是一個開源的數學工具包,它是建立在NumPy的基礎上的。它提供了很多有效的正常操作,包括數值綜合、最優化、統計、信号處理以及圖像處理。正如接下來所展示的,SciPy庫包含了很多有用的子產品。SciPy庫可以再[http://scipy.org/Download]下載下傳。

1.4.1 圖像模糊

一個經典的并且十分有用的圖像卷積例子是對圖像進行高斯模糊。高斯模糊可以用于定義圖像尺度、計算興趣點以及很多其他的應用場合。下面是對圖像進行模糊顯示原書P017 Fig1-9的例子。# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *from scipy.ndimage import filters# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)#im = array(Image.open('board.jpeg'))im = array(Image.open('../data/empire.jpg').convert('L'))figure()gray()axis('off')subplot(1, 4, 1)axis('off')title(u'原圖', fontproperties=font)imshow(im)for bi, blur in enumerate([2, 5, 10]):

im2 = zeros(im.shape)

im2 = filters.gaussian_filter(im, blur)

im2 = np.uint8(im2)

imNum=str(blur)

subplot(1, 4, 2 + bi)

axis('off')

title(u'标準差為'+imNum, fontproperties=font)

imshow(im2)#如果是彩色圖像,則分别對三個通道進行模糊#for bi, blur in enumerate([2, 5, 10]):# im2 = zeros(im.shape)# for i in range(3):# im2[:, :, i] = filters.gaussian_filter(im[:, :, i], blur)# im2 = np.uint8(im2)# subplot(1, 4, 2 + bi)# axis('off')# imshow(im2)show()

運作上面代碼,可得P017 Fig1-9中的結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

上面第一幅圖為待模糊圖像,第二幅用高斯标準差為2進行模糊,第三幅用高斯标準差為5進行模糊,最後一幅用高斯标準差為10進行模糊。關于該子產品的使用以及參數選擇的更多細節,可以參閱SciPy scipy.ndimage文檔[docs.scipy.org/doc/scipy/reference/ndimage.html]。

1.4.2 圖像差分

圖像強度的改變是一個重要的資訊,被廣泛用以很多應用中,正如它貫穿于本書中。下面是對圖像進行差分顯示原書P019 Fig1-10的例子。# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *from scipy.ndimage import filtersimport numpy# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('../data/empire.jpg').convert('L'))gray()subplot(1, 4, 1)axis('off')title(u'(a)原圖', fontproperties=font)imshow(im)# Sobel derivative filtersimx = zeros(im.shape)filters.sobel(im, 1, imx)subplot(1, 4, 2)axis('off')title(u'(b)x方向差分', fontproperties=font)imshow(imx)imy = zeros(im.shape)filters.sobel(im, 0, imy)subplot(1, 4, 3)axis('off')title(u'(c)y方向差分', fontproperties=font)imshow(imy)#mag = numpy.sqrt(imx**2 + imy**2)mag = 255-numpy.sqrt(imx**2 + imy**2)subplot(1, 4, 4)title(u'(d)梯度幅度', fontproperties=font)axis('off')imshow(mag)show()

運作上面代碼,可得P019 Fig1-10中的運作結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

再看一個高斯差分的例子,運作下面代碼可得原書P020 Fig1-11頁對圖像進行高斯差分示例:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *from scipy.ndimage import filtersimport numpy# 添加中文字型支援#from matplotlib.font_manager import FontProperties#font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)def imx(im, sigma):

imgx = zeros(im.shape)

filters.gaussian_filter(im, sigma, (0, 1), imgx)

return imgxdef imy(im, sigma):

imgy = zeros(im.shape)

filters.gaussian_filter(im, sigma, (1, 0), imgy)

return imgydef mag(im, sigma):

# there's also gaussian_gradient_magnitude()

#mag = numpy.sqrt(imgx**2 + imgy**2)

imgmag = 255 - numpy.sqrt(imgx ** 2 + imgy ** 2)

return imgmagim = array(Image.open('../data/empire.jpg').convert('L'))figure()gray()sigma = [2, 5, 10]for i in sigma:

subplot(3, 4, 4*(sigma.index(i))+1)

axis('off')

imshow(im)

imgx=imx(im, i)

subplot(3, 4, 4*(sigma.index(i))+2)

axis('off')

imshow(imgx)

imgy=imy(im, i)

subplot(3, 4, 4*(sigma.index(i))+3)

axis('off')

imshow(imgy)

imgmag=mag(im, i)

subplot(3, 4, 4*(sigma.index(i))+4)

axis('off')

imshow(imgmag)show()

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

注意運作的結果在擺放位置時與原書P020 Fig1-11結果稍微不同。上面代碼中,第一行标準差為2,列分别表示的是x、y和mag,第二行和第三行依次類推。

1.4.3 形态學-物體計數

形态學常用于二值圖像,不過它也可以用于灰階圖像。二值圖像像素隻有兩種取值,通常是0和1。二值圖像通常是由一幅圖像進行二值化處理後的産生的,它可以用于用于對物體進行計數,或計算它們的大小。對形态學的介紹和較好的介紹是wiki[en.wikipedia.org/wiki/Mathematical_morphology]。

形态學操作包括在sci.ndimage子產品morphology中。下面我們看一個簡單地怎樣使用它們例子。# -*- coding: utf-8 -*-from PIL import Imagefrom numpy import *from scipy.ndimage import measurements, morphologyfrom pylab import *""" This is the morphology counting objects example in Section 1.4. """# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)# load image and threshold to make sure it is binaryfigure()gray()im = array(Image.open('../data/houses.png').convert('L'))subplot(221)imshow(im)axis('off')title(u'原圖', fontproperties=font)im = (im < 128)labels, nbr_objects = measurements.label(im)print "Number of objects:", nbr_objectssubplot(222)imshow(labels)axis('off')title(u'标記後的圖', fontproperties=font)# morphology - opening to separate objects betterim_open = morphology.binary_opening(im, ones((9, 5)), iterations=2)subplot(223)imshow(im_open)axis('off')title(u'開運算後的圖像', fontproperties=font)labels_open, nbr_objects_open = measurements.label(im_open)print "Number of objects:", nbr_objects_opensubplot(224)imshow(labels_open)axis('off')title(u'開運算後進行标記後的圖像', fontproperties=font)show()

運作上面代碼,可得原書P022 Fig1-12的結果:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

同時列印計數結果為:Number of objects: 45

Number of objects: 48

1.4.4 有用的SciPy子產品

SciPy有一些用于輸入和輸出資料有用的子產品,其中兩個是io和misc。

讀寫.mat檔案

如果你有一些資料存儲在Matlab .mat檔案中,可以用scipy.io子產品讀取:data = scipy.io.loadmat('test.mat')

如果要儲存到.mat檔案中的話,同樣也很容易,僅僅隻需要建立一個字典,字典中即可儲存你想儲存的所有變量,然後用savemat()方法即可:#建立字典

data = {}

#将變量x儲存在字典中

data['x'] = x

scipy.io.savemat('test.mat',data)

儲存數組為圖像

在scipy.misc子產品中,包含了imsave()函數,要儲存數組為一幅圖像,可通過下面方式完成:from scipy.misc import imsaveimsave('test.jpg',im)

scipy.misc子產品中還包含了著名的"Lena"測試圖像:lena = scipy.misc.lena()

上面得到的lena圖像是一幅512*512大小的灰階圖像。

1.5 更進階的例子:圖像降噪

我們以一個非常有用的例子結束本章。圖像降噪是一個在盡可能保持圖像細節和結構資訊時去除噪聲的過程。我們采用Rudin-Osher-Fatemi de-noising(ROF)模型。圖像去噪可以應用于很多場合,它涵蓋了從你的度假照片使之更好看到衛星照片品質提高。

下面我們看一個圖像降噪的綜合執行個體:# -*- coding: utf-8 -*-from pylab import *from numpy import *from numpy import randomfrom scipy.ndimage import filtersfrom scipy.misc import imsavefrom PCV.tools import rof""" This is the de-noising example using ROF in Section 1.5. """# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)# create synthetic image with noiseim = zeros((500,500))im[100:400,100:400] = 128im[200:300,200:300] = 255im = im + 30*random.standard_normal((500,500))U,T = rof.denoise(im,im)G = filters.gaussian_filter(im,10)# save the result#imsave('synth_original.pdf',im)#imsave('synth_rof.pdf',U)#imsave('synth_gaussian.pdf',G)# plotfigure()gray()subplot(1,3,1)imshow(im)#axis('equal')axis('off')title(u'原噪聲圖像', fontproperties=font)subplot(1,3,2)imshow(G)#axis('equal')axis('off')title(u'高斯模糊後的圖像', fontproperties=font)subplot(1,3,3)imshow(U)#axis('equal')axis('off')title(u'ROF降噪後的圖像', fontproperties=font)show()

運作上面代碼,可得到原書P025 Fig1-13的結果,如下圖示:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

其中第一幅圖示原噪聲圖像,中間一幅圖示用标準差為10進行高斯模糊後的結果,最右邊一幅圖是用ROF降噪後的圖像。上面原噪聲圖像是模拟出來的圖像,現在我們在真實的圖像上進行測試:# -*- coding: utf-8 -*-from PIL import Imagefrom pylab import *from numpy import *from numpy import randomfrom scipy.ndimage import filtersfrom scipy.misc import imsavefrom PCV.tools import rof""" This is the de-noising example using ROF in Section 1.5. """# 添加中文字型支援from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('../data/empire.jpg').convert('L'))U,T = rof.denoise(im,im)G = filters.gaussian_filter(im,10)# save the result#imsave('synth_original.pdf',im)#imsave('synth_rof.pdf',U)#imsave('synth_gaussian.pdf',G)# plotfigure()gray()subplot(1,3,1)imshow(im)#axis('equal')axis('off')title(u'原噪聲圖像', fontproperties=font)subplot(1,3,2)imshow(G)#axis('equal')axis('off')title(u'高斯模糊後的圖像', fontproperties=font)subplot(1,3,3)imshow(U)#axis('equal')axis('off')title(u'ROF降噪後的圖像', fontproperties=font)show()

同樣,運作上面代碼,可得原書P026 Fig1-14的結果,結果如下:

python計算機視覺_Python計算機視覺:第一章 圖像處理基礎

正如你所看到的,在去除噪聲的同時,ROF降噪能夠保持邊緣和圖像結構。