第九章 基于水色图像的水质评价
9.1 背景与挖掘目标
有通过水色变化调控水质的需要,但是人工判别存在主观偏差,数字图像处理技术以专家经验为基础,可以对水色准确快速的判别,达到自动评价的功能。上机实验/data/images有众多已经判级的图像数据。
9.2 分析方法与过程
图像特征提取是关键,其主要包括 颜色特征、纹理特征、形状特征、空间关系特征等。书中案例适合针对颜色特征进行提取,颜色特征更为稳健,表现出较强的鲁棒性。颜色直方图是最基本的颜色特征表示方式,即出现了哪些颜色以及各种颜色出现的概率。由于“随机比那里的概率分布可以由其各阶矩唯一地表示和描述”,且颜色直方图产生的特征维数常常大于颜色矩阵的特征维数,所以书中案例选用颜色矩来提取水样图像特征,同时收集专家对水样图像的分类数据,建立样本库。
数据预处理
1、图像切割:统一提取图像中央部分具有代表意义的图像,即提取水样图像中央101×101像素的图像。(宽为第
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
(
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个像素点)。
2、特征提取
(1)一阶颜色矩
E
i
=
1
N
∑
j
=
1
N
p
i
j
E_i=\frac{1}{N}\sum_{j=1}^{N}p_{ij}
Ei=N1∑j=1Npij(一阶原点矩,可以反映图像的整体明暗程度,Ei是第i个颜色的一阶颜色矩,pij是第j个像素的第i个RGB颜色值)。
(2)二阶颜色矩
s
i
=
1
N
∑
j
=
1
N
(
p
i
j
−
E
i
)
2
s_i=\sqrt{\frac{1}{N}\sum_{j=1}^{N}(p_{ij}-E_i)^2}
si=N1∑j=1N(pij−Ei)2(二阶中心矩的平方根,反映图像颜色的分布范围)。
(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=3N1∑j=1N(pij−Ei)3(三阶中心矩的立方根,反映了图像颜色分布的对称性)。
可得数据集示例程序/data/moment.csv
模型构建
1、模型输入
# 设置工作空间
# 把“数据及程序”文件夹拷贝到F盘下,再用setwd设置工作空间
setwd("F:/数据及程序/chapter9/示例程序")
# 把数据分为两部分:训练数据、测试数据
# 读入数据
Data <- read.csv("./data/moment.csv")
# 数据命名
colnames(Data) <- c("class", "id", "R1", "G1", "B1", "R2",
"G2", "B2", "R3", "G3", "B3")
# 数据分割
set.seed(1234) # 设置随机种子
# 定义序列ind,随机抽取1和2,1的个数占80%,2的个数占20%
ind <- sample(2, nrow(Data), replace = TRUE, prob = c(0.8, 0.2))
trainData <- Data[ind == 1, ] # 训练数据
testData <- Data[ind == 2, ] # 测试数据
# 数据存储
write.csv(trainData, "./tmp/trainData.csv", row.names = FALSE)
write.csv(testData, "./tmp/testData.csv", row.names = FALSE)
SVM支持向量机模型代码
# 支持向量机模型构建
# 设置工作空间
# 把“数据及程序”文件夹拷贝到F盘下,再用setwd设置工作空间
setwd("F:/数据及程序/chapter9/示例程序")
# 读取数据
trainData <- read.csv("./data/trainData.csv")
testData <- read.csv("./data/testData.csv")
# 将class列转换为factor类型
trainData <- transform(trainData, class = as.factor(class))
testData <- transform(testData, class = as.factor(class))
# 支持向量机分类模型构建
library(e1071) # 加载e1071包
# 利用svm建立支持向量机分类模型
svm.model <- svm(class ~ ., trainData[, -2])
summary(svm.model)
# 建立混淆矩阵
confusion <- table(trainData$class, predict(svm.model, trainData, type = "class"))
accuracy <- sum(diag(confusion)) * 100 / sum(confusion)
# 保存输出结果
output_trainData <- cbind(trainData, predict(svm.model, trainData, type = "class"))
colnames(output_trainData) <- c("class", "id", "R1", "G1", "B1", "R2", "G2",
"B2", "R3", "G3", "B3", "OUTPUT")
write.csv(output_trainData, "./tmp/output_trainData.csv", row.names = FALSE)
# 保存支持向量机模型
save(svm.model, file = "./tmp/svm.model.RData")
2、结果及分析
模型混淆矩阵
3、水质评价
即输入测试数据
# 模型评价
# 设置工作空间
# 把“数据及程序”文件夹拷贝到F盘下,再用setwd设置工作空间
setwd("F:/数据及程序/chapter9/示例程序")
# 读取数据
testData <- read.csv("./data/testData.csv")
# 读取模型
load("./tmp/svm.model.RData")
# 建立混淆矩阵
confusion <- table(testData$class, predict(svm.model, testData, type = "class"))
accuracy <- sum(diag(confusion)) * 100 / sum(confusion)
# 保存输出结果
output_testData <- cbind(testData, predict(svm.model, testData, type = "class"))
colnames(output_testData) <- c("class", "id", "R1", "G1", "B1", "R2",
"G2", "B2", "R3", "G3", "B3", "OUTPUT")
write.csv(output_testData, "./tmp/output_testData.csv", row.names = FALSE)