Python-OpenCV 18. 圖像分類

本系統文章來自《機器學習實踐指南 案例應用解析 第2版》學習筆記。

一、定義

圖像分類利用計算機對圖像進行分析,根據圖像信息的不同特徵,將不同類別的圖像區分開來。

算法過程

  1. 準備樣本圖像。樣本圖像能代表所屬類別中儘可能多的圖像
  2. 提取每個樣本的特徵後,形成類別特徵碼
  3. 應用機器學習算法對類別特徵碼進行學習,提取特徵包含的圖像知識
  4. 判斷未知圖像所屬類別

前面記錄了計算圖片相似度的方法,用其中部分算法,就可以實現圖像分類的實現。

二、餘弦相似度實現圖片分類

餘弦相似度通過測量兩個向量內積空間的餘弦值來度量它們之間的相似性,尤其適用於任何維度的向量比較中,因此屬於高維空間應用較多的機器學習算法。通常來說,數字圖像包含的特徵碼較多,而這些特徵組就屬於高維空間,這正是餘弦相似度算法應用的範圍,算法將每個圖像的特徵組轉化為高維空間的向量,兩個向量之間的角度之餘弦值可用於確定兩個向量是否大致指向相同的方向。

在圖像分類中應用餘弦相似度算法的關鍵在於:計算這些代表每個圖像特徵的向量的內積空間的夾角餘弦值,從而度量圖像之間的相似性。對於相似性的衡量標準有以下兩種:

為相似性設置一個閾值,在這個閾值以內的都屬於同一類別圖像。這種標準可以將圖像劃分為多種類型,例如:高樓不但屬於城市美景,而且屬於寫字樓景觀。
選擇與樣本向量的餘弦相似度最接近1的圖像為該類別圖像。這種標準只能將圖像劃分為一種類別。

1. 算法描述

特徵提取一直是圖像處理和計算機視覺研究領域的值得探討的問題。如何準確定位和提取關鍵特徵往往是首先需要需要解決的問題之一,是提高識別率等問題的重要前期準備和關鍵因素。目前圖像特徵提取算法較多,不同的算法適應於不同的圖像分析任務。

本節原理: 把圖像上的點分為不同的子集,這些子集往往屬於孤立的點、連續的曲線或者連續的區域。將這些點按區域組成子集,提取子集的特徵後,將每個子集的特徵作為圖像的一個特徵項來進行計算。

1) 樣本特徵
設圖像分為m個區域,每個區域有n個像素,每個像素在圖像矩陣中以紅、綠、藍三色來表示,且區域特徵計算方式為:
區域特徵碼=(∑i∈n像素i顏色的紅色分量值n,∑i∈n像素i顏色的綠色分量值n,∑i∈n像素i顏色的藍色分量值n)
區域特徵碼=(∑i∈n像素i顏色的紅色分量值n,∑i∈n像素i顏色的綠色分量值n,∑i∈n像素i顏色的藍色分量值n)

那麼,樣本特徵碼矩陣為3xm,即共3行m列,這3行分別代表紅、綠、藍三個分量,每列為各分量的區域特徵碼。
2) 類別特徵
這裡為每個類別準備了3個樣本,類別特徵的計算方式為:
類別特徵碼=(∑i∈n樣本i顏色的紅色分量特徵值n,∑i∈n樣本i顏色的綠色分量特徵值n,∑i∈n樣本i顏色的藍色分量特徵值n)
類別特徵碼=(∑i∈n樣本i顏色的紅色分量特徵值n,∑i∈n樣本i顏色的綠色分量特徵值n,∑i∈n樣本i顏色的藍色分量特徵值n)

其中,樣本i是屬於該類別的樣本。
在計算出類別特徵後,算法對樣本學習完畢。當有未知圖像需要分類時,首先計算其圖像的樣本特徵,然後將樣本特徵和類別特徵映射為高維空間的向量,最後計算這兩個向量的餘弦相似度,選擇餘弦相似度最大的類別為未知圖像對應的類別。

2. 算法應用

下面的示例每個類別3個樣本圖像,提取類別特徵碼,然後將待分類圖像劃分到藍天風景、樹木風景、瀑布風景三個分類中。

# -*- coding: utf-8 -*-
import cv2
import numpy as np

print(u'正在處理中')
w_fg = 20
h_fg = 15
picflag = 3


def readpic(fn):
# 返回圖像特徵碼
fnimg = cv2.imread(fn)
img = cv2.resize(fnimg,(800,600))
w = img.shape[1]
h = img.shape[0]
w_interval =int( w/w_fg)
h_interval =int( h/h_fg)
alltz = []
alltz.append([])
alltz.append([])
alltz.append([])
for now_h in range(0,h,h_interval):
for now_w in range(0,w,w_interval):
b = img[now_h:now_h + h_interval, now_w:now_w+w_interval,0]
g = img[now_h:now_h + h_interval, now_w:now_w+w_interval,1]
r = img[now_h:now_h + h_interval, now_w:now_w+w_interval,2]
btz = np.mean(b)
gtz = np.mean(g)
rtz = np.mean(r)
alltz[0].append(btz)
alltz[1].append(gtz)
alltz[2].append(rtz)
return alltz


def get_cossimi(x,y):
myx = np.array(x)

myy = np.array(y)
cos1 = np.sum(myx*myy)
cos21 = np.sqrt(sum(myx*myx))
cos22 = np.sqrt(sum(myy*myy))
return cos1/float(cos21*cos22)

# x和d樣本初始化
train_x = []
d = []

# 讀取圖像,提取每類圖像的特徵
# 計算類別特徵碼,通過每個類別所有樣本的區域特徵的平均值,提取類別特徵
for ii in range(1,picflag+1):
smp_x = []
b_tz = np.array([0,0,0])
g_tz = np.array([0,0,0])
r_tz = np.array([0,0,0])
mytz = np.zeros((3,w_fg*h_fg))
for jj in range(1,3):
fn = 'p'+str(ii)+'-' + str(jj) + '.png'
tmptz = readpic(fn)
mytz += np.array(tmptz)
mytz /=3
train_x.append(mytz[0].tolist()+mytz[1].tolist() + mytz[2].tolist())

# 計算目標圖片的分類
# 計算待分類圖像的特徵碼與每個類別特徵碼之間的餘弦距離,距離最大者為圖像所屬分類
fn = 'test.png'
testtz = np.array(readpic(fn))
simtz = testtz[0].tolist() + testtz[1].tolist() + testtz[2].tolist()
maxtz = 0
nowi = 0
for i in range(0,picflag):
nowsim = get_cossimi(train_x[i], simtz)
if nowsim>maxtz:
maxtz = nowsim
nowi = i
print(u'%s 屬於第 %d 類' % (fn,nowi+1))

運行代碼,準備訓練圖片

p1-1.png p1-2.png p1-3.png 屬於分類1
p2-1.png p2-2.png p2-3.png 屬於分類2
p3-1.png p3-2.png p3-3.png 屬於分類3

運行結果對給定的待分類圖片test.png進行了準確的自動分類。

Python-OpenCV 18. 圖像分類

三、PCA 圖像特徵提取算法

PCA (Principal Component Analysis),是一種掌握事物主要矛盾的統計分析方法,它可以從多元事物中解析出主要影響因素,揭示事物的本質,簡化複雜的問題。
它可以用於圖像矩陣降維,以降維後的矩陣為基礎提取圖像特徵。當提取的圖像特徵維度比較高時,為了簡化計算量以及存儲空間,需要對這些高維數據進行一種程度的降維,並儘量保證數據不失真。
此外,PCA算法還可應用於圖像矩陣,便於後期識別算法並進一步加工,因為圖像特徵組含有的不明顯的特徵值會影響識別的精度。
對於高維的向量,PCA方法求得一個k維特徵的投影矩陣,這個投影矩陣可以將特徵從高維降到低維。投影矩陣民可以叫作變化矩陣。新的低維特徵必須每個維都正交,特徵向量都是正交的。
通過求樣本矩陣的協方差矩陣,然後注出協方差矩陣的特徵向量,這些特徵向量就可以構成這個投影矩陣了。特徵向量的選擇取決於協方差矩陣的特徵值大小。
——摘自百度百科
其它還有 svm、深度學習等方式實現圖片分類,後面再慢慢補充學習。


分享到:


相關文章: