2016年11月28日 星期一

機器學習(2)--使用OPENCV SVM實作手寫辨識

 
      這一篇我們要來利用OPENCV 所提供的SVM(支援向量機)來實作手寫辨識。在程式實作中,我稍微改變了OPENCV官版原本的範例程式,除了修正在Python3.5+OPENCV3.x
build code 會error以外,程式最後並加入自己手畫的數字圖進行預測。可以使用小畫家直接手繪一20x20 pixel 黑底白字數字圖當作自己輸入預測的樣本。如下<圖一>

另外可以跟前一篇KNN做比較
機器學習(1)--使用OPENCV KNN實作手寫辨識


<圖一>上方為用小畫家手寫輸入的樣本圖片,下方是使用OPENCV SVM辨識出的結果



2016年11月22日 星期二

Conway's Game of Life in Python(使用Python實現Conway的生命遊戲)

    這篇文章提供一Python範例程式來實現Conway的生命遊戲,並使用Pygame套件實現出動畫效果。

在1970年,英國數學家約翰·康威(John Conway)創造了他的“生命遊戲”。
這是一組規則,在一殖民地裡模仿生物有機體的混亂和生長及死亡。
在“遊戲”裡由“活的”和“死的”細胞單元組成,並將演變呈現在網格上。
從這一代過到下一代的規則如下:
     在網格上以該細胞為中心計算其八個相鄰的細胞,

1.假設人口過剩:如果該"活細胞"被三個以上的活細胞包圍,它就會死亡。
2.停滯:如果活細胞被兩個或三個活細胞包圍,它可以繼續存活。
3.如果人口過少:如果活細胞被少於兩個活細胞包圍,它也會死亡。
4.繁殖:如果死細胞被正好三個細胞包圍,它將變成活細胞。

    在程式裡我們設定0為死細胞,1為活細胞,利用Numpy及Pygame做成演變動畫
透過一直循環執行這些規則,可以出現美麗和意想不到的圖案,
有些已死的區域或是長時間不再變化的區域,經由更長的時間演變
因外來的細胞將再重新活耀起來。這遊戲迷人的地方在於它不完全是
由隨機亂數產生,他有上述的幾個規則存在,但是結果又是那麼不可預期,
好像是真的生命細胞在自己演化一般,然而實質上這只是一段程式代碼。


<圖一>隨機產生的細胞自由演化



2016年11月17日 星期四

機器學習(1)--使用OPENCV KNN實作手寫辨識

 
      這一篇我們要來利用OPENCV 所提供的kNN(k-Nearest Neighbour )來實作手寫辨識。在程式實作中,我稍微改變了OPENCV官版原本的範例程式,除了修正在Python3.5+OPENCV3.x
build code 會error以外,程式最後並加入自己手畫的數字圖進行預測。可以使用小畫家直接手繪一20x20 pixel 黑底白字數字圖當作自己輸入預測的樣本。如下<圖一>

<圖一>上方為輸入的手寫樣本圖片,下方是使用OPENCV KNN辨識出的結果


OPENCV(10)--Canny Edge Detection(Canny邊緣檢測)


    這篇介紹Canny 邊緣檢測原理,即OPENCV提供的Canny演篹法函式庫並實作一範例程式
可用兩個Trackbar 去調整minVal(T1) ,maxVal(T2)閥值,可以清楚看出minVal ,maxVal閥值對Canny 邊緣的變化影響。




原理:
    Canny  邊緣檢測是一種非常流行的邊緣檢測演算法,是 John  F.Canny 在
1986  年提出的。它是一個有很多步驟形成的演算法,我們接下來逐步介紹。

Canny邊緣檢測演算法步驟:

Step 1.雜訊去除
由於邊緣檢測很容易受到雜訊影響,所以第一步是使用 5x5 的高斯濾波器 去除雜訊。

Step 2.計算圖像梯度
    對平滑後的圖像使用 Sobel 運算元計算水平方向和垂直方向的一階導數(Gx  和 Gy),
根據得到的這兩幅梯度圖(Gx  和 Gy)找到邊界的梯度和方向,公式如下:


2016年11月16日 星期三

OPENCV(9)--Image Gradients(圖像梯度)



這篇文章介紹Image Gradients(圖像梯度),Gradient(梯度)簡單來說就是求導數(微分)。
利用Gradient(梯度)可以找出圖像邊界,通常會將圖像先灰值化,而邊界就存在像素變化差異大的地方。
    例如:鄰近連續的黑像素(0)與白像素(255)之間必然存在一邊界,鄰近像素值差異越大,存在的邊界越明顯。可以把鄰近連續的像素值變化看作一函數,而利用Gradient(梯度)便可查知其形成的可能邊界。


Sobel 運算元和 Scharr 運算元

        Sobel,Scharr 可求一階或二階導數。
        Scharr 其實是Sobel在kernel 核心3X3時的優化。
        Sobel 運算元是高斯平滑與微分操作的結合體,所以它的抗雜訊能力很好。
        你可以設定求導的方向,x方向或y方向(即對X或Y作偏微分)。也可以設定使用的卷積核的大小ksize)。
        如果 ksize=-1,會使用 3x3 的 Scharr 濾波器,它的的效果要 比 3x3 的 Sobel 濾波器好
        3x3 的 Scharr 濾波器卷積核如下:

Sobel 濾波器卷積核如下:



Laplacian 運算元

         Laplacian 是求二階導數,其找出邊界效果佳,但是對於抗雜訊能力不佳。
可假設其離散實現類似於二階Sobel 導數,事實上,OpenCV 在計算拉普拉斯運算元時直接調用Sobel 算子。計算公式如下:


拉普拉斯濾波器使用的卷積核:

OpenCV 提供了這種不同的梯度濾波器,或者說高通濾波器。Sobel,Scharr 和 Laplacian。
使用到的函數為:cv2.Sobel(),cv2.Schar(),cv2.Laplacian()        
下圖為其程式範例結果:

<圖一>Sobel ,Scharr ,Laplacian 


2016年11月14日 星期一

OPENCV(8)--Histogram & Histograms Equalization(長條圖與長條圖均衡化)


        這篇文章介紹長條圖原理及OPENCV對長條圖的處裡,包含如何均等化長條圖。

長條圖原理:
        什麼是長條圖呢?通過長條圖你可以對整幅圖像素的分佈有一個整體的瞭解,特別是對灰階圖。
        長條圖的 x 軸是灰度值0(黑) 到 255(白),y 軸是圖片中相同灰度值數量。
透過長條圖我們可以 對圖像的對比度,亮度,灰度分佈等有一個直觀的認識。

   如下<圖一> 左上圖為一對比不強烈的原圖,其對應的右上角長條圖可以看出像素值大多集中在中間像素,通常一張亮度,對比均衡的圖片應當像左下角,而可以看出其對應的右下角長條圖可以看出像素值分布較為均衡。而實際上在圖中下方圖片是經過長條圖均衡化後的結果,底下即來介紹如何用OPENCV,Numpy,MatplotLib來製作長條圖。

<圖一>





2016年11月6日 星期日

OPENCV(7)--2D Convolution ,Image Filtering and Blurring (旋積,濾波與模糊)


        這篇介紹OPENCV提供的對影像作空間濾波的工具,透過2D Convolution(旋積或譯卷積),可以達到對影像作濾波的功能,而對影像實施低通濾波(LPF),實質上就是對影像作去除雜訊,模糊化的作用,而高通濾波(HPF)實質上對影像的作用就是銳利化,以及可以凸顯出影像的邊緣。

2D Convolution 

        跟信號一樣我們也可以對 2D 圖像實施低通濾(LPF)高通濾波(HPF)等。OpenCV 提供的函數 cv.ftlter2D() 可以讓我們對一幅圖像進行卷積操作。
如下圖<一>我們對一幅圖像Convolution (旋積),底下是使用一個 3x3 kernel (核)的運算範例圖。

        操作如下:將核放在原圖像的一個像素A 上,求與核對應的圖像上 3x3個像素的和,用這個值替代像素 A 的值。重複以上操作直到 將圖像的每一個像素值都更新一遍。

圖<一>2D Convolution演算法

此圖來源:



人工神經網路(2)--使用Python實作後向傳遞神經網路演算法(Backprogation artificial neature network)

     這篇文章介紹後向傳遞神經網路演算法(Backprogation artificial neature network),並使用Python語言實作實現一XOR邏輯功能的多層網路模型。
     在底下前一篇文章單一神經元感知器的實作上知道,單一感知器無法實作出具XOR邏輯運算的功能,在這篇會改用多層網路模型並使用後向傳遞神經網路演算法(Backprogation artificial neature network)來實現XOR的邏輯功能。

人工神經網路(1)--使用Python實作perceptron(感知器)


多層神經網路:

          多層感知器是有一個或是多個隱含層的神經網路,通常網路包含一個來源神經元的輸入層,至少包含一個計算元的隱含層,以及一個計算神經元的輸出層,輸入號信一層一層的向前傳遞,這動作也稱之為前饋式傳遞神經網路,其模型如下圖<一>所示
          多層神經網路,各層多有其特定的功能,輸入層為接受外部的輸入信號,輸出層從隱含層接受輸出信號,為整個網路建立輸出形樣類別。
          隱含層的神經元發現特徵,其權重表示了其輸入型樣中的特徵,輸出層再根據這些特徵確定輸出型樣。
          利用一個隱含層,可以表示輸入信號的任何連續ˋ函數,利用兩個隱含層甚至可以表示不連續的函數,換言之,多個隱含層也可以解決單一感知器只能做單一線性分割的問題。


<圖一>有兩個隱含層的多層感知器神經網路



多層神經網路如何學習?

           最常用的是後向傳遞神經網路演算法,在1969年被首次提出(Bryson和Ho),但是由於對計算要求過於嚴苛而被忽略,直到20世紀80年代這種演算法才又被重新重視。
          多層網路的學習過程與感知器類似,提供輸入信號經過權重調節加總,計算出實際輸出,跟期望輸出比較算出誤差,再藉由調整權重來減小收斂誤差。
         在感知器中,每個輸入Xi僅有一個相對應的權重Wi和一個輸出Y,但在多層神經網路中,每一個權重對每一個輸出都有貢獻,而每一個輸入信號Xi,連接到各隱含層的神經元都有相對應的權重Wij,每個隱含層輸出也會有相對應的Wjk連結到每個輸出Yk,如下<圖二>所示:
         其中i為輸入層第i個輸入,j表示隱含層第j個神經元感知器,k為輸出層第k個輸出。
在後向傳遞網路中,學習演算法過程分為兩個階段,第一階段與感知器前饋式演算雷同,信號由輸入端向隱含層一層一層傳遞直到輸出層,如果實際輸出與預期的輸出不同,則計算其誤差,而第二階段則是將此誤差反向從輸出端經過隱含層再傳遞回輸入層,在這過程則同時調整其權重Wjk和Wij。反覆這樣的動作直到誤差收斂到一定的滿足條件值。


<圖二>三層後向傳遞網路

2016年11月5日 星期六

人工神經網路(1)--使用Python實作perceptron(感知器)



        這篇文章介紹人工神經網路最基本的單元,perceptron(感知器)。使用最簡化的數學公式
說明,並利用Python語言實作單一感知器and 及or 的邏輯功能.

        1943年,Warren McCulloch 和Walter Pitts 提出了一簡單計算元素的神經元,這個思想現在仍然是大多數人工神經網路的基礎.
        如下<圖一>神經元接收了來自輸入連結的一些輸入信號(X1......Xn),這些輸入信號可以是原始資料或是其他神經元的輸出信號。輸出信號則可以是最終答案,也可以是其他神經元的輸入信號。
        神經元計算帶權重輸入信號和並將結果和臨界值θ比較,如果網路淨輸入比臨界值低,則神經元輸出-1,反之,如果網路淨輸入比臨界值低,則神經元輸出1。

<圖一>典型的神經元




        換言之,神經元使用下面的轉移或激勵函數.
其中X是神經元的淨權重輸入,Xi 是"輸入i"的值,Wi是"輸入i"的權重,
n是神經元輸入數量,Y是神經元的輸出。


2016年11月1日 星期二

OPENCV(6)--Trackbar(軌道桿)


    這篇介紹OPENCV提供的另一個基本工具Trackbar(軌道桿).可以用滑鼠拖拉改變特定的數值.
如下圖,拖拉 R,G,B Trackbar(軌道桿) 即可以更改,RGB顏色,範圍可以設定為0~255之間的數值.
Opencv 並沒有提供如Checkbox 這樣的工具,但是只要將Trackbar(軌道桿) 範圍值成0~1 ,也可以權當如checkbox的功能,當然如果需要更多一些GUI介面的元件,在Python 裡也可以利用別人提供的套件,如Tkinter ,或是PyQT 之類的.也可以跟OPENCV 套件整合在一起由Python實現.這就是Python 語言的便利性.


<圖一>當切換ON/OFF Trackbar(軌道桿) 在ON 位置時, 拉動R,G,B Trackbar(軌道桿)可以及時改變顏色