成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Programming Computer Vision with Python (學(xué)習(xí)筆記二)

Berwin / 1928人閱讀

摘要:首先介紹跟圖像處理顯示有關(guān)兩個(gè)庫(kù)和,然后介紹增強(qiáng)圖像對(duì)比度的實(shí)現(xiàn)原理。直方圖均衡化就是為了達(dá)到這個(gè)目的,均衡化后的圖像,像素落在每個(gè)灰度級(jí)上的個(gè)數(shù)是相等的。

首先介紹跟圖像處理、顯示有關(guān)兩個(gè)庫(kù):NumPy和Matplotlib,然后介紹增強(qiáng)圖像對(duì)比度的實(shí)現(xiàn)原理。

NumPy

NumPy是Python用于科學(xué)計(jì)算的基礎(chǔ)庫(kù),提供了一些很有用的概念,如:N維數(shù)組對(duì)象,可用于表示向量、矩陣、圖像數(shù)據(jù)等,另外還包含了線性代數(shù)及其運(yùn)算函數(shù)。NumPy的數(shù)組對(duì)象在本書示例中會(huì)被大量使用,它可以作諸如矩陣乘法、變換、向量乘法和正態(tài)化等運(yùn)算,我們通過這些運(yùn)算來實(shí)現(xiàn)圖像對(duì)齊、圖像分類、圖像扭轉(zhuǎn)等。
這是一個(gè)基礎(chǔ)庫(kù),通常不需要額外安裝。

N維數(shù)組在NumPy中對(duì)應(yīng)的數(shù)據(jù)類型是ndarry,有時(shí)使用別名array(即numpy.array)。但要注意的是,它與Python的內(nèi)置類型array是兩回事,不要混淆,Python內(nèi)置array類型只處理一維數(shù)組,其功能遠(yuǎn)不及ndarray。ndarray中的所有元素的存儲(chǔ)類型是一樣的,下面對(duì)ndarray一些重要的屬性進(jìn)行說明:

ndarray.ndim
數(shù)組維度

ndarray.shape
對(duì)于一個(gè)n×m矩陣,shape返回元組(n,m)

ndarray.size
數(shù)組的所有元素個(gè)數(shù)

ndarray.dtype
數(shù)組元素的數(shù)據(jù)類型

ndarray.itemsize
數(shù)據(jù)中每個(gè)元素的類型長(zhǎng)度(單位byte)

ndarray.data
包含數(shù)組所有元素的buffer,通常我們只是使用數(shù)組下標(biāo)來獲取元素的值

構(gòu)造
用Python的數(shù)組表示來構(gòu)造ndarray,很直觀:

In [3]: import numpy as np

In [5]: a = np.array([[0,1,2], 
                      [3,4,5]]) 

In [6]: a.shape
Out[6]: (2, 3)

In [7]: a.ndim
Out[7]: 2

In [8]: a.dtype.name
Out[8]: "int64"

In [9]: a.itemsize
Out[9]: 8

In [10]: a.size
Out[10]: 6

In [11]: type(a)
Out[11]: numpy.ndarray

構(gòu)建dnarray時(shí)可以指定元素的類型:

In [12]: b = np.array([0,1,2],dtype=int16)

In [13]: b.itemsize
Out[13]: 2

我們最常用的是想把一幅圖像轉(zhuǎn)為np.array表示,而PIL的Image類可以處理大部分的圖像格式,所以從Image轉(zhuǎn)為np.array很有用,如:

from PIL import Image
import numpy as np
im = np.array(Image.open("Selection_001.png"))

注:Image對(duì)象之所以能直接轉(zhuǎn)為ndarray類型,是因?yàn)镮mage類實(shí)現(xiàn)了ndarray的data和shape等接口。

其它一些有用的構(gòu)造方法:

np.zeros( (n, m) ) 構(gòu)建n乘m數(shù)組,其中元素初始化為0

np.ones( (n, m) ) 同上,但元素初始化為1

np.empty( (n, m) ) 同上,但元素不作初始化

np.arange([start,] stop[, step,], dtype=None) 構(gòu)建1維數(shù)組,元素的值從start到stop,增加步長(zhǎng)為step

In [75]: np.arange(5)
Out[75]: array([0, 1, 2, 3, 4])

In [76]: np.arange(5, 10)
Out[76]: array([5, 6, 7, 8, 9])

In [77]: np.arange(5, 10, 2)
Out[77]: array([5, 7, 9])

np.linspace( start, stop, item_count ) 構(gòu)建1維數(shù)組,元素從start到stop,元素個(gè)數(shù)為item_count,所以元素的增加步長(zhǎng)是自動(dòng)計(jì)算的: (to - from) / (item_count - 1)

In [63]: np.linspace(5,10,2)
Out[63]: array([  5.,  10.])

In [64]: np.linspace(5,10,3)
Out[64]: array([  5. ,   7.5,  10. ])

In [65]: np.linspace(5,10,4)
Out[65]: array([  5.        ,   6.66666667,   8.33333333,  10.        ])

In [66]: np.linspace(5,10,5)
Out[66]: array([  5.  ,   6.25,   7.5 ,   8.75,  10.  ])

基本運(yùn)算
兩個(gè)數(shù)組的+-<>*運(yùn)算,作用于兩個(gè)數(shù)組相對(duì)應(yīng)位置的元素,結(jié)果是一個(gè)新數(shù)組:

In [22]: a
Out[22]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [23]: b
Out[23]: 
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

In [24]: a + b
Out[24]: 
array([[ 2.,  3.,  4.],
       [ 5.,  6.,  7.]])

In [25]: a - b
Out[25]: 
array([[ 0.,  1.,  2.],
       [ 3.,  4.,  5.]])

In [26]: a < b
Out[26]: 
array([[False, False, False],
       [False, False, False]], dtype=bool)

In [30]: c
Out[30]: 
array([[1, 1, 1],
       [2, 2, 2]])

In [31]: a * c
Out[31]: 
array([[ 1,  2,  3],
       [ 8, 10, 12]])

數(shù)組A與B的乘積:A.dot(B)np.dot(A, B)
對(duì)+=*=等運(yùn)算符產(chǎn)生的結(jié)果,直接修改調(diào)用數(shù)組自身,而不是返回新數(shù)組。
其它一些有用的運(yùn)算操作:np.sin, np.cos, np.exp(指數(shù)), np.sqrt(開方)等。

下標(biāo)訪問

In [45]: a
Out[45]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23],
       [30, 31, 32, 33],
       [40, 41, 42, 43]])

In [46]: a[2,3]  #訪問行下標(biāo)為2,列下標(biāo)為3的元素
Out[46]: 23

In [47]: a[0:5, 1] #訪問行下標(biāo)從0到5(不含),列下標(biāo)為1的元素
Out[47]: array([ 1, 11, 21, 31, 41])

In [50]: a[:, 1] #訪問所有行,但列下標(biāo)為1的元素
Out[50]: array([ 1, 11, 21, 31, 41])

In [51]: a[1:3] #訪問行下標(biāo)從1到3(不含)的元素
Out[51]: 
array([[10, 11, 12, 13],
       [20, 21, 22, 23]])

In [52]: a[-1] #訪問最后一行
Out[52]: array([40, 41, 42, 43])

In [2]: x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [3]: x[1:7:2]  #指定起始、結(jié)束(不含)以及步長(zhǎng)
Out[3]: array([1, 3, 5])

變形
展開為一維數(shù)組:

In [53]: a = np.array([[1,2],[3,4]])  #2乘2數(shù)組

In [54]: a
Out[54]: 
array([[1, 2],
       [3, 4]])

In [57]: b = a.ravel()  #展開為1維數(shù)組,返回新數(shù)組

In [58]: b
Out[58]: array([1, 2, 3, 4])

In [59]: b.reshape(2, 2) #變形為2乘2數(shù)組,返回新數(shù)組
Out[59]: 
array([[1, 2],
       [3, 4]])

In [60]: b.resize(2, 2)  #變形為2乘2數(shù)組,直接修改本身

In [61]: b
Out[61]: 
array([[1, 2],
       [3, 4]])

有了以上的了解,我們來看看實(shí)際的應(yīng)用例子。先讀取一張圖片,把它轉(zhuǎn)為ndarray類型,再看其數(shù)組屬性:

In [88]: from PIL import Image
In [89]: import numpy as np

In [91]: im = np.array(Image.open("Selection_001.png"))  #用PIL.Image讀取圖像,并轉(zhuǎn)為ndarray數(shù)組
In [92]: print im.shape, im.dtype
(240, 568, 3) uint8  #表示圖像數(shù)據(jù)240行,568列,顏色通道數(shù)3,以u(píng)int8類型存儲(chǔ)

In [93]: im_l = np.array(Image.open("Selection_001.png").convert("L"))  #轉(zhuǎn)為灰度圖像
In [94]: print im_l.shape, im_l.dtype
(240, 568) uint8  #灰度圖像沒有顏色通道信息

矩陣
class numpy.matrix(data, dtype=None, copy=True)
從data中構(gòu)造一個(gè)矩陣對(duì)象,data可以是ndarray也可以是字符串,若data為ndarray,則copy表示是否復(fù)制data來構(gòu)造。

In [4]: np.matrix("1 2; 3 4")
Out[4]: 
matrix([[1, 2],
        [3, 4]])

In [5]: np.matrix([[1, 2], [3, 4]])
Out[5]: 
matrix([[1, 2],
        [3, 4]])

還可以使用以下兩個(gè)函數(shù)來構(gòu)造矩陣:
numpy.mat(data, dtype=None)或numpy.asmatrix(data, dtype=None),兩個(gè)只是名字不一樣,都相當(dāng)于numpy.matrix(data, copy=False)。

矩陣類提供了一些矩陣運(yùn)算的方便的接口,如:
getT:返回轉(zhuǎn)置矩陣
getI: 返回可逆矩陣的逆矩陣
getH:返回共軛轉(zhuǎn)置矩陣
getA:返回矩陣的ndarray

Matplotlib

Matplotlib是一個(gè)用于科學(xué)計(jì)算及制圖方面的強(qiáng)大的開源庫(kù),支持很多常見的圖形圖表,如:

雖然Matplotlib功能很強(qiáng)大,我們可能只是用到它很少的一些接口,比如畫圖像的輪廓和灰度圖像的柱狀圖。
安裝Matplotlib

sudo apt-get install python-matplotlib

pylab和pyplot
為簡(jiǎn)化畫圖工作,Matplotlib的pyplot模塊提供了與MATLAB相似的接口,并且可以跟IPython配合使用。
需要注意的是,書中的代碼示例使用的是Matplotlib.pylab這個(gè)模塊:

from PIL import Image
from pylab import *
im = array(Image.open("empire.jpg"))  #讀圖并轉(zhuǎn)為ndarray
imshow(im)

根據(jù)Matplotlib官網(wǎng)上的pyplot和pylab的關(guān)系說明得知:使用pylab只是為了import時(shí)方便起見,import pylab相當(dāng)于import了pyplot和numpy模塊中大部分的接口,雖然有些例子還這樣用,但已經(jīng)不被推薦使用,而是推薦使用pyplot。另外,pyplot模塊內(nèi)置了狀態(tài)機(jī),它能自動(dòng)生成必要的圖例和坐標(biāo)軸等信息,可以簡(jiǎn)化畫圖代碼。

灰度變換(GrayLevel Transformation)

對(duì)圖像進(jìn)行灰度變換的目的是為了:

改善畫質(zhì),使圖像更加清晰

有選擇地突出圖像中感興趣的特征或抑制圖像中某些不需要的特征,使圖像與視覺響應(yīng)特性相匹配

改變圖像的直方圖分布,增加圖像對(duì)比度

最簡(jiǎn)單的灰度變換就是反轉(zhuǎn)顏色,示例:

In [88]: from PIL import Image
In [89]: import numpy as np
In [90]: import matplotlib.pyplot as plt

In [97]: im = np.array(Image.open("cover.png").convert("L"))
In [98]: plt.gray()  #不加的話,顯示出來的圖像會(huì)有顏色
In [100]: plt.imshow(im)
In [102]: plt.show()

In [103]: im2 = 255 - im
In [104]: plt.imshow(im2)
In [105]: plt.show()

反轉(zhuǎn)前:

反轉(zhuǎn)后:

直方圖均衡化(histogram equalization)

灰度變換的一個(gè)很有用的例子就是直方圖均衡化,這里的直方圖指圖像的灰度直方圖,因?yàn)槲覀円纠氖腔叶葓D像,每個(gè)像素用8bit表示,值從0到255,共有256個(gè)灰度級(jí)。但通常的圖像像素值,都沒有完全占用這256個(gè)級(jí)別,很多像素的灰度值集中在一起,這樣導(dǎo)致灰度之間的變化不明顯,如果我們把圖像的灰度級(jí)按比例拉伸到256級(jí),可以使得像素灰度級(jí)差距增大,從而使圖像看起來更清晰,對(duì)比度更強(qiáng)一些。直方圖均衡化就是為了達(dá)到這個(gè)目的,均衡化后的圖像,像素落在每個(gè)灰度級(jí)上的個(gè)數(shù)是相等的。而且原圖像的第i個(gè)灰度累積和(即落在[0,i]區(qū)間所有像素個(gè)數(shù))與均衡化后的第i個(gè)灰度累積和相等,即原圖像累積和按0到255的比例進(jìn)行變換。所以下面將使用累積分布函數(shù)(cumulative distribution function,簡(jiǎn)稱cdf)。

直方圖數(shù)據(jù)的統(tǒng)計(jì)將借助numpy.histogram函數(shù)來獲得:

numpy.histogram(a, bins=10, range=None, normed=False, weights=None, density=None)

傳入數(shù)組及直方圖的柱的數(shù)目(柱也可由X軸點(diǎn)的系列指定),統(tǒng)計(jì)落在各個(gè)柱區(qū)間的元素的個(gè)數(shù)。

參數(shù):
a: 數(shù)組,需要扁平化
bins: bin指的是直方圖中的“柱”,取值對(duì)應(yīng)X軸上的區(qū)間[x,y),此參數(shù)可選,傳入int表示等寬柱的數(shù)量,也支持非等寬柱的設(shè)置
range:(float, float),可選,指定柱的最低和最高值
normed:bool,可選,NumPy1.6棄用,建議使用density參數(shù)
density:bool,可選,F(xiàn)alse表示函數(shù)返回的是落在每個(gè)柱區(qū)間的元素的數(shù)量,若為True,函數(shù)返回的是由`概率密度分布函數(shù)`對(duì)每個(gè)柱計(jì)算出來的值

返回值:
hist:ndarray,如density參數(shù)所說
bin_edges:柱的邊界數(shù)組,length(hist) + 1,即X軸上柱之間的分割點(diǎn)形成的數(shù)組

示例:
In [8]: a = np.array([0,1,2,3,4])
In [9]: np.histogram(a, 5)
Out[9]: (array([1, 1, 1, 1, 1]), #a中落在以下各個(gè)區(qū)間的元素的個(gè)數(shù)
array([ 0. ,  0.8,  1.6,  2.4,  3.2,  4. ])) #柱的邊界(區(qū)間),自動(dòng)均分

In [10]: np.histogram(a, 5, density=True)
Out[10]: (array([ 0.25,  0.25,  0.25,  0.25,  0.25]), #概率密度分布
 array([ 0. ,  0.8,  1.6,  2.4,  3.2,  4. ]))

而累積和的計(jì)算需要用到numpy.cumsum函數(shù):

numpy.cumsum(a, axis=None, dtype=None, out=None)
示例:
In [21]: a = np.array([1,2,3,4,5,6])
In [22]: np.cumsum(a)
Out[22]: array([ 1,  3,  6, 10, 15, 21])

現(xiàn)在來寫一個(gè)函數(shù)實(shí)現(xiàn)直方圖均衡化:

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

def histeq(im,nbr_bins=256):
    imhist,bins = np.histogram(im.flatten(),nbr_bins,density=True) #對(duì)每個(gè)元素求概率密度
    cdf = imhist.cumsum() #對(duì)概率密度數(shù)組求累積和
    cdf = 255 * cdf / cdf[-1] #累積和變換到0-255區(qū)間
    im2 = np.interp(im.flatten(),bins[:-1],cdf) #線性插值
    return im2.reshape(im.shape), cdf #還原圖像維度

im = np.array(Image.open("hist-sample.jpg").convert("L"))
im2,cdf = histeq(im)

plt.gray()
plt.subplot(221) #2行2列,第1個(gè)圖
plt.imshow(im)
plt.subplot(222) #2行2列,第2個(gè)圖
plt.hist([x for x in im.flatten() if x < 250], 128)
plt.subplot(223)
plt.imshow(im2)
plt.subplot(224)
plt.hist([x for x in im2.flatten() if x < 250], 128)
plt.show()

效果對(duì)比如下,上面的是原圖及直方圖,下面的是均衡化后的圖及直方圖:

明顯看出,均衡化后的圖對(duì)比度要更強(qiáng)一些。

多圖像平均法(Averaging Images)

多圖像平均法是一個(gè)用于降噪和美化圖片的簡(jiǎn)單方法。假設(shè)多張圖像具有相同尺寸,一個(gè)計(jì)算方法就是把所有圖像的數(shù)據(jù)相加起來再除以圖像數(shù)目從而得到圖像的平均值。這個(gè)操作使用ndarray的+=/=運(yùn)算符就可以完成。
另一個(gè)實(shí)現(xiàn)的方法就是使用numpy.mean()函數(shù),放在后面再講。

小結(jié)

下一個(gè)筆記內(nèi)容講圖像的主成分分析(PCA)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44174.html

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.30 - 學(xué)習(xí) Python 來做一些神奇好玩的事情吧

    摘要:學(xué)習(xí)筆記七數(shù)學(xué)形態(tài)學(xué)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測(cè)形狀和改變形狀。學(xué)習(xí)筆記十一尺度不變特征變換,簡(jiǎn)稱是圖像局部特征提取的現(xiàn)代方法基于區(qū)域圖像塊的分析。本文的目的是簡(jiǎn)明扼要地說明的編碼機(jī)制,并給出一些建議。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 開始之前,我們先來看這樣一個(gè)提問: pyth...

    lifesimple 評(píng)論0 收藏0
  • Programming Computer Vision with Python學(xué)習(xí)筆記一)

    摘要:接下來的學(xué)習(xí)筆記本人都將使用來代替。庫(kù)中提供的很多圖像操作都是分別作用于某個(gè)通道的數(shù)據(jù)。是最流行的開源色彩管理庫(kù)之一。目前只支持在增加和。模塊支持從圖像對(duì)象創(chuàng)建或的對(duì)象,方便被使用和顯示。模塊對(duì)圖像或指定區(qū)域的每個(gè)通道進(jìn)行統(tǒng)計(jì),包括等。 介紹 《Programming Computer Vision with Python》是一本介紹計(jì)算機(jī)視覺底層基本理論和算法的入門書,通過這本收可以...

    huashiou 評(píng)論0 收藏0
  • Programming Computer Vision with Python學(xué)習(xí)筆記五)

    摘要:下面是二維空間的高斯分布函數(shù)公式這個(gè)公式被稱作高斯核。高斯模糊使用高斯平均算子來實(shí)現(xiàn)的圖像模糊叫高斯模糊,也叫高斯平滑被認(rèn)為是一種最優(yōu)的圖像平滑處理。 SciPy庫(kù) SciPy庫(kù),與之前我們使用的NumPy和Matplotlib,都是scipy.org提供的用于科學(xué)計(jì)算方面的核心庫(kù)。相對(duì)NumPy,SciPy庫(kù)提供了面向更高層應(yīng)用的算法和函數(shù)(其實(shí)也是基于NumPy實(shí)現(xiàn)的),并以子模塊...

    Rocko 評(píng)論0 收藏0
  • Programming Computer Vision with Python學(xué)習(xí)筆記八)

    摘要:簡(jiǎn)稱庫(kù)是從擴(kuò)展下來的,提供了更豐富的圖像處理函數(shù),去噪函數(shù)除了還有算法,比如邊緣檢測(cè)還有以前簡(jiǎn)單提過的算子濾波器。下面我用看具體的例子,將和高斯平滑進(jìn)行對(duì)比效果對(duì)比如下明顯感覺使用的效果要比高斯平滑好很多。 圖像去噪(Image Denoising)的過程就是將噪點(diǎn)從圖像中去除的同時(shí)盡可能的保留原圖像的細(xì)節(jié)和結(jié)構(gòu)。這里講的去噪跟前面筆記提過的去噪不一樣,這里是指高級(jí)去噪技術(shù),前面提過的...

    FleyX 評(píng)論0 收藏0
  • Programming Computer Vision with Python學(xué)習(xí)筆記七)

    摘要:數(shù)學(xué)形態(tài)學(xué)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測(cè)形狀和改變形狀。所以這個(gè)結(jié)果也會(huì)把形狀以外的噪點(diǎn)排除掉。你還可以查看其它筆記。參考資料圖像的膨脹與腐蝕數(shù)學(xué)形態(tài)學(xué)基本操作及其應(yīng)用計(jì)算機(jī)視覺特征提取與圖像處理第三版 數(shù)學(xué)形態(tài)學(xué)(mathematical morphology)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測(cè)形狀和改變形狀。起初是基于二值圖像提出的,后來擴(kuò)展到灰度圖像。...

    Charles 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<