一、圖像分類的過(guò)程

圖片必須經(jīng)過(guò)標(biāo)注
圖片的類別為有限的集合,如{貓、狗、牛、馬、狼}
每個(gè)類別的圖片數(shù)量接近,如果不同類別圖片的數(shù)量差異很大,訓(xùn)練出來(lái)的分類器容易傾向于圖片數(shù)量多的類別劃分訓(xùn)練/測(cè)試集
在訓(xùn)練之前,要把數(shù)據(jù)集劃分為訓(xùn)練集(學(xué)習(xí)分類器)和測(cè)試集(對(duì)分類器進(jìn)行評(píng)估)
訓(xùn)練集和測(cè)試集相互獨(dú)立,不重合!
3.特征表示 :對(duì)圖片進(jìn)行數(shù)值處理,轉(zhuǎn)換成計(jì)算機(jī)可理解的特征,常用特征:
- 顏色直方圖(Color Histograms)
- 方向梯度直方圖(Histogram of Oriented Gradients,HOG)
- 局部二值模式(Local Binary Pattern,LBP)
分類算法 :一般分類算法即可:邏輯回歸,支持向量機(jī)(SVM),隨機(jī)森林
模型評(píng)估 : 混淆矩陣(Confusion Matrix)
- 精確度(Precision)
- 召回率(Recall)
- F1值(F1 score) recall與Precision的調(diào)和均值
二、開(kāi)發(fā)環(huán)境:(安裝)OpenCV 計(jì)算機(jī)視覺(jué)庫(kù)
安裝:
方法1:conda install -c menpo opencv
方法2:conda install --channel https://conda.anaconda.org/menpo opencv3
方法3:pip/conda install opencv-python
方法4:使用 whl 文件進(jìn)行安裝,進(jìn)入網(wǎng)站 http://www.lfd.uci.edu/~gohlke/pythonlibs/。
下載與當(dāng)前環(huán)境兼容的 opencv 文件。切換到該文件所在的目錄,在命令行環(huán)境下使用
例如:安裝文件:opencv_python-3.2.0-cp35-cp35m-win_amd64.whl
pip install opencv_python-3.2.0-cp35-cp35m-win_amd64.whl
opencv 的導(dǎo)入:
import cv2
cv2.__version__
OpenCV的使用
在線文檔:http://docs.opencv.org/2.4.11/
三、顏色空間(顏色模型:RGB,HSV,Lab)
RGB顏色空間有:
RGB :模型容易理解,連續(xù)變換顏色時(shí)不直觀
(紅red 綠green 藍(lán)blue)三原色:取值范圍都是:[0,255],[0,255],[0,255]
HSV: 是為了數(shù)字化圖像提出來(lái)了,不能很好的表示人眼解釋圖像過(guò)程
- H (Hue)色相:[0,360]
- S (Saturation)飽和度,即色彩純凈度,0飽和度為白色
- V (Value/Brightness):明度 0明度為純黑色
在OpenCV中,顏色范圍:
- H = [0,179]
- S = [0,255]
- V = [0,255]
Lab:顏色之間的歐式距離有具體含義–距離越大,人眼感官兩種顏色差距越遠(yuǎn)
- L 通道:像素亮度,上白下黑 中間灰
- a 通道:左綠 右紅
- b 通道:一端純藍(lán),一端純黃
灰度圖:每個(gè)像素[0,255]
根據(jù)人眼敏感度,把RGB圖片轉(zhuǎn)換為灰度圖,不是簡(jiǎn)單把RGB每個(gè)通道取平均值
而是:Y = 0.299R + 0.587G + 0.114*B

3.1 opencv–HSV顏色空間
HSV(hue,saturation,value)顏色空間的模型對(duì)應(yīng)于圓柱坐標(biāo)系中的一個(gè)圓錐形子集,圓錐的頂面對(duì)應(yīng)于V=1. 它包含RGB模型中的R=1,G=1,B=1 三個(gè)面,所代表的顏色較亮。
色彩H由繞V軸的旋轉(zhuǎn)角給定。紅色對(duì)應(yīng)于 角度0° ,綠色對(duì)應(yīng)于角度120°,藍(lán)色對(duì)應(yīng)于角度240°。
在HSV顏色模型中,每一種顏色和它的補(bǔ)色相差180° 。 飽和度S取值從0到1,所以圓錐頂面的半徑為1。
在圓錐的頂點(diǎn)(即原點(diǎn))處V=0,H和S無(wú)定義, 代表黑色。
圓錐的頂面中心處 S=0,V=1,H無(wú)定義,代表白色。
從該點(diǎn)到原點(diǎn)代表亮度漸暗的灰色,即具有不同 灰度的灰色。
對(duì)于這些點(diǎn),S=0,H的值無(wú)定義。可以說(shuō),HSV模型中的V軸對(duì)應(yīng)于RGB顏色空間中的主對(duì)角線。 在圓錐頂面的圓周上的顏色,V=1,S=1,這種顏色是純色。
HSV顏色空間它錐形的鉆換模型中可以理解到: hue 通道的取值范圍就應(yīng)該是 0-360度,單數(shù)在opencv中其取值范圍 [0,180]。

在opencv-hsv取值詳情如下:

顏色庫(kù):


原本輸出的 HSV 的取值范圍分別是 0-360, 0-1, 0-1;但是為了匹配目標(biāo)數(shù)據(jù)類型 OpenCV 將每個(gè)通道的取值范圍都做了修改,于是就變成了 0-180, 0-255, 0-255,并且同時(shí)解釋道:為了適應(yīng) 8bit 0-255 的取值范圍,將 hue 通道 0-360 的取值范圍做了減半處理
四、OpenCV處理圖片
4.1 直接讀取圖片
import cv2 #導(dǎo)入 Opencv
import os
import numpy as np
import matplotlib.pyplot as plt
output_dir = 'output2' #設(shè)置輸出文件夾,若不存在則創(chuàng)建
if not os.path.exists(output_dir):
os.mkdir(output_dir)
img_file = './../image.png' #讀取圖片
img = cv2.imread(img_file)
type(img) #讀入圖片后得到ndarray 對(duì)象
img.shape #ndarray的三個(gè)維度分別是圖片的:高,寬,通道
# pyplot.imgshow 在顯示圖片時(shí)是按照RGB通道順序顯示,cv2則相反
# 需要通過(guò) np.flip(img,axis = 2) 調(diào)整3個(gè)通道的順序(若不調(diào)整圖片顏色失真)
plt.imshow(np.flip(img,axis = 2))
plt.axis('off')
plt.show() #圖1
plt.imshow(img)
plt.axis('off') #不顯示坐標(biāo)
plt.show() #圖2
#輸出并保存圖片
output_image = os.path.join(output_dir,'image.png')
cv2.imwrite(output_image,img)

4.2 讀取圖片并簡(jiǎn)單處理—圖像特征:顏色直方圖
OpenCV-Python中調(diào)用的直方圖計(jì)算函數(shù)為cv2.calcHist。
"""
hist = cv2.calcHist([image], # 傳入圖像(列表)
[0], # 使用的通道(使用通道:可選[0],[1],[2])
None, # 沒(méi)有使用mask(蒙版)
[256], # HistSize
[0.0,255.0]) # 直方圖柱的范圍
# return->list
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
def calcAndDrawHist(image, color):
hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0])
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)
histImg = np.zeros([256,256,3], np.uint8)
hpt = int(0.9* 256);
for h in range(256):
intensity = int(hist[h]*hpt/maxVal)
cv2.line(histImg,(h,256), (h,256-intensity), color)
return histImg
if __name__ == '__main__':
original_img = cv2.imread("666.png")
img = cv2.resize(original_img,None,fx=0.6,fy=0.6,interpolation = cv2.INTER_CUBIC)
b, g, r = cv2.split(img)
histImgB = calcAndDrawHist(b, [255, 0, 0])
histImgG = calcAndDrawHist(g, [0, 255, 0])
histImgR = calcAndDrawHist(r, [0, 0, 255])
cv2.imshow("histImgB", histImgB)
cv2.imshow("histImgG", histImgG)
cv2.imshow("histImgR", histImgR)
cv2.imshow("Img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

顏色空間 RGB–HSV–Lab
RGB顏色空間
import cv2
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
pic_file = '../data/images/image_crocus_0003.png'
img_bgr = cv2.imread(pic_file, cv2.IMREAD_COLOR) #OpenCV讀取顏色順序:BGR
img_b = img_bgr[..., 0]
img_g = img_bgr[..., 1]
img_r = img_bgr[..., 2]
fig = plt.gcf() #圖片詳細(xì)信息
fig = plt.gcf() #分通道顯示圖片
fig.set_size_inches(10, 15)
plt.subplot(221)
plt.imshow(np.flip(img_bgr, axis=2)) #展平圖像數(shù)組并顯示
plt.axis('off')
plt.title('Image')
plt.subplot(222)
plt.imshow(img_r, cmap='gray')
plt.axis('off')
plt.title('R')
plt.subplot(223)
plt.imshow(img_g, cmap='gray')
plt.axis('off')
plt.title('G')
plt.subplot(224)
plt.imshow(img_b, cmap='gray')
plt.axis('off')
plt.title('B')
plt.show()

HSV顏色空間
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
img_h = img_hsv[..., 0]
img_s = img_hsv[..., 1]
img_v = img_hsv[..., 2]
fig = plt.gcf() # 分通道顯示圖片
fig.set_size_inches(10, 15)
plt.subplot(221)
plt.imshow(img_hsv)
plt.axis('off')
plt.title('HSV')
plt.subplot(222)
plt.imshow(img_h, cmap='gray')
plt.axis('off')
plt.title('H')
plt.subplot(223)
plt.imshow(img_s, cmap='gray')
plt.axis('off')
plt.title('S')
plt.subplot(224)
plt.imshow(img_v, cmap='gray')
plt.axis('off')
plt.title('V')
plt.show()

Lab*顏色空間
img_lab = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2LAB)
img_ls = img_lab[..., 0]
img_as = img_lab[..., 1]
img_bs = img_lab[..., 2]
# 分通道顯示圖片
fig = plt.gcf()
fig.set_size_inches(10, 15)
plt.subplot(221)
plt.imshow(img_lab)
plt.axis('off')
plt.title('L*a*b*')
plt.subplot(222)
plt.imshow(img_ls, cmap='gray')
plt.axis('off')
plt.title('L*')
plt.subplot(223)
plt.imshow(img_as, cmap='gray')
plt.axis('off')
plt.title('a*')
plt.subplot(224)
plt.imshow(img_bs, cmap='gray')
plt.axis('off')
plt.title('b*')
plt.show()

灰度圖與其顏色直方圖
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
fig = plt.gcf()
fig.set_size_inches(5, 7.5)
plt.imshow(img_gray, cmap='gray')
plt.axis('off')
plt.title('Gray')
plt.show()
"""
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) → hist
參數(shù)說(shuō)明
images: 圖片列表
channels: 需要計(jì)算直方圖的通道。[0]表示計(jì)算通道0的直方圖,[0,1,2]表示計(jì)算通道0,1,2所表示顏色的直方圖
mask: 蒙版,只計(jì)算值>0的位置上像素的顏色直方圖,取None表示無(wú)蒙版
histSize: 每個(gè)維度上直方圖的大小,[8]表示把通道0的顏色取值等分為8份后計(jì)算直方圖
ranges: 每個(gè)維度的取值范圍,[lower0, upper0, lower1, upper1, ...],lower可以取到,upper無(wú)法取到
hist: 保存結(jié)果的ndarray對(duì)象
accumulate: 是否累積,如果設(shè)置了這個(gè)值,hist不會(huì)被清零,直方圖結(jié)果直接累積到hist中
"""
img_gray_hist = cv2.calcHist([img_gray], [0], None, [256], [0, 256])
plt.plot(img_gray_hist)
plt.title('Grayscale Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.show()

帶蒙版的顏色直方圖
# 讀取模板
mask_file = '../data/masks/mask_crocus_0003.png'
mask = cv2.imread(mask_file, cv2.IMREAD_UNCHANGED)
help(cv2.calcHist)
img_gray_hist_with_mask = cv2.calcHist([img_gray], [0], mask, [256], [0, 256])
"""
圖片按位與
cv2.bitwise_and(src1, src2[, dst[, mask]]) → dst
參數(shù)說(shuō)明
src1: 圖片1
src2: 圖片2
dst: 保存結(jié)果的ndarray對(duì)象
mask: 蒙版
"""
img_masked = cv2.bitwise_and(img_gray, img_gray, mask=mask)
plt.imshow(img_masked, cmap='gray')
plt.axis('off')
plt.title('Image with mask')
plt.show()
plt.plot(img_gray_hist_with_mask)
plt.title('Grayscale Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.show()

多個(gè)顏色直方圖
# 按R、G、B三個(gè)通道分別計(jì)算顏色直方圖
b_hist = cv2.calcHist([img_bgr], [0], None, [256], [0, 256])
g_hist = cv2.calcHist([img_bgr], [1], None, [256], [0, 256])
r_hist = cv2.calcHist([img_bgr], [2], None, [256], [0, 256])
# 顯示3個(gè)通道的顏色直方圖
plt.plot(b_hist, label='B', color='blue')
plt.plot(g_hist, label='G', color='green')
plt.plot(r_hist, label='R', color='red')
plt.legend(loc='best')
plt.xlim([0, 256])
plt.show()
# 顯示3個(gè)通道的顏色直方圖
plt.plot(b_hist, label='B', color='blue')
plt.plot(g_hist, label='G', color='green')
plt.plot(r_hist, label='R', color='red')
plt.legend(loc='best')
plt.xlim([0, 256])
plt.show()

按多個(gè)通道計(jì)算顏色直方圖
關(guān)于直方圖均衡詳情 請(qǐng)點(diǎn)擊
# 把一個(gè)像素的多個(gè)通道合在一起看作一個(gè)值
hist = cv2.calcHist([img_bgr], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
hist.shape
# 含義:B取值在[0, 32), G取值在[0, 32), R取值在[0, 32)的像素個(gè)數(shù)
hist[0, 0, 0]