SVM機器學習算法和OpenCV實現貓咪圖片識別器

2022-01-30 藍橋雲課精選

SVM(支持向量機)是一種常用的機器學習分類算法。本課程使用HOG+SVM算法和OpenCV實現一個圖片分類器,通過自己訓練分類器,達到可以判斷任意圖片是否是貓咪的效果。

一、課程介紹

1. 內容簡介

SVM(支持向量機)是一種常用的機器學習分類算法。本課程使用HOG+SVM算法和OpenCV實現一個圖片分類器,通過自己訓練分類器,達到可以判斷任意圖片是否是貓咪的效果。

2. 課程知識點

HOG+SVM分類器的基本原理

OpenCV處理圖片

訓練分類器,以得到適合自己項目的分類器

Python文件操作

3. 適合人群

本課程難度為中等,適合掌握Python基礎的用戶,建立對SVM分類器的基礎知識。

4. 實驗環境

二、實驗原理

SVM(支持向量機)分類器的原理是利用「分類超平面」來實現數據分類。在利用「分類超平面」對數據進行劃分時,遵循「間距最大」原則。例如,將二維平面內的兩組數據分類,可以確定很多個「分類超平面」,在二維維度下,超平面退化為一條直線:

上圖中使用綠線將藍色圓圈和紅色方塊進行分類,可以有多種方式。那麼根據SVM原理,哪一條線是最佳分類線呢?答案是,最佳分類線因該是距離藍色圓圈和紅色方框的距離都是最大的那一條,即找到兩組數據的最大間距,在最大間距中點畫一條線,如下:

如果分類3維數據,我們就使用一個平面來分割數據。如果分類4維數據,我們將會使用一個體來分割數據。以此類推,如果分類1024維數據,我們將使用1023維平面來分割數據。1023維的平面是什麼樣子?天知道。所以這個時候,將1023維度的平面命名為「分類超平面」。

SVM是一個由分類超平面定義的判別分類器。也就是說給定一組帶標籤的訓練樣本,算法將會輸出一個最優超平面對新樣本(測試樣本)進行分類。

這也是監督類型機器學習的特點,即,把一堆帶有標籤的數據輸入到機器中,讓機器根據給定的數據計算出規則,再利用這個規則,去對未知數據進行分類。說白了,就是先積累幾年工作經驗,然後去工作。

本實驗是讀入輸入圖片的灰度圖,即黑白的。然後計算該圖片的hog值,將計算得到的結果作為向量來代表該圖片。對由很多張圖片組成的向量集進行計算,找到最大間距的分類超平面,進而分類數據。

hog的全稱是Histogram of Oriented Gradient, HOG,即方向梯度直方圖。它是一種在計算機視覺和圖像處理中用來進行物體檢測的特徵描述子。它通過計算和統計圖像局部區域的梯度方向直方圖來構成特徵。Hog特徵結合SVM分類器已經被廣泛應用於圖像識別中,尤其在行人檢測中獲得了極大的成功。HOG+SVM進行行人檢測的方法是法國研究人員Dalal在2005的CVPR上提出的,今天的很多行人檢測算法基本都是以HOG+SVM的思路。

主要思想:在一副圖像中,局部目標的表象和形狀(appearance and shape)能夠被梯度或邊緣的方向密度分布很好地描述。(本質:梯度的統計信息,而梯度主要存在於邊緣的地方)。

具體的實現方法是:首先將圖像分成小的連通區域,我們把它叫細胞單元。然後採集細胞單元中各像素點的梯度的或邊緣的方向直方圖。最後把這些直方圖組合起來就可以構成特徵描述器。

提高性能:把這些局部直方圖在圖像的更大的範圍內(我們把它叫區間或block)進行對比度歸一化(contrast-normalized),所採用的方法是:先計算各直方圖在這個區間(block)中的密度,然後根據這個密度對區間中的各個細胞單元做歸一化。通過這個歸一化後,能對光照變化和陰影獲得更好的效果。

優點:與其他的特徵描述方法相比,HOG有很多優點。首先,由於HOG是在圖像的局部方格單元上操作,所以它對圖像幾何的和光學的形變都能保持很好的不變性,這兩種形變只會出現在更大的空間領域上。其次,在粗的空域抽樣、精細的方向抽樣以及較強的局部光學歸一化等條件下,只要行人大體上能夠保持直立的姿勢,可以容許行人有一些細微的肢體動作,這些細微的動作可以被忽略而不影響檢測效果。因此HOG特徵是特別適合於做圖像中的人體檢測的。

三、開發準備

打開Xfce終端,下載並安裝 OpenCV的相關依賴。

$ sudo pip install numpy$ sudo apt-get install python-opencv

遇到是否安裝的詢問時,輸入y,按回車鍵繼續安裝。安裝時間較長,並且視網絡狀態而定。

下載實驗所需的圖片數據:

$ wget http://labfile.oss.aliyuncs.com/courses/794/cat.zip$ wget http://labfile.oss.aliyuncs.com/courses/794/other.zip$ wget http://labfile.oss.aliyuncs.com/courses/794/predict.zip

這三組數據分別是含有貓的圖片,沒有貓的圖片,以及用於測試SVM分類器的數據集。

下載後,解壓得到圖片:

$ unzip cat.zip$ unzip other.zip$ unzip predict.zip

這些圖片都是從網上下載的。如果想使用自己下載的圖片,也沒有問題。需要注意爹是,輸入到分類器的圖片都是固定像素的。我們需要對下載的圖片數據進行處理,使其符合我們程序的要求。將大圖片裁減成固定像素的小圖片的程序如下:

# -*- coding: utf-8 -*-import numpy as npimport cv2from os.path import dirname, join, basenamefrom glob import globnum=0for fn in glob(join(dirname(__file__)+'\other', '*.jpg')):    img = cv2.imread(fn)    res=cv2.resize(img,(64,128),interpolation=cv2.INTER_AREA)    cv2.imwrite(r'D:\ECLIPSE-PROJECT\Python\my_opencv\other_64_128\test'+str(num)+'.jpg',res)    num=num+1print 'all done!'  cv2.waitKey(0)cv2.destroyAllWindows()

使用程序時,請替換輸出路徑為一個已存在的路徑,即替換這一句中的路徑:

cv2.imwrite(r'D:\ECLIPSE-PROJECT\Python\my_opencv\other_64_128\test'+str(num)+'.jpg',res)

這段代碼會掃描Python腳本所在的文件夾的子文件夾other文件夾下的所有.jpg文件,然後使用OpenCV讀取圖片數據,並按照指定的大小進行縮放,將縮放後的結果寫入到指定目錄下的指定圖片中。

四、實驗步驟

4.1 訓練數據集

首先,我們根據已經分類好的數據集來對分類器進行訓練。我們的cat文件夾下全是貓的照片,而other文件夾下全不是貓,已經完成了貼標籤這個過程了。讓程序從這兩組數據裡學習,計算分類的方法。

使用HOG+SVM算法進行訓練前,需要先計算每張圖片的HOG值以得到供SVM分類器使用的輸入向量。計算該值的算法實現的一般過程為:

灰度化(OpenCV處理圖像時,一般都處理為灰度圖像,忽略顏色幹擾)

採用Gamma校正法對輸入圖像進行顏色空間的標準化(歸一化);目的是調節圖像的對比度,降低圖像局部的陰影和光照變化所造成的影響,同時可以抑制噪音的幹擾;

計算圖像每個像素的梯度(包括大小和方向);主要是為了捕獲輪廓信息,同時進一步弱化光照的幹擾。

將圖像劃分成小cells(例如6*6像素/cell);

統計每個cell的梯度直方圖(不同梯度的個數),即可形成每個cell的descriptor;

將每幾個cell組成一個block(例如3*3個cell/block),一個block內所有cell的特徵descriptor串聯起來便得到該block的HOG特徵descriptor。

將圖像image內的所有block的HOG特徵descriptor串聯起來就可以得到該image(你要檢測的目標)的HOG特徵descriptor了。這個就是最終的可供分類使用的特徵向量了。

在本實驗中,沒有嚴格按照上述的過程實現,我們採用了下述方法:我們在每個cell內計算X和Y方向的Sobel導數。然後找到每個像素的梯度和方向。此梯度被量化為16*16個整數值。把每個圖像分成四個子圖方塊。對於每個子正方形,計算加權其幅度的方向(16*16bins)的直方圖。因此,每個子圖給我們一個包含16*16個值的向量。四個這樣的向量(分別代表四個子圖的16*16向量)一起給我們一個特徵向量包含1024個值。這就是我們用來訓練數據的特徵向量。這部分的代碼如下所示:

bin_n = 16*16 # Number of binsdef hog(img):    x_pixel,y_pixel=194,259    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)    mag, ang = cv2.cartToPolar(gx, gy)    bins = np.int32(bin_n*ang/(2*np.pi))    # quantizing binvalues in (0...16)    bin_cells = bins[:x_pixel/2,:y_pixel/2], bins[x_pixel/2:,:y_pixel/2], bins[:x_pixel/2,y_pixel/2:], bins[x_pixel/2:,y_pixel/2:]    mag_cells = mag[:x_pixel/2,:y_pixel/2], mag[x_pixel/2:,:y_pixel/2], mag[:x_pixel/2,y_pixel/2:], mag[x_pixel/2:,y_pixel/2:]    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]    hist = np.hstack(hists)     # hist is a 64 bit vector#    print hist.shape#    print type(hist)    return hist

完整的代碼如下所示,程序首先掃描cat和other文件夾內的圖片,然後用灰度方式讀入,計算每個圖片的hog值,然後建立SVM分類器,使用輸入的數據進行訓練,將訓練結果保存於svm_cat_data.dat文件中。

#file name:train.pyimport numpy as npimport cv2#from matplotlib import pyplot as pltfrom os.path import dirname, join, basenameimport sysfrom glob import globbin_n = 16*16 # Number of binsdef hog(img):    x_pixel,y_pixel=194,259    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)    mag, ang = cv2.cartToPolar(gx, gy)    bins = np.int32(bin_n*ang/(2*np.pi))    # quantizing binvalues in (0...16)    bin_cells = bins[:x_pixel/2,:y_pixel/2], bins[x_pixel/2:,:y_pixel/2], bins[:x_pixel/2,y_pixel/2:], bins[x_pixel/2:,y_pixel/2:]    mag_cells = mag[:x_pixel/2,:y_pixel/2], mag[x_pixel/2:,:y_pixel/2], mag[:x_pixel/2,y_pixel/2:], mag[x_pixel/2:,y_pixel/2:]    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]    hist = np.hstack(hists)     # hist is a 64 bit vector#    print hist.shape#    print type(hist)    return hist#print glob(join(dirname(__file__)+'/cat','*.jpg'))img={}num=0for fn in glob(join(dirname(__file__)+'/cat', '*.jpg')):    img[num] = cv2.imread(fn,0)#參數加0,只讀取黑白數據,去掉0,就是彩色讀取。#    print img[num].shape    num=num+1print num,' num'positive=numfor fn in glob(join(dirname(__file__)+'/other', '*.jpg')):    img[num] = cv2.imread(fn,0)#參數加0,只讀取黑白數據,去掉0,就是彩色讀取。#    print img[num].shape    num=num+1print num,' num'print positive,' positive'trainpic=[]for i in img:#    print type(i)    trainpic.append(img[i])svm_params = dict( kernel_type = cv2.SVM_LINEAR,                    svm_type = cv2.SVM_C_SVC,                    C=2.67, gamma=5.383 )#img = cv2.imread('02.jpg',0)#hist_full = cv2.calcHist([img],[0],None,[256],[0,256])#print hist_full#plt.plot(hist_full)#plt.show()#img1 = cv2.imread('02.jpg',0)#temp=img[0].ravel()#print temp#print len(temp)temp=hog(img[0])print temp.shape#hogdata = [map(hog,img[i]) for i in img]hogdata = map(hog,trainpic)print np.float32(hogdata).shape,' hogdata'trainData = np.float32(hogdata).reshape(-1,bin_n*4)print trainData.shape,' trainData'responses = np.float32(np.repeat(1.0,trainData.shape[0])[:,np.newaxis])responses[positive:trainData.shape[0]]=-1.0print responses.shape,' responses'print len(trainData)print len(responses)print type(trainData)svm = cv2.SVM()svm.train(trainData,responses, params=svm_params)svm.save('svm_cat_data.dat')

注意,如果想要運行此程序並得到正確的結果,需要在控制臺輸入:

$ python /home/shiyanlou/train.py

如果只輸入:

$ python train.py

也能看到輸出,只不過執行到一半會報錯。

這其中的原因,主要是程序中使用了glob包來枚舉文件夾下的某個類型的文件。

正常運行後,可以見到文件夾下生成的數據:

同時也會看到,當導入OpenCV包的時候,程序報錯libdc1394 error: Failed to initiallize libdc1394,這個錯誤,是因為沒有加載攝像頭驅動。實驗樓使用的雲伺服器,很可能沒有攝像頭,所以報錯。但這個錯誤並不影響我們的實驗,所以忽略即可。在自己的筆記本上或者臺式機上,只要正確安裝了驅動,不會有這個錯誤。

做到這裡,項目只完成了一半,後續步驟及詳細代碼請點擊閱讀原文觀看。學編程,當然是要一遍敲一遍看啦!


猛戳「閱讀原文」

查看完整《基於SVM的貓咪圖片識別器

相關焦點

  • HOG+SVM實現圖像識別
    圖像識別,主要是通過圖像的輪廓。所以先提取訓練圖像的輪廓特徵。然後使用SVM支持向量機模型進行學習,從而實現圖像識別。首先把圖片劃分成多個8*8的cell,每個cell包含8*8*2=128個值(梯度和角度),把這128個值用長度為9的數組來表示,這個數組就是梯度直方圖。這種表示方法不僅使得特徵更加緊湊,而且對單個像素值的變化不敏感,也就是能夠抗噪聲幹擾。直方圖數組的9個數值,對應於角度0、20、40、60... 160。也就是9 bins。
  • 基於HOG+SVM的目標檢測與識別
    國家也投入了大量的財力物力推進其發展,在各大高校、科研院所也有相應的機構進行專門的研發,在研究生學歷攻讀階段,也有相應的基礎和高級課程的設計。今天,我不是以一個科研人員的身份進行說話,而是站在一個普通的圖像算法應用工程師的角度總結下我的工作經驗,不足之處,多多海涵!     下面,我以一個人臉目標的檢測為例,使用OpenCV2.4.7做一個HOG+SVM的檢測實例。
  • 模板識別:使用OpenCV實現基於特徵的圖像對齊
    詳細信息見:https://www.robots.ox.ac.uk/~vgg/rg/papers/brisk.pdf定位器和特徵描述子應用很廣泛。計算機視覺的許多應用中,我們分兩步解決識別問題a)定位;2)識別。例如,為了實現面部識別系統,我們首先需要一個面部檢測器,其輸出面部所在矩形的坐標。檢測器不知道或不關心該人是誰。唯一的工作就是找到一張臉。
  • 機器學習變量篩選系列教程三:SVM算法
    支持向量機(support vector machines, SVM)是一種常用的分類算法,核心採用的是線性分類器,是一種二分類模型。      SVM的基本模型是定義在特徵空間上的間隔最大的線性分類器,模型訓練即求解能夠正確劃分訓練數據集並且幾何間隔最大的分離超平面。
  • 用Python+OpenCV+PIL構建貓臉識別器
    當我用圖像測試代碼時,我發現其中有些圖像中有動物,但是我們創建的人臉檢測模型並不能識別動物的面部,所以我想知道是否有一種方法可以在圖像中檢測動物的臉,於是我在網際網路上做了一點研究,發現這是可能的,而且在Kaggle上找到了很多免費的數據集,裡面有幾百張圖片。Kaggle是一個尋找免費數據集的好地方,他們也在組織數據科學競賽,這是一個練習數據科學技能和向他人學習的好地方。不管怎樣,回到我們的項目。
  • opencv +數字識別
    ,比如銀行卡識別,以及車牌識別等,在AI領域有很多圖像識別算法,大多是居於opencv 或者谷歌開源的tesseract 識別.它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的很多通用算法。以上幾種ocr 識別比較,最後選擇了opencv 的方式進行ocr 數字識別,下面講解通過ocr識別的基本流程和算法.open
  • 機器學習算法一覽(附python和R代碼)
    寫這篇文章的目的,就是希望它可以讓有志於從事數據科學和機器學習的諸位在學習算法的路上少走些路。我會在文章中舉例一些機器學習的問題,你們也可以在思考解決這些問題的過程中得到啟發。我也會寫下對於各種機器學習算法的一些個人理解,並且提供R和Python的執行代碼。讀完這篇文章,讀者們至少可以行動起來親手試試寫一個機器學習的程序。
  • 訓練SVM進行行人檢測
    訓練好的SVM分類器保存為XML文件,然後根據其中的支持向量和參數生成OpenCV中的HOG描述子可用的檢測子參數,再調用OpenCV中的多尺度檢測函數進行行人檢測。#include <iostream>#include <fstream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp
  • 使用python+sklearn實現管道、Anova和SVM
    0.          0.          0.          0.          0.          0.  -0.04736524  0.          0.          0.          0.          0.
  • [OpenCV實戰]45 基於OpenCV實現圖像哈希算法
    基於OpenCV實現圖像哈希算法目前有許多算法來衡量兩幅圖像的相似性,本文主要介紹在工程領域最常用的圖像相似性算法評價算法:圖像哈希算法(img hash)。圖像哈希算法通過獲取圖像的哈希值並比較兩幅圖像的哈希值的漢明距離來衡量兩幅圖像是否相似。兩幅圖像越相似,其哈希值的漢明距離越小,通過這種方式就能夠比較兩幅圖像是否相似。
  • 算法集錦(11)| 自動駕駛 | 基於HOG和SVM的車輛識別算法
    , u_img, v_img = source.visualize()= 410, 390, 380, 380 6boxed_images, strips = [], [] 7for ws, wp in zip(window_sizes, strip_positions): 8  bounding_boxes = slider.locate(frame = this_frame, window_size = ws, window_position
  • 使用Python訓練SVM模型識別手寫體數字
    Python對SVM模型進行訓練並對手寫數字進行識別的過程。準備工作手寫數字識別的原理是將數字的圖片分割為8X8的灰度值矩陣,將這64個灰度值作為每個數字的訓練集對模型進行訓練。手寫數字所對應的真實數字作為分類結果。
  • 機器學習之分類算法:SVM [5. 實例解析]
    類中方法:fit(X,y[, sample_weight]) 用訓練數據擬合svm模型predict(X) 預測待測樣本X的類別值decision_function(X) 決策函數,獲得樣本X到分類超平面的距離score(X,y[, sample_weight]) 計算測試集的平均準確率get_params([deep]) 獲得模型(分類器類)的參數。
  • svm是什麼?如何找到正確的超平面
    在機器學習中,支持向量機是在分類與回歸分析中分析數據的監督式學習模型與相關的學習算法。給定一組訓練實例,每個訓練實例被標記為屬於兩個類別中的一個或另一個,SVM訓練算法創建一個將新的實例分配給兩個類別之一的模型,使其成為非概率二元線性分類器。SVM模型是將實例表示為空間中的點,這樣映射就使得單獨類別的實例被儘可能寬的明顯的間隔分開。
  • opencv怎麼把圖片「掰直」(源碼)
    本次實戰,對於圖像的矯正使用了兩種矯正思路: 基於輪廓提取的矯正算法🧡整體思路:圖片灰度化,二值化檢測輪廓,並篩選出目標輪廓(通過橫縱比或面積去除幹擾輪廓)獲取目標輪廓的最小外接矩形獲取最小外接矩形的四頂點,並定義矯正圖像後的四頂點
  • 一個項目帶你進入機器學習算法--預測心臟病(二)
    現在,我們已經將數據分為訓練集和測試集,是時候建立機器學習模型了。我們將嘗試6種不同的機器學習模型:邏輯回歸最近鄰分類器支持向量機決策樹分類器隨機森林分類器XGBoost分類器from sklearn.metrics import accuracy_score, confusion_matrix, classification_reportdef
  • 【OpenCV入門】手把手教你圖片預處理
    子豪 發自 凹非寺 量子位 報導 | 公眾號 QbitAIOpenCV是一個跨平臺計算機視覺和機器學習算法庫它不僅能用來實現各種複雜的算法,還能夠對圖像進行預處理:包括圖像的平移、旋轉、縮放、翻轉、裁剪。希望把這些知識分享給初學者。圖像平移我們使用OpenCV提供的仿射變換函數cv.warpAffine()沿x和y軸移動圖像。Step1. 調用一個函數cv.warpAffine()。Step2.
  • 使用OpenCV+Python進行人臉識別
    在本文的最後,你將能夠開發一個人臉識別程序來識別圖像中的人臉!目錄人臉檢測概述如果機器能夠在沒有人工幹預的情況下自動檢測圖像中的物體會怎樣?讓我們看看:人臉檢測是我們在圖像中檢測人臉的問題。人臉可能略有不同,但可以肯定地說,所有人臉都有特定的特徵。存在各種人臉檢測算法, Viola-Jones算法是現在也在使用的最古老的方法。
  • 機器學習之sklearn基礎教程!
    機器學習算法主要步驟有:調整算法本次分享主要把目光聚集在"選擇分類器並優化算法",我們將用學術界和工業界常用的機器學習庫sklearn,對算法進行實踐。本文內容:1.solver:指定優化器類型,可選『newton-cg』, 『lbfgs』, 『liblinear』, 『sag』, 『saga』具體的優化方法參考:機器學習中的優化算法!max_iter:算法收斂的最大迭代次數,默認100。multi_class:不常用。
  • 基於隨機森林、svm、CNN機器學習的風控欺詐識別模型
    數據風控「的實際意義是用DT(Data Technology)識別欺詐,將欺詐防患於未然,然後淨化信用體系。挑戰信貸風險和欺詐風險是消費金融業務發展中最重要的兩種風險,信息不對稱是導致這些風險的主要原因。「 數據防欺詐」是數據風控武器之一。這種武器的力量的重要保證是數據和信息收集的完整性和準確性。