1.背景与挖掘目标
通过观察水色变化调控水质,维持水体生态系统平衡。
2.分析方法与过程
通过图像显示提取水样特征,提取反映图像本质的关键指标,以达到自动进行图像识别或分类的目的。图像特征包括颜色特征,纹理特诊,形状特征和空间关系特征等。此处采用颜色特征进行处理,基于颜色矩的特征提取。
步骤:
1.采集水样图像进行选择性抽取和实时抽取,形成建模数据和增量数据(即为训练集与测试集)
2.对上述数据集进行预处理,包括图像切割和颜色矩特征提取
3.对已完成数据进行预处理,有专家经验进行分类,构成专家样本
4.专家样本构建分类模型
5.利用模型进行水质评价
3.数据预处理
图像切割
由于图像较大,我们提取每张图片最中间的100x100像素构成子图象集。
特征提取
我们采用颜色矩来提取水样特征。这种方法的数学基础在于图像中任何的颜色分布均可以用它的矩来表示。此外,由于颜色分布信息主要集中在低阶矩中,因此仅采用颜色的一阶矩(mean)、二阶矩(variance)和三阶矩(skewness)就足以表达图像的颜色分布。与颜色直方图相比,该方法的另一个好处在于无需对特征进行向量化。因此,图像的颜色矩一共只需要9个分量(3个颜色分量,每个分量上3个低阶矩),与其他的颜色特征相比是非常简洁的。在实际应用中为避免低次矩较弱的分辨能力,颜色矩常和其它特征结合使用,而且一般在使用其它特征前起到过滤缩小范围(narrow down)的作用。
其中Ei是第i个颜色通道的一阶颜色矩,对于RGB颜色空间的图像,i=1,2,3,pij是第i个像素点的第j个颜色通道的颜色值。 在颜色矩的提取中,提取每个文件名中的类别和序号,同时针对所有图片进行同样操作。
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 04 20:16:15 2018
@author: Administrator
"""
#导入库文件
#import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import os
import pandas as pd
#查看
#img = mpimg.imread('eeeee/chapter9/chapter9/test/data/images/1_1.jpg')#读取一张图片
#l,w,t=img.shape #提取长,宽,通道数
#print(l, w, t)
#plt.imshow(img)
#寻找中心100x100像素点
#l_max =img.shape[0]//2+50
#l_min=img.shape[0]//2-50
#w_max =img.shape[1]//2+50
#w_min =img.shape[1]//2-50
#计算颜色矩特征
def img2vector(filename):
returnvect=np.zeros((1,9))
fr=mpimg.imread(filename)
l_max =fr.shape[0]//2+50
l_min=fr.shape[0]//2-50
w_max =fr.shape[1]//2+50
w_min =fr.shape[1]//2-50
water=fr[l_min:l_max, w_min:w_max, :].reshape(1, 10000, 3)
for i in range(3):
this = water[:,:,i]/255.
print this
returnvect[0,i]=np.mean(this) #0,1,2存储一阶颜色矩
returnvect[0,3+i]=np.sqrt(np.mean(np.square(this-returnvect[0,i])))#3,4,5存储二阶颜色矩
returnvect[0,6+i]=np.cbrt(np.mean(np.power(this-returnvect[0,i], 3)))#6,7,8存储三阶颜色矩
print returnvect
return returnvect
#计算每个图片的特征
trainfilelist=os.listdir('eeeee/chapter9/chapter9/test/data/images')#读取目录下文件列表
m=len(trainfilelist) #计算文件数目
labels=np.zeros((1,m))
train=np.zeros((1,m))
#trainingMat=[]
#print(trainfilelist)
trainingMat=np.zeros((m,9))
for i in range(m):
filenamestr=trainfilelist[i] #获取当前文件名,例1_1.jpg
filestr=filenamestr.split('.')[0] #按照.划分,取前一部分
classnumstr=int(filestr.split('_')[0])#按照_划分,后一部分为该类图片中的序列
picture_num = int(filestr.split('_')[1])
labels[0,i]=classnumstr #前一部分为该图片的标签
train[0,i]=picture_num
trainingMat[i,:]=img2vector('eeeee/chapter9/chapter9/test/data/images/%s' % filenamestr) #构成数组
#保存
d=np.concatenate((labels.T,train.T,trainingMat),axis=1)#连接数组
dataframe=pd.DataFrame(d,columns=['label','num','R_1','G_1','B_2','R_2','G_2','B_2','R_3','G_3','B_3'])
dataframe.to_csv('eeeee/chapter9/chapter9/test/moment.csv',header=None,index=None)#保存文件
4模型构建
#导入数据
import pandas as pd
inputfile = 'eeeee/chapter9/chapter9/test/moment.csv'
data = pd.read_csv(inputfile, header=None)
data = data.as_matrix()
#划分
from sklearn.cross_validation import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data[:,2:]*30,data[:,0],test_size=0.2, random_state=42)
#导入模型相关的函数,建立并且训练模型
from sklearn import svm
model = svm.SVC()
model.fit(x_train, y_train)
#导入输出相关的库,生成混淆矩阵
from sklearn import metrics
cm_train = metrics.confusion_matrix(y_train, model.predict(x_train))
cm_test = metrics.confusion_matrix(y_test, model.predict(x_test))
pd.DataFrame(cm_train, index=range(1,6),columns=range(1,6)).to_excel('cm_train.xls')#模型混淆矩阵
pd.DataFrame(cm_test, index=range(1,6),columns=range(1,6)).to_excel('metrics_test.xls')#水质检测混淆矩阵
print cm_train
print cm_test
#报告
print metrics.classification_report(y_train, model.predict(x_train))
print metrics.classification_report(y_test, model.predict(x_test))
#准确率
from sklearn.metrics import accuracy_score
print accuracy_score(y_train, model.predict(x_train))
print accuracy_score(y_test, model.predict(x_test))
有经验的从事渔业生产的从业者可通过观察水色变化调控水质,以维持养殖水体生态系统中浮游植物、微生物、浮游动物等合理的动态平衡。我们期望通过机器学习的方法将这一过程自动化。通过拍摄照片获取不同水质的图片。这里我们还需要通过专家对数据打 label,这个过程很是费时费力,并且质量奖影响整体模型的效果。使用直接提取的方式对图片进行切割,在此基础上计算 一阶颜色矩,二阶颜色矩,三阶颜色矩 3 个特征。将特征向量输入到 svm 分类器中,这里有个需要注意的细节,征的范围都在 0~1 之间,如果直接输入 SVM,彼此之间区分度会比较小,因此不妨将所有特征统一乘以一个适当的常数 k,经过反复测试最佳的 k=30。