2018年10月10日 星期三
深度學習(8)--使用Tensorflow Object Detection API 實現物件自動辨識
2017年6月,Google公司開放了Tensorflow Object Detection API。這個專案使用TensorFlow 實現了大多數深度學習目標檢測架構,其中就包含Faster R-CNN。在本文章中將會介紹如何安裝Tensorflow Object Detection API,再介紹如何使用已訓練好的模型進行物體檢測,本文介紹的環境將會是架構在Windows 10 上面,使用Python 3.5.2,TensorFlow V1.9,最後並利用OPENCV 的WebCam攝影功能,利用攝影機即時辨別物體。
底下就先來觀看利用攝影機即時辨別物體的DEMO影片吧。
<Demo 影片>
2017年3月26日 星期日
深度學習(2)--使用Tensorflow實作卷積神經網路(Convolutional neural network,CNN)
卷積神經網路(Convolutional neural network,CNN),是一多層的神經網路架構,是以類神經網路實現的深度學習,在許多實際應用上取得優異的成績,尤其在影像物件識別的領域上表現優異。
傳統的多層感知器(Multilayer Perceptron,MLP)可以成功的用來做影像識別,如之前
所介紹,可以用來做MNIST 手寫數字辨識,但是由於多層感知器(Multilayer Perceptron,MLP)在神經元之間採用全連接的方式(Full connectivity),當使用在較高解析度或是較高維度的影像或資料時,便容易發生維度災難而造成過度適合(Overfitting)。
例如,考慮MNIST的手寫輸入資料為28x28解析度,考慮神經元全連接的方式
(Full connectivity),連接到第一個隱藏層神經元便需要28x28=784個權重(Weight)。如果考慮一
RGB三通道色彩圖像輸入,如CIFAR-10為32x32x3的圖像解析度,連接到第一個隱藏層神經
元便需32x32x3=3072個權重(Weight)。那麼如果是200x200x3的圖像解析度,便需要120000
個權重,而這只是連接到隱含層的第一個神經元而已,如果隱含層有多個神經元,那麼連
接權重的數量必然再倍數增加。
像這樣子的網路架構,沒有考慮到原始影像資料各像素(pixel)之間的遠近,或是密集關係,只是一昧的將全部像素(pixel)當各個輸入的特徵值,連接到隱含層神經元,造成爆量增加的權重不僅是一種浪費,因為實際上不須這麼多的權重,效果不僅沒增加,只是增加了運算的負荷,而且很可能會造成過度適合(Overfitting)。而卷積神經網路(Convolutional neural network,
CNN)被提出來後,可以有效的解決此一問題。
事實上卷積神經網路(Convolutional neural network,CNN)設計的目標就是用來處理以多陣列型態表達的資料,如以RGB三通道表達的彩色圖片。CNN和普通神經網路之間的一個實質差別在於,CNN是對原始圖像直接做操作,而傳統神經網路是人為的先對影像提取特徵(例如灰階化,二值化)才做操作。
CNN有三個主要的特點。
1.感知區域(Receptive field):可採用3維的圖像資料(width,height,depth)與神經元連接方式,
實際上也可以直接採用2維的圖像資料,但隱含層內部的神經元只與原本圖像的某一小塊
區域做連結。該區塊我們稱之為感知區域(Receptive field)。
2.局部連結採樣(Local connectivity):根據上述感知區域(Receptive field)的概念,CNN使用過濾
器(filters)增強與該局部圖形空間的相關性,然後堆疊許多這樣子的層,可以達到非線性
濾波的功能,且擴及全域,也就是允許網路架構從原圖小區塊的較好的特徵值代表性,組
合後變成大區塊的特徵值代表性。
3.共享權重(Shared weights):使用的過濾器(filters)是可以重複使用的,當在原始圖像產生一
特徵圖(Feature Map)時,其權重向量(weights vector)及偏誤(bias)是共用的。這樣可以確保
在該卷積層所使用的神經元會偵測相同的特徵。並且即使圖像位置或是有旋轉的狀態,
仍然可以被偵測。
這三個特點使得CNN在圖像辨識上有更好的效果。在實際操作上的三個基礎分別是:
區域感知域(Local Receptive field),卷積(Convolutional ),池化(pooling)。
我們可以從下面圖形化的實際操作來理解它的意思。
卷積層(Convolutional Layer )
下圖1,2說明在卷積層的運作方式,假設原始影像為一32x32x3維度,我們可以任意給定一
卷積核(filter),其卷積核的值即為權重(weight)。其大小可以為5x5x3,3為與原影像有一樣的深度(RGB三通道),如果輸入影像為一灰階單通道色彩,那麼卷積核大小5x5即可。卷積核大小3x3或5x5或7x7...等等可以自訂,通常為奇數維度。
接著與原圖像相同的小區域計算點積,得到的一個值便是在新的feature Map的一個新元素值。卷積核會在原始的圖像或者前一個圖像(Map)按照Stride(步伐)的設定移動,直到掃描完全部圖像區域,這樣便會產生一個新的Feature Map。便是下圖圖3~圖5所示,在這個步驟中產生單一新feature Map所使用的權重W,也就是卷積核是共用的,並且共用同一個偏誤(bias),通常初始預設偏誤(bias)可以為0。這樣確保這一新的feature map偵測的是該原始圖像同一特徵。
<圖1>
2017年3月11日 星期六
機器學習(8)--實作多層感知器(Multilayer Perceptron,MLP)手寫數字辨識
在這章節,我們使用Python實作一多層感知器(Multilayer Perceptron,MLP)來做手寫數字辨識功能。使用MNIST的數據集及反向傳遞演算法(Backpropagation)做模型訓練及測試。並將訓練好的權重存成檔案,以便對新的數據直接作預測,不須每次都重新訓練模型。最後練習使用windows內建的"小畫家"自己手畫數字進行辨識。結果如下圖所示:
<圖一>第1、3列為使用windows小畫家手繪出的手寫數字,第2,4列為相對應的預測結果。
有關反向傳遞演算法(Backpropagation)的公式推導,可以參閱底下連結:
該連結範例為有帶值的手解計算,作者:Matt Mazur已解釋的非常清楚了,
建議大家可以跟著做一次。
https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/
補充:對於啟動函數sigmoid 的求導推導有疑慮的,可以參考我下面手寫證明的方式:
2016年12月18日 星期日
OPENCV(12)--追蹤顏色物件並利用它來做打磚塊遊戲
這篇文章利用之前所介紹的OPENCV基礎方法來做一個可以追蹤顏色物件的範例。
首先我用3D印表機列印一個綠色的小物件,然後用筆電的內建webcam 抓取即時影像透過OPENCV的處裡來追蹤這個綠色物件的位置。然後可以畫出他移動的軌跡。接著利用這個特點把它應用在經典遊戲打磚塊擋板的控制,當該綠色物件往右移時打磚塊裡的擋板也會跟著往右移,往左移也跟著往左移,提供一種不需透過鍵盤或滑鼠就可以隔空操作擋板的方式,增加遊戲的樂趣。實際操作請觀看底下影片連結。
主要處理步驟如下
1.開啟Web camera 擷取影像
_, frame = cap.read()
2. 高斯模糊
frame = cv2.GaussianBlur(frame,(77,77),0)
3.從BGR轉成HSV 色域
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
4.設定擷取綠色物件範圍
lower_green = np.array([60,50,50])
upper_green = np.array([80,255,255])
mask = cv2.inRange(hsv, lower_green, upper_green)
5.利用找出的mask 跟原圖做 Bitwise-AND
res = cv2.bitwise_and(frame,frame, mask= mask)
6.找出輪廓
cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
7.找出輪廓之後便可以找出其質心或是面積周長
M = cv2.moments(cnt)
<圖一>追蹤物件並劃出軌跡
<圖二>應用在打磚塊遊戲,擋板位置會跟著綠色物件X軸位置而移動
2016年12月1日 星期四
OPENCV(11)--contours and convex hull(輪廓與凸包)
這篇介紹OPENCV提供找出輪廓與繪製輪廓,凸包的函數。
<圖一輪廓,凸包>
什麼是輪廓:
輪廓可以簡單認為成將連續的點(連著邊界)連在一起的曲線,具有相同的顏色或者灰度。輪廓在形狀分析和物體的檢測和識別中很有用。
• 為了更加準確,必須使用二值化圖像。所以在尋找輪廓之前,要進行閾值化處理或者 Canny
邊界檢測。
• 查找輪廓的函數會修改原始圖像。如果你在找到輪廓之後還想使用原始圖像的話,應該將
原始圖像存儲到其他變數中。
• 在 OpenCV 中,查找輪廓就像在黑色背景中找超白色物體。注意,要找的物體應該是白色
而背景應該是黑色。
OPENCV提供函數 cv2.ftndContours()找輪廓:
它有三個參數,第一個是輸入圖像,第二個是輪廓檢索模式,第三個是輪廓近似方法。
返回值有三個,第一個是圖像,第二個是輪廓,第三個是輪廓的層析結構。
第二個返回值"輪廓"是一個Python 清單(list),其中存儲這圖像中的所有輪廓。每一個輪廓都是一個 Numpy 陣列,包含物件邊界點(x,y)的座標。
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來製作長條圖。
<圖一>

訂閱:
文章 (Atom)













