python数据与挖掘实战学习:实战篇 第九章基于水色图像的水质评价笔记

第九章 基于水色图像的水质评价

9.1 背景与挖掘目标

有经验的从事渔业生产的从业者可通过观察水色变化调控水质,以维持养殖水体生态系统中浮游植物、微生物类、浮游动物等合理的动态平衡。在水质在线监测方面,数字图像处理技术是基于计算机视觉的,以专家经验为基础,对池塘水质进行优劣分级,实现对池塘水色的准确快速判别。

9.2 分析方法与过程

通过拍摄水样,采集得到水样图像,而图像数据的维度过大,不容易分析,需要从中提取水样图像的特征,提取反映图像本质的一些关键指标,以达到自动进行图像识别或分类的目的。因此图像特征提取是图像识别或分类的关键步骤,图像特征提取的效果直接影响到图像识别和分类的好坏。
图像特征主要包括颜色特征、纹理特征、形状特征和空间关系特征等。与几何特征相比,颜色特征更为稳健,对于物体的大小和方向均不敏感,表现出较强的鲁棒性。一般颜色特征是基于像素点的特征,所有属于图像或图像区域的像素都有各自的贡献。对于颜色特征,主要采用颜色处理常用的直方图法和颜色矩方法
(1)颜色直方图
颜色直方图反映的是图像中颜色的组成分布,即出现了哪些颜色以及各种颜色出现的概率。其优点在于它能简单描述一幅图像中颜色的全局分布,即不同色彩在整幅图像中所占的比例,适用于描述那些难以自动分割的图像和不需要考虑物体空间位置的图像。缺点在于它无法描述图像中颜色的局部分布及每种色彩所处的空间位置,即无法描述图像中某一具体的对象或物体。
(2)颜色矩方法
基于颜色矩提取图像特征的数学基础为图像中任何的颜色分布均可以用它的矩来表示。据随机变量的概率分布可以由其各阶矩唯一的表示和描述。一幅图像的色彩分布也可认为是一种概率分布,则图像也可以由其各阶矩来描述。颜色矩包含各个颜色通道的一阶矩、二阶矩和三阶矩,对于一幅RGB颜色空间的图像,具有R、G和B三个颜色通道,则有9个分量
本案例选择采用产生特征维数较小的颜色矩来提取水样图像特征。
分析步骤:
1)从采集到的原始水样图像中进行选择性抽取与实时抽取,形成建模数据和增量数据。
2)对1)形成的两个数据集进行数据预处理,包括图像切割和颜色矩特征提取。
3)利用2)形成的已完成数据预处理的建模数据,由有经验的专家对水样图像根据经验进行分类,构建专家样本。
4)利用3)的专家样本构建分类模型。
5)利用4)的构建好的分类模型进行水质评价。

9.2.1 数据预处理

1.图像切割
避免容器颜色的干扰并且水体位于图像中央,为了提取水色的特征,需要提取水样图像中央具有代表意义的图像,即提取水样图像中央101x101像素的图像。设原始图像I的大小是MxN,则截取宽从第 f i x ( M 2 ) − 50 fix(\frac{M}{2})-50 fix(2M)50个像素点到第 f i x ( M 2 ) + 50 fix(\frac{M}{2})+50 fix(2M)+50个像素点,长从第 f i x ( N 2 ) − 50 fix(\frac{N}{2})-50 fix(2N)50到第 f i x ( N 2 ) + 50 fix(\frac{N}{2})+50 fix(2N)+50个像素点的子图像。
图像切割
2.特征提取
(1)一阶颜色矩
一阶颜色矩采用一阶原点矩,反映图像的整体明暗程度。
E i = 1 N ∑ j = 1 N p i j E_{i}=\frac{1}{N}\sum_{j=1}^{N}p_{ij} Ei=N1j=1Npij
其中,Ei是在第i个颜色通道的一阶颜色矩,对于RGB颜色空间的图像,i=1,2,3,pij是第j个像素的第i个颜色通道的颜色值。
(2)二阶颜色矩
二阶颜色矩采用的是二阶中心距的平方根,反映图像颜色的分布范围。
σ i = 1 N ∑ j = 1 N ( p i j − E i ) 2 σ_{i}=\sqrt{\frac{1}{N}\sum_{j=1}^{N}(p_{ij}-E_{i})^{2}} σi=N1j=1N(pijEi)2
其中,σi是在第i个颜色通道的二阶颜色矩,Ei是在第i个颜色通道的一阶颜色矩。
(3)三阶颜色矩
三阶颜色矩采用的是三阶中心距的立方根,反映图像颜色分布的对称性。
s i = 1 N ∑ j = 1 N ( p i j − E i ) 3 3 s_{i}=\sqrt[3]{\frac{1}{N}\sum_{j=1}^{N}(p_{ij}-E_{i})^{3}} si=3N1j=1N(pijEi)3
其中,si是在第i个颜色通道的三阶颜色矩,Ei是在第i个颜色通道的一阶颜色矩。
提取切割后的图像颜色矩,作为图像的颜色特征。

import numpy as np
import os,re

import pandas as pd
from PIL import Image

# 图像切割及特征提取
path = './test/data/images/'  # 图片所在路径
# 自定义获取图片名称函数
def getImgNames(path=path):
    '''
    获取指定路径中所有图片的名称
    :param path: 指定的路径
    :return: 名称列表
    '''
    filenames = os.listdir(path)
    imgNames = []
    for i in filenames:
        if re.findall('^\d_\d+\.jpg$', i) != []:
            imgNames.append(i)
    return imgNames

# 自定义获取三阶颜色矩函数
def Var(data=None):
    '''
    获取给定像素值矩阵的三阶颜色矩
    :param data: 给定的像素值矩阵
    :return: 对应的三阶颜色矩
    '''
    x = np.mean((data-data.mean())**3)
    return np.sign(x)*abs(x)**(1/3)

# 批量处理图片数据
imgNames = getImgNames(path=path)  # 获取所有图片名称
n = len(imgNames)        # 图片张数
data = np.zeros([n, 9])  # 用来装样本自变量
labels = np.zeros([n])   # 用来放样本标签

for i in range(n):
    img = Image.open(path+imgNames[i])  # 读取图片
    M,N = img.size  # 图片像素的尺寸
    img = img.crop((M/2-50,N/2-50,M/2+50,N/2+50))    # 图片切割
    r,g,b = img.split()     # 将图片分割成三通道
    rd = np.asarray(r)/255  # 转化成数组数据
    gd = np.asarray(g)/255
    bd = np.asarray(b)/255

    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] = imgNames[i][0]  # 样本标签

data = pd.DataFrame(data)
labels = pd.DataFrame(labels)
data = pd.concat([labels, data], axis=1)
data.to_excel('./demo/data/model_data.xlsx',index=False)

图像特征数据

9.2.2 模型构建

对特征提取后的样本进行抽样,抽取80%作为训练样本,剩下的20%作为测试样本,用于水质评价检验。

import pandas as pd

data = pd.read_csv('./demo/data/moment.csv', encoding='gbk')  # 读取数据,指定编码为gbk
data = data.values

from random import shuffle  # 引入随机函数
shuffle(data)  # 随机打乱数据
data_train = data[:int(0.8*len(data)), :]  # 选取前80%作为训练数据
data_test = data[int(0.8*len(data)):, :]  # 选取前80%作为训练数据
print(len(data))
print(len(data_train))
print(len(data_test))

本案例采用支持向量机作为水质评价分类模型,模型输入包括训练样本的输入和建模参数的输入。
参数说明

其中1~9作为输入的特征,其取值都在0 ~ 1之间,如果直接输入SVM模型,彼此之间区分度会比较小,因此将所有特征都统一乘以一个适当的常数k,从而提高区分度和准确率。但k的选取不能过大或过小,可根据测试准确率来选择k的最优值。通过测试,本案例k的最优值为30。

# 导入模型相关函数,建立并训练模型
from sklearn import svm
model = svm.SVC()
model.fit(x_train, y_train)
import pickle
pickle.dump(model, open('./demo/tmp/svm.model', 'wb'))
# 保存模型,可通过下面语句加载模型
# model = pickle.load(open(./demo/tmp/svm.model), 'rb')

# 导入输出相关的库,生成混淆矩阵
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))  # 测试样本的混淆矩阵
print(cm_train)
print(cm_test)

# 保存结果
pd.DataFrame(cm_train, index=range(1, 4), columns=range(1, 4)).to_excel('./demo/tmp/cm_train.xlsx')
pd.DataFrame(cm_test, index=range(1, 5), columns=range(1, 5)).to_excel('./demo/tmp/cm_test.xlsx')

import warnings
warnings.filterwarnings("ignore")
#报告
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)))
  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值