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

資訊專欄INFORMATION COLUMN

Programming Computer Vision with Python (學習筆記三)

wpw / 470人閱讀

摘要:從而將高維圖像識別問題轉(zhuǎn)化為低維特征向量的識別問題,大大降低了計算復雜度,同時也減少了冗余信息所造成的識別誤差。向量上的大量藍色圓點白色邊緣表示二維數(shù)據(jù)在其上的投影。

概要

原書對于PCA的講解只有一小節(jié),一筆帶過的感覺,但我發(fā)現(xiàn)PCA是一個很重要的基礎(chǔ)知識點,在機器機視覺、人臉識別以及一些高級圖像處理技術(shù)時都被經(jīng)常用到,所以本人自行對PCA進行了更深入的學習。

PCA是什么

PCA(Principal Component Analysis,主成分分析或主元分析)是一種算法,PCA的結(jié)果是用盡可能少的特征數(shù)據(jù)來表達最多的原始圖像的本質(zhì)結(jié)構(gòu)特征。即使它會丟失一部分原始圖像的特征表達,但它仍然是很有用的處理技巧,也很常用,特別在計算機視覺和人臉識別方面。

假設(shè)我們有一個二維數(shù)據(jù)集,它在平面上的分布如下圖:

如果我們想要用一個一維向量來表達此數(shù)據(jù)集,就會丟失一部分此數(shù)據(jù)集的信息,但我們的目標是讓求得的這個一維向量可以盡可能多地保留這個數(shù)據(jù)集的特征信息,那么這個求解過程就是PCA。

通過PCA我們可以找到若干個1維向量,如圖:

直觀上看出,向量u1是數(shù)據(jù)集變化的主方向,而u2是次方向,u1比u2保留了更多的數(shù)據(jù)集的結(jié)構(gòu)特征,所以我們選擇u1作為主成分,并把原數(shù)據(jù)集投影到u1上就可以得出對原數(shù)據(jù)集的一維近似重構(gòu):

以上只是一種直觀的示例,把二維數(shù)據(jù)降為用1維來表示,當然,PCA通常是應(yīng)用在高維數(shù)據(jù)集上。

PCA解決什么問題

假設(shè)我們有10張100 × 100像素的灰度人臉圖,我們目標是要計算這10張圖的主成分來作為人臉特征,這樣就可以基于這個‘特征臉’進行人臉匹配和識別。但即使一個100 × 100像素的灰度圖像維度就達到10,000維,10張圖像的線性表示可以達到100,000維,如此高維的數(shù)據(jù)帶來幾個問題:

對高維數(shù)據(jù)集進行分析處理的計算量是巨大的,消耗資源太大,時間太長

高維數(shù)據(jù)包含了大量冗余和噪聲數(shù)據(jù),會降低圖像識別率

所以通常對于高維數(shù)據(jù)集,首先需要對其進行降維運算,以低維向量表達原數(shù)據(jù)集最多最主要的結(jié)構(gòu)特征。從而將高維圖像識別問題轉(zhuǎn)化為低維特征向量的識別問題,大大降低了計算復雜度,同時也減少了冗余信息所造成的識別誤差。PCA其實就是最常用的一種降維算法。

PAC也可用于高維數(shù)據(jù)壓縮、高維數(shù)據(jù)可視化(轉(zhuǎn)二維或三維后就可以畫圖顯示)等方面,也是其它很多圖像處理算法的預處理步驟。

PCA的計算

關(guān)于PCA,網(wǎng)上一搜還是不少的,但我仔細看了幾篇文章之后,發(fā)現(xiàn)這些文章講的跟書上講的有些地方不一致,甚至連計算時的公式都不一樣,這讓我產(chǎn)生了很多困惑。所以我想最重要的還是要理解PCA的數(shù)學原理,數(shù)學原理才是根,掌握了數(shù)學原理,再來寫代碼。恰好找到一篇文章專門講PCA數(shù)學原理,作者的數(shù)學功底和邏輯表達能力非常棒,讓我很容易看明白。另外,我也找到一篇老外寫的文章(見底部參考文章),這兩篇文章對PCA的計算描述是一致的,所以我決定在這兩篇文章的基礎(chǔ)上,結(jié)合書上的示例代碼進行學習和驗證。

本文不是要要把PCA的數(shù)學原理及推導寫出來,而是通過理解PCA的數(shù)學原理,總結(jié)PCA的計算步驟,因為計算步驟是代碼實現(xiàn)的必備知識。

PCA的計算過程涉及到幾個很重要的數(shù)學知識點:

零均值化

矩陣的轉(zhuǎn)置及乘法

協(xié)方差與協(xié)方差矩陣

特征值及特征向量

現(xiàn)在來看PCA的計算步驟:
1)將原始數(shù)據(jù)按列組成d行n列矩陣X
重要說明:d對應(yīng)的就是數(shù)據(jù)的字段(或叫變量、特征、維,下稱’維‘),而n表示n條記錄(或叫樣本、觀察值,下稱’樣本‘),即每1列對應(yīng)1個樣本,之所以行和列這樣安排,是為了與數(shù)學公式保持一致,很多文章對這一點都沒有明確的說明,導致計算的方式各有不同,讓人產(chǎn)生不必要的困惑
2)將X的每個維(行)進行零均值化,即將行的每個元素減去這一行的均值
3)求出X的協(xié)方差矩陣C,即 X 乘 X的轉(zhuǎn)置
4)求出C所有的特征值及對應(yīng)的特征向量
5)將特征向量按對應(yīng)特征值大小從上到下按行排列成矩陣,取前k行組成矩陣E
6)Y=EX即為降維到k維后的數(shù)據(jù)

下面用一個例子來驗證一下這個計算過程。

黑白圖像的PCA實現(xiàn)

書中的例子是用PCA計算特征臉(人臉識別中的一步),它應(yīng)用在多張圖片上面。為直觀起見,我用另外一個例子——對單張黑白圖像進行PCA,相當于把二維圖像降為一維。

把圖像轉(zhuǎn)成二維矩陣
這張圖像是原書封面:

下面代碼是將圖中‘怪魚’部分截取出來,并轉(zhuǎn)成黑白圖像顯示:

from PIL import Image
pim = Image.open("cover.png").crop((110,360,460,675)).convert("1")
pim.show()

效果如圖:

之所以截取這部分的圖片,是因為我們大概能猜到這幅圖像降到一維后,其一維表示的向量應(yīng)該跟怪魚的方向大概一致。

使用黑白圖像是因為黑點才是我們關(guān)心的數(shù)據(jù),因為是這些黑點描繪了圖像,每個黑點有唯一確定的行和列位置,對應(yīng)平面上的(x,y)坐標,于是我們就可以得到此圖像的 2乘n 矩陣表示:第一行表示x維,第二行表示y維,每一列表示一個點。參考代碼:

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

im = np.array(Image.open("cover.png").crop((110,360,460,675)).resize((256,230)).convert("L"))
n,m = im.shape[0:2]
points = []
for i in range(n):
    for j in range(m):
        if im[i,j] < 128.0:  #把小于128的灰度值當作黑點取出來
            points.append([float(j), float(n) - float(i)]) #坐標轉(zhuǎn)換一下
    
im_X = np.mat(points).T; #轉(zhuǎn)置之后,行表示維度(x和y),每列表示一個點(樣本)
print "im_X=",im_X,"shape=",im_X.shape

現(xiàn)在,我們按上面說明的計算步驟來實現(xiàn)PCA:

def pca(X, k=1): #降為k維
  d,n = X.shape
  mean_X = np.mean(X, axis=1) #axis為0表示計算每列的均值,為1表示計算每行均值
  print "mean_X=",mean_X
  X = X - mean_X
  #計算不同維度間的協(xié)方差,而不是樣本間的協(xié)方差,方法1:
  #C = np.cov(X, rowvar=1) #計算協(xié)方差,rowvar為0則X的行表示樣本,列表示特征/維度
  #方法2:
  C = np.dot(X, X.T)
  e,EV = np.linalg.eig(np.mat(C)) #求協(xié)方差的特征值和特征向量
  print "C=",C
  print "e=",e
  print "EV=",EV
  e_idx = np.argsort(-e)[:k] #獲取前k個最大的特征值對應(yīng)的下標(注:這里使用對負e排序的技巧,反而讓原本最大的排在前面)
  EV_main = EV[:,e_idx]   #獲取特征值(下標)對應(yīng)的特征向量,作為主成分
  print "e_idx=",e_idx,"EV_main=",EV_main      
  low_X = np.dot(EV_main.T, X)    #這就是我們要的原始數(shù)據(jù)集在主成分上的投影結(jié)果
  return low_X, EV_main, mean_X

OK,現(xiàn)在我們調(diào)用此PCA函數(shù),并把原圖像和投影到一維向量后的結(jié)果也描繪出來:

low_X, EV_main, mean_X = pca(im_X)
print "low_X=",low_X
print "EV_main=",EV_main
recon_X = np.dot(EV_main, low_X) + mean_X  #把投影結(jié)果重構(gòu)為二維表示,以便可以畫出來直觀的看到
print "recon_X.shape=",recon_X.shape

fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(im_X[0].A[0], im_X[1].A[0],s=1,alpha=0.5)
ax.scatter(recon_X[0].A[0], recon_X[1].A[0],marker="o",s=100,c="blue",edgecolors="white")
plt.show()

畫散點圖函數(shù)pyplot.scatter說明:

matplotlib.pyplot.scatter(x, y, ...)
x: 數(shù)組,樣本點在X軸上的坐標集
y: 數(shù)組,樣本點在Y軸上的坐標集
s: 表示畫出來的點的縮放大小
c: 表示畫出來的點(小圓圈)的內(nèi)部顏色
edgecolors: 表示小圓圈的邊緣顏色

運行以上代碼打印:

im_X= [[  23.   24.   25. ...,  215.  216.  217.]
 [ 230.  230.  230. ...,    5.    5.    5.]] shape= (2, 19124)
mean_X= [[ 133.8574566 ]
 [ 123.75941226]]
C= [[ 2951.65745054 -1202.25277635]
 [-1202.25277635  3142.71830026]]
e= [ 1841.14567037  4253.23008043]
EV= [[-0.73457806  0.67852419]
 [-0.67852419 -0.73457806]]
e_idx= [1] EV_main= [[ 0.67852419]
 [-0.73457806]]
low_X= [[-153.26147057 -152.58294638 -151.90442219 ...,  142.29523704
   142.97376123  143.65228541]]
EV_main= [[ 0.67852419]
 [-0.73457806]]
recon_X.shape= (2, 19124)

并顯示如下圖像:

從圖中看出,向量的方向跟位置與我們目測的比較一致。向量上的大量藍色圓點(白色邊緣)表示二維數(shù)據(jù)在其上的投影。

小結(jié)

以上實現(xiàn)的PCA算法,跟我參考的兩篇文章所講的原理一致。但跟書中的PCA計算方法有一定的不同,但也因為使用的例子不一樣,對原始數(shù)據(jù)集的定義不一樣導致的,由于避免文章過長,這些放在后面再講。
至此,通過對PCA的計算過程的學習,了解了一些線性代數(shù)知識、numpy和pyplot模塊的一些接口的用法,接下來我打算做點更有興趣的事情——就是使用PCA來實現(xiàn)人臉識別。

參考鏈接:
PCA的數(shù)學原理
A Tutorial on Principal Component Analysis
NumPy函數(shù)索引

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

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

相關(guān)文章

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

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

    lifesimple 評論0 收藏0
  • Programming Computer Vision with Python學習筆記一)

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

    huashiou 評論0 收藏0
  • Programming Computer Vision with Python學習筆記五)

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

    Rocko 評論0 收藏0
  • Programming Computer Vision with Python學習筆記六)

    摘要:由所有邊緣增強像素組成的新圖像,稱為邊緣增強圖像。交叉算子上述使用差分方法得出亮度變化梯度其實就是一階微分的近似值。 邊緣檢測(edge detection)是最重要的圖像處理技術(shù)之一,圖像邊緣檢測大幅度地減少了數(shù)據(jù)量,并且剔除了可以認為不相關(guān)的信息,保留了圖像重要的結(jié)構(gòu)屬性,為后續(xù)圖像理解方法提供了基礎(chǔ)。 邊緣檢測方法 從視覺上看,圖像中的邊緣處亮度較周圍強,比如對一垂直方向的邊緣,...

    MageekChiu 評論0 收藏0
  • Programming Computer Vision with Python學習筆記八)

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

    FleyX 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<