使用OpenCV-python对植物图片进行分类

news/2024/11/28 4:33:02/

文章目录

  • 图片分类的思路和需要加载的库函数说明
  • 核心代码分析
    • 数据预处理:文件处理和命名匹配
    • 数据预处理:特征提取和标签提取
    • 学习模型:数据划分和模型训练
    • 预测输出:利用训练好的模型进行图片分类
  • 完整代码附录和运行结果

图片分类的思路和需要加载的库函数说明

图片分类的基本思路如下

  1. 首先需要有一个标注好图片里面花朵名称的数据集,例如命名好的rose.png
  2. 特征提取,即提取图片中的重要特征(能区别于其他图片的特征),并把重要特征加工成可以训练的数据,因为每种花的颜色分布不同,这里的思路是计算图片的彩色直方图信息,作为图片的特征。
  3. 标签提取,即把图片标注加工成数值信息,这里的思路是把图片的字符串名字转换成唯一的数字序列。
  4. 挑选一个分类器模型,例如随机森林分类器,然后划分训练集和测试集进行训练,得到学习器,即分类模型。
  5. 用这个训练好的模型,对图片进行分离,即利用模型预测。

需要使用的库函数和功能说明

# 标签处理
from sklearn.preprocessing import LabelEncoder# 随机森林分类器模型
from sklearn.ensemble import RandomForestClassifier# 对数据集进行有效划分的方法,划分成训练集和测试集
# from sklearn.cross_validation import train_test_split
# 在python新版本中,train_test_split被移动到model_selection中
from sklearn.model_selection import train_test_split# 分类器性能评估报告
from sklearn.metrics import classification_report# 基本矩阵运算库
import numpy as np# 文件操作模块,主要是进行文件搜索和通配符操作
import glob# opencv函数库
import cv2 

核心代码分析

数据预处理:文件处理和命名匹配

glob函数使用参考:python glob model - 漩涡鸣人 - 博客园

# 加载所有的图片和蒙版
imagePath = "dataset/images"
maskPath  = "dataset/masks"
# 利用sorted函数实现名字的一一对应,对每个图片进行蒙版的加载
imagePaths = sorted(glob.glob(imagePath + "/*.png"))
maskPaths  = sorted(glob.glob(maskPath + "/*.png"))

数据预处理:特征提取和标签提取

# 计算直方图,返回的是均一化之后的彩色直方图数据
features = desc.describe(image,mask)
# 构造测试数据集的特征信息集合
data.append(features)
# 注意图片的命名格式为"image_crocus_0001.png",我们需要提取的"crocus"是倒数第二个
target.append(imagePath.split("_")[-2])
# 初始化一个打标签的对象
le = LabelEncoder()
# 对target进行数字化标签index(因为字符串这种特征是不能直接拿来训练的,需要转换成唯一的数值)
target = le.fit_transform(target)

标签处理:unique()fit_transform()的用法

target = ["happy","birthday","happy","wedding","happy","ending"]

unique对这串字符串进行去重:

targetNames = np.unique(target)
print(targetNames)
['birthday' 'ending' 'happy' 'wedding']

fit_transform最后算出每个字符串label对应的标签序号,此时brithdayendinghappywedding按照字母表顺序,分别对应0~3。

le = LabelEncoder()
target = le.fit_transform(target)
print(target)
[2 0 2 3 2 1]

学习模型:数据划分和模型训练

# 对数据进行训练集和测试集的划分,划分比例是7:3
(trainData,testData,trainTarget,testTarget) = \train_test_split(data,target,test_size=0.3,random_state=42)# 初始化一个随机森林分类器模型
model = RandomForestClassifier(n_estimators=25,random_state=84)
# 用训练集训练这个分类器模型
model.fit(trainData,trainTarget)# 用测试集合评估分类器性能,并打印出来
print(classification_report(testTarget, model.predict(testData),\target_names=targetNames))

预测输出:利用训练好的模型进行图片分类

# 生成图片的特征(彩色直方图)
features = desc.describe(image,mask)
# 预测输出,从数字index转换成对应的字符串标签
flower = le.inverse_transform(model.predict([features]))[0]

完整代码附录和运行结果

from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
# from sklearn.cross_validation import train_test_split
# 在python新版本中,train_test_split被移动到model_selection中
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import numpy as np
import glob
import cv2 # 定义一个RGB直方图的类和方法
class RGBHistogram:def __init__(self,bins):self.bins = bins# 定义对图片特征的描述为彩色直方图def describe(self,image,mask=None):# 计算三个通道的直方图hist=cv2.calcHist([image],[0,1,2],mask,self.bins,[0,256,0,256,0,256])# 直方图均一化,减少图片亮度和对比度信息的干扰cv2.normalize(hist,hist)return hist.flatten()# 加载所有的图片和蒙版
imagePath = "dataset/images"
maskPath  = "dataset/masks"
# 利用sorted函数实现名字的一一对应,对每个图片进行蒙版的加载
imagePaths = sorted(glob.glob(imagePath + "/*.png"))
maskPaths  = sorted(glob.glob(maskPath + "/*.png"))# data保存彩色直方图信息,保存测试数据集的feature
data = []
# target保存图片名称的字符串信息,相当于测试数据的label
target = []# 实例化一个计算RGB直方图的对象,类似于一个操作句柄
desc = RGBHistogram([8,8,8])# 数据预处理,把照片信息转换成可训练的数据
for (imagePath,maskPath) in zip(imagePaths,maskPaths):# 读取照片和蒙版image = cv2.imread(imagePath)mask  = cv2.imread(maskPath)# 虽然蒙版已经是黑白的了,但要确保图片格式也是灰度表示的mask  = cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)# 计算直方图,返回的是均一化之后的彩色直方图数据features = desc.describe(image,mask)# 构造测试数据集的特征信息集合data.append(features)# 注意图片的命名格式为"image_crocus_0001.png",我们需要提取的"crocus"是倒数第二个target.append(imagePath.split("_")[-2])# 这时候的target里面保存的是字符串,并不是具体的数值,还不能进行学习
# 对名字进行去重处理,注意target本身没变,targetNames是去重之后的标签名
targetNames = np.unique(target)
# 初始化一个打标签的对象
le = LabelEncoder()
# 对target进行数字化标签index(因为字符串这种特征是不能直接拿来训练的,需要转换成唯一的数值)
target = le.fit_transform(target)######################### 至此,数据预处理已经全部完成 ############################### 对数据进行训练集和测试集的划分,划分比例是7:3
(trainData,testData,trainTarget,testTarget) = \train_test_split(data,target,test_size=0.3,random_state=42)# 初始化一个随机森林分类器模型
model = RandomForestClassifier(n_estimators=25,random_state=84)
# 用训练集训练这个分类器模型
model.fit(trainData,trainTarget)# 用测试集合评估分类器性能,并打印出来
print(classification_report(testTarget, model.predict(testData),\target_names=targetNames))######################### 至此,训练已经全部完成 ############################### 随机抽取10个案例进行测试
for i in np.random.choice(np.arange(0,len(imagePaths)),10):imagePath = imagePaths[i]maskPath  = maskPaths[i]image = cv2.imread(imagePath)mask  = cv2.imread(maskPath)mask  = cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)# 生成特征(彩色直方图)features = desc.describe(image,mask)# 预测输出,从数字index转换成对应的字符串标签flower = le.inverse_transform(model.predict([features]))[0]print(imagePath)print("According to RFT, this flower is {}".format(flower))cv2.imshow("predicted to be {}".format(flower.upper()),image)cv2.waitKey(0)cv2.destroyAllWindows()
cv2.destroyAllWindows()

学习器的性能如下

 				precision    recall  f1-score   supportcrocus       0.92      1.00      0.96        12daisy       0.88      0.93      0.90        15pansy       1.00      0.85      0.92        20sunflower       0.96      1.00      0.98        24accuracy                           0.94        71macro avg       0.94      0.95      0.94        71
weighted avg       0.95      0.94      0.94        71

预测输出效果:

在这里插入图片描述


http://www.ppmy.cn/news/715598.html

相关文章

如何通过图片识别植物?识别植物软件有哪些?

想必大家都有这样的经历,当我们在外面散步时,看到一种美丽的植物,但是却不知道它的名字。现在,有一种神奇的技术可以帮助我们解决这个问题,那就是通过图片识别植物。现在你只需要拍下这种植物的照片,然后上…

认识植物 —— 花

说句扫兴的话,花朵是植物的性器官,用于授粉,结籽。 虞美人是一种词牌名,也是一种花卉;玫瑰和月季都是蔷薇科植物; 1. 花瓣的数量 五个花瓣(报春花(左),杏花…

React将数据转化成树形结构

1、React将数据转化成树形结构 // 初始数据 let result [{ parentId: null, id: 1, name: "书籍", count: 100 },{ parentId: 1, id: 2, name: "西游记", count: 50 },{ parentId: 1, id: 3, name: "红楼梦", count: 10 },{ parentId: 1, id: 4…

Ubuntu 20.04 LTS SPEC CPU 2017 cpu2017-1_0_5.iso 安装、测试 笔记

环境 $ gcc -v Using built-in specs. COLLECT_GCCgcc COLLECT_LTO_WRAPPER/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMESnvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pk…

执行sqlplus / as sysdba报错ORA-01031: insufficient privileges

背景: 从线上环境copy OracleHome到线下做测试环境,修改完pfile后执行sqlplus / as sysdba报错 [erparcxxx.com ~]$ sqlplus / as sysdbaSQL*Plus: Release 11.2.0.4.0 Production on Mon Feb 14 16:26:00 2022Copyright (c) 1982, 2013, Oracle. All r…

记一次数组越界的BUG

(这是19年遇到的一个问题,现在回来看看,有了不一样的收获~) 问题:Android下执行reboot recovery后, 黑屏无输出,重新上电也还是黑屏 具体现象:执行reboot recovery后,进…

android porting usb audio,android - 在android中启动时找不到audio-hal-2-0 - 堆栈内存溢出...

我正在为Resenas Rcar-H3开发板构建android 9。 构建过程成功。 但是,在将映像刷新到电路板上之后,启动过程将无法正常进行。 audioserver由初始化进程重新启动,并通知一些错误,如下所示: [ 737.947862] init: Service audioserver (pid 2734) exited with status 1 [ 737…

Nginx——Nginx反向代理

目录 1、Nginx反向代理概述 1.1、Nginx正向代理 1.2、Nginx反向代理 1.2.1、Nginx反向代理的配置语法 1.2.2、Nginx反向代理实战 2、Nginx的安全控制 2.1、如何使用SSL对流量进行加密 2.1.1、nginx添加SSL的支持 2.1.2、Nginx的SSL相关指令 2.1.3、生成证书 2.1.4、…