杜琰琪
(安徽公安教育研究院,安徽 合肥230031)
Python 誕生于20 世紀90 年代初,是一種解釋型、面向?qū)ο蟆討B(tài)數(shù)據(jù)類型的高級程序設計語言,因其具有較強的可移植性、可擴展性和豐富的代碼庫受到程序員的喜愛,在圖像處理、數(shù)據(jù)統(tǒng)計和可視化表達等領域有著廣泛的應用。在圖像處理方面常用的包有CV2、PIL、Pillow、Pillow-SIMD。
在水產(chǎn)養(yǎng)殖中,水質(zhì)是至關重要的,需要時刻對水質(zhì)進行監(jiān)測,傳統(tǒng)方式是由專家或有經(jīng)驗的由人進行評判,但這種方式,對個人經(jīng)驗要求很高,也會存在主觀性偏差,因此重復性和推廣性有一定的局限。我們希望根據(jù)水質(zhì)圖片,利用自動化手段,根據(jù)專家經(jīng)驗再結(jié)合機器學習算法、計算機視覺、數(shù)字圖像處理等技術(shù)設計一個在線的水質(zhì)監(jiān)測系統(tǒng),搭建一個模型對輸入進來的圖片進行水質(zhì)類別的一個判斷。
通過歷史樣本數(shù)據(jù),通過機器學習,數(shù)據(jù)分分析,把不同水質(zhì)樣本的特點探究、總結(jié)出來形成一個模型,當新樣本進入模型后,模型能對新樣本進行預測。具體流程如圖1 所示:
圖1 水質(zhì)評價分析流程
通過PIL Image.open()函數(shù)將圖片轉(zhuǎn)換為像素矩陣,r,g,b=im.split()將每個像素分成三個顏色通道,r_d=np.asarray(r) 取出各通道像素值。以圖片的左上角為頂點,向右為橫軸,向下為縱軸,設原始圖像的大小是M*N,則截取寬從第到第個像素點,高從第個像素點到第個像素點的子圖像。則提取的是水樣圖像中央101*101 像素的圖像。原始圖像和截取后子圖像如圖2 所示。
圖2 截取圖像對比
圖像的特征主要包括:形狀特征、空間關系特征、顏色特征、紋理特征等。與幾何特征相比,顏色特征表現(xiàn)出較強的魯棒性,對于物體的大小和方向均不敏感。本應用中由于水色圖像是均勻的,故主要關注顏色特征[2]。
根據(jù)圖片反映出來的水色,引入專家知識將水質(zhì)類別分為五類如表1,不同顏色代表不同的水質(zhì)。
表1 水質(zhì)類別
顏色直方圖和顏色矩是反映圖像特征的兩種指標。顏色直方圖能簡單描述不同色彩在圖像中所占的比例,適用于描述難以自動分割的圖像和不需要考慮物體空間位置的圖像,但對于圖像中顏色的局部分布及每種顏色所處的空間位置卻無法描述。顏色矩可以表示圖像中顏色的分布,包括一階矩、二階矩和三階矩,每種顏色具有R、G、B 三個顏色通道,因此顏色矩具有9 個分量[3]。顏色直方圖產(chǎn)生的特征維數(shù)一般大于顏色矩陣的特征維數(shù),為了避免過多變量影響后續(xù)的分類效果,在本應用中采用顏色矩來表達圖像的特征。
采用二階中心矩的平方根,求標準差,反映了圖像顏色的分布均勻性、波動性,r2=rd.std()。
三階顏色矩:
def var(rd): #求顏色通道的三階顏色矩
mid = np.mean((rd-rd.mean())**3)
return np.sign(mid)*abs(mid)**(1/3)
在Python 環(huán)境下通過調(diào)用相關函數(shù),首先對采集的水質(zhì)圖像進行數(shù)據(jù)提取,然后對相應數(shù)據(jù)建立模型并對模型進行訓練,獲得水質(zhì)評價效果。
3.3.1 數(shù)據(jù)提取過程
通過for 循環(huán)把所有照片的特征都提取出來,共獲得197 行9 列的二維表數(shù)據(jù)如圖3,部分數(shù)據(jù)結(jié)果如圖4 所示。
圖3 獲取數(shù)據(jù)量
圖4 獲取的部分具體數(shù)據(jù)
獲取每張圖片R、G、B 三通道的三階矩數(shù)據(jù)代碼如下:
import os, re
from PIL import Image
import numpy as np
path = 'water_images/'
def var(rd): # 求顏色通道的三階顏色矩
mid = np.mean((rd-rd.mean())**3)
return np.sign(mid)*abs(mid)**(1/3)
def get_img_names(path=path):
file_names = os.listdir(path)
img_names = []
for i in file_names:
if re.findall('^d_d+.jpg$', i) != []:
img_names.append(i)
return img_names
def get_img_data(path=path):
img_names = get_img_names(path=path)
n = len(img_names)
data = np.zeros([n, 9])
labels = np.zeros([n])
for i in range(n):
img = Image.open(path+img_names[i]) # 讀取圖片數(shù)據(jù)
M, N = img.size # 像素矩陣的行列數(shù)
region = img.crop ((M/2-50, N/2-50, M/2+50, N/2+50)) # 截取圖像的中心區(qū)域
r, g, b = region.split() # 分割像素通道
rd = np.asarray(r) # 將圖片數(shù)據(jù)轉(zhuǎn)換為數(shù)組
gd = np.asarray(g)
bd = np.asarray(b)
data[i, 0] = rd.mean() # 一階顏色矩
data[i, 1] = gd.mean()
data[i, 2] = bd.mean()
data[i, 3] = rd.std() # 二階顏色矩
data[i, 4] = gd.std()
data[i, 5] = bd.std()
data[i, 6] = var(rd) # 三階顏色矩
data[i, 7] = var(gd)
data[i, 8] = var(bd)
labels[i] = img_names[i][0]
return data, labels
3.3.2 模型構(gòu)建與評價
抽取80%作為訓練樣本,剩下的20%作為測試樣本,進行模型訓練和模型的驗證,模型在測試集樣本上的精度為0.925,如圖5 所示,基本滿足實際應用需求。
圖5 模型精度
模型構(gòu)建與評價main 文件的主要代碼如下:
from data_process import get_img_data # 導入數(shù)據(jù)預處里的函數(shù)
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
data, labels = get_img_data() # 數(shù)據(jù)預處理
data_train, data_test, labels_train, labels_test = train_test_split (data,labels, test_size=0.2) # 將專家樣本拆分為訓練集和測試集
dtc = DecisionTreeClassifier() #調(diào)用決策樹分類器
dct.fit(data_train, label_train) # 模型訓練
dct.score(data_test,label_test) # 模型性能評估
joblib.dump(dct,'dct_water_rec.m') # 將訓練好的模型保存下來
model_new=joblib.load('dct_water_rec.m')
model_new.predict(data_test)
根據(jù)水質(zhì)圖片,利用圖像處理技術(shù)和相應模型,在Python 環(huán)境下實現(xiàn)了水質(zhì)的自動評價,正確率為92.5%,能實現(xiàn)預期功能,后期如需提高正確率,需要對模型進行優(yōu)化。