5310浏览
查看: 5310|回复: 2

[项目] [AI人工智能]基于行空板的机器学习物体分类项目(水果识别)

[复制链接]
本帖最后由 IvanDMido 于 2022-11-25 18:42 编辑

基于行空板的物体分类项目(水果识别)

前言
应两位小伙伴要求,将原“智能快递柜机器人”项目中的物体分类功能摘出,作一分享。

项目目标
用人工智能中的物体分类技术,对三种不同的水果(苹果、香蕉、西瓜)进行识别分类。
[AI人工智能]基于行空板的机器学习物体分类项目(水果识别)图3[AI人工智能]基于行空板的机器学习物体分类项目(水果识别)图4


项目器材
行空板,USB摄像头

项目流程
1、采集拍取要识别的三类水果的图片集
2、利用已有的一个基础物体分类模型,结合采集的图片数据集,训练一个包含这三类图片的新模型
3、借助生成的模型,预测某一类水果

项目实践
STEP0硬件连接
将USB摄像头连上行空板。

STEP1摄像头采集图像
一、功能描述
在这个任务中,将采集苹果、香蕉、西瓜、以及白色背景四种类型的图像,并存储到当前路径下“dataset_object_classification”目录中的“01Apple”、“02Banana”、“03Watermelon”、“04Others”四个子目录内,这些目录自动生成。

二、编写程序
  1. '''拍照,采集图像作为数据集;
  2. 运行程序,终端输入1,表示采集"01Apple"数据集,待摄像头的画面启动后,按住按键a进行持续拍照,终端出现“image saved”字样,表示100张图片已采集完成”
  3. 之后重复上述操作,可采集02、03、04类数据集'''
  4. import cv2 # 导入cv库
  5. import os
  6. os.system('mkdir -p dataset_object_classification/01Apple')  # 创建文件夹以保存采集的图像
  7. os.system('mkdir -p dataset_object_classification/02Banana')  # 创建文件夹以保存采集的图像
  8. os.system('mkdir -p dataset_object_classification/03Watermelon')  # 创建文件夹以保存采集的图像
  9. os.system('mkdir -p dataset_object_classification/04Others')  # 创建文件夹以保存采集的图像
  10. number = input("请输入数据集文件夹编号:")
  11. if number == "1":
  12.     location = 'dataset_object_classification/01Apple/'
  13. elif number == "2":
  14.     location = 'dataset_object_classification/02Banana/'
  15. elif number == "3":
  16.     location = 'dataset_object_classification/03Watermelon/'
  17. elif number == "4":
  18.     location = 'dataset_object_classification/04Others/'
  19. print(location)
  20. def get_photo(): # 定义拍照函数(上传参数--图片保存地址)
  21.     cap = cv2.VideoCapture(0) # 创建一个 VideoCapture 对象, 构建视频抓捕器, 0表示需要启动的摄像头
  22.     cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # Set the camera buffer to 1, to decrease the latency. # 设置1帧的缓冲,减少延迟避免卡顿
  23.     cv2.namedWindow('window',cv2.WND_PROP_FULLSCREEN) # Set the windows to be full screen. # 构建一个窗口,名称为window,属性为可以全屏
  24.     cv2.setWindowProperty('window', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) # Set the windows to be full screen. # 设置窗口全屏
  25.     count = 0
  26.    
  27.     while (cap.isOpened()): # 循环读取每一帧
  28.         ret, frame = cap.read() # 从摄像头读取图片 , ret存储布尔值,frame存储图像
  29.         #frame = cv2.flip(frame, 1, dst=None) # 镜像
  30.         cv2.imshow("window", frame) # 窗口显示,显示名为 window
  31.         # 保持画面的持续。
  32.         key = cv2.waitKey(1) # 每帧数据延时1ms,延时不能为 0,否则读取的结果会是静态帧
  33.         if key & 0xFF == ord('b'): # 按b键退出
  34.             break
  35.         elif key & 0xFF == ord('a'): # 通过a键保存图片,并退出。
  36.             if count < 100:  # 100张图片,可自行修改数量
  37.                 global location
  38.                 cv2.imwrite(location+ str(count) + ".jpg", frame) # 将图像保存为图片
  39.                 count = count + 1
  40.                 # print(count)
  41.             else:
  42.                 print("image saved")
  43.     cap.release()  # 释放摄像头
  44.     cv2.destroyAllWindows()  # 关闭所有窗口
  45. get_photo()  # 调用拍照函数,同时传入要保存的图片名称
复制代码
三、运行程序
A:运行程序,在终端输入1(表示将采集的图像存储到“01Apple”目录),随后将摄像头对准苹果的图片,待画面启动后,按住按键a进行持续拍照,终端出现“image saved”字样后,100张图片即采集完成”,再按下按键b退出摄像头画面。这里,我们采集苹果的图片集。
操作过程视频:

B:之后用同样的方式,分别在终端输入2,3,4在“02Banana”、“03Watermelon”、“04Others”目录中拍摄并存储香蕉、西瓜、以及白色背景(用白色背景模拟其他物体)三种图片集。
结果视频:

STEP2用神经网络训练物体模型
一、功能描述
将采集的四组图片数据集用神经网络训练出物体模型。

二、编写程序
  1. '''训练模型,将采集的图片数据集用神经网络训练出物体模型;
  2. 运行程序,待计算机自动训练,时间约1-5分钟不等,完成后,终端会显示“模型保存完成!”字样,并在当前文件目录下会自动生成“object_classification_model.h5”模型文件。'''
  3. # 导入tensorflow深度学习框架
  4. import tensorflow as tf
  5. # 导入keras深度学习库
  6. from tensorflow import keras
  7. # 导入数据处理库
  8. import numpy as np
  9. # 数据预处理
  10. # 将图片处理成预训练模型可以输入的格式
  11. # 定义数据集路径
  12. train_dir = 'dataset_object_classification'
  13. # ImageDataGenerator为Keras的图像生成器,用于预处理图像数据
  14. # mobilenet_v2.preprocess_input为mobilenet_v2的输入图像处理方法,用于将图像处理成适合mobilenet_v2模型的格式
  15. datagen = keras.preprocessing.image.ImageDataGenerator(preprocessing_function=keras.applications.mobilenet_v2.preprocess_input)
  16. # 图像生成器的flow_from_directory方法,负责生成批量数据,供模型训练
  17. train_batches = datagen.flow_from_directory(        
  18.         directory=train_dir,     #   directory:目标文件夹路径,在目标文件夹中,包含多个子文件夹,每个子文件夹都是一类,包含一类图像数据
  19.         shuffle=True,            #     shuffle:是否打乱数据,设置为True,表示打乱每个子文件夹的数据处理顺序,否则按照子文件夹中图片名称的字母顺序处理数据
  20.         target_size=(96,96),   # target_size:目标尺寸,所有图像将被重置为目标尺寸
  21.         batch_size=10)           #  batch_size:数据批次大小,表示一批数据中包含的数据量,预处理时,会按批次处理数据
  22. # train_batches返回的参数包括输入数据和标签数据
  23. # 冻结预训练模型
  24. # 基础模型用的是mobilenet_v2,输入图像尺寸为 224*224
  25. base_model = keras.models.load_model("mobilenet_v2_96.h5",compile=False)  # 导入预训练模型
  26. base_model.trainable = False                                 # 冻结预训练模型
  27. # 这里的模型不含输出层,只有输入层和隐藏层
  28. # 冻结后,权重等参数不再改变
  29. # 冻结后的模型相当于只含输入层的特征提取器
  30. # 创建神经网络
  31. # 实例化一个神经网络模型
  32. model = keras.Sequential(name="object_classification_model")
  33. # 创建输入层
  34. model.add(base_model)                                   # 定义输入层为预训练模型,输入尺寸即为 224*224
  35. # 创建隐藏层
  36. model.add(keras.layers.Dense(100, activation='relu'))   # 创建一层隐藏层,包括100个神经元
  37. # 创建输出层
  38. model.add(keras.layers.Dense(4, activation='softmax'))  # 定义输出层为4分类(种类数量)
  39. # # 查看模型结构
  40. # print("模型结构:")
  41. # model.summary()
  42. # 训练模型
  43. # 设置参数
  44. model.compile(
  45.     optimizer=keras.optimizers.Adam(0.0001),
  46.     loss='categorical_crossentropy',
  47.     metrics=['accuracy']
  48. )
  49. # 训练模型
  50. print("开始训练:")
  51. model.fit(train_batches, epochs=5)  # 设置5轮训练
  52. print("训练完成!")
  53. # 保存模型
  54. model.save("object_classification_model.h5")
  55. print("模型保存完成!")
复制代码
三、运行程序
Tips:如果出现没有库的一些报错,如tensorflow等,可通过pip install的方式自行安装。

A:运行程序,等待行空板自动训练模型(时间约1-5分钟不等,图片越多时间越久)。
训练过程视频

B:训练完成后,会在终端显示“模型保存完成”,并在程序路径下生成对应的模型文件。
[AI人工智能]基于行空板的机器学习物体分类项目(水果识别)图1

STEP3用神经网络预测单张图片
一、功能描述
用“dataset_object_classification/03Watermelon/2.jpg”图片进行预测,检验模型准确率。

二、编写程序
  1. '''用“dataset_object_classification/03Watermelon/2.jpg”图片进行预测,检验模型准确率;
  2. 运行程序,待计算机自动导入模型进行预测,随后会在终端显示该图片在四个类别下的不同分类概率,以及取概率最高的类别作为最终结果
  3. PS:本程序非必须'''
  4. # 导入tensorflow深度学习框架
  5. import tensorflow as tf
  6. # 导入keras深度学习库
  7. from tensorflow import keras
  8. # 导入数据处理库
  9. import numpy as np
  10. # 导入物体分类模型
  11. print("导入模型中...")
  12. model_name = "object_classification_model.h5"
  13. model = tf.keras.models.load_model(model_name)
  14. print("{}模型导入完成".format(model_name))
  15. # 输出预测结果
  16. img = keras.preprocessing.image.load_img("dataset_object_classification/01Apple/2.jpg", target_size=(96, 96))
  17. img2 = keras.preprocessing.image.load_img("dataset_object_classification/02Banana/2.jpg", target_size=(96, 96))
  18. img3 =keras.preprocessing.image.load_img("dataset_object_classification/03Watermelon/2.jpg", target_size=(96, 96))
  19. img4 =keras.preprocessing.image.load_img("dataset_object_classification/04Others/2.jpg", target_size=(96, 96))
  20. # 图像预处理
  21. img_array = keras.preprocessing.image.img_to_array(img3)                  # 将图像数据转换为数组    #  用img3进行预测,可自行修改
  22. img_array = keras.applications.mobilenet_v2.preprocess_input(img_array)  # 将数组处理成适合mobilenet_v2的输入格式
  23. img_array = tf.expand_dims(img_array, 0)                                 # 在图像数组前面增加一维,即将 (224,224,3) 的图像矩阵变成 (1,224,224,3)
  24. # 定义分类结果的名称,按照数据集中的文件夹顺序,神经网络的输出依次为01-04
  25. class_names = ["01Apple","02Banana","03Watermelon","04Others"]
  26. # 预测
  27. print("预测结果为:")
  28. predictions = model.predict(img_array)  # 预测图像(整体概率)
  29. print(predictions)
  30. result = class_names[predictions.argmax()]  # 预测结果(概率最高者)
  31. print(result)
复制代码
三、运行程序
A:运行程序,等待行空板加载模型并进行预测
预测过程视频

结果图示
[AI人工智能]基于行空板的机器学习物体分类项目(水果识别)图2

STEP4用神经网络预测视频流
一、功能描述
实时显示图像的预测结果。

二、编写程序
  1. '''在Pyboard屏幕上显示视频流画面并实时预测结果'''
  2. # 导入tensorflow深度学习框架
  3. import tensorflow as tf
  4. # 导入keras深度学习库
  5. from tensorflow import keras
  6. # 导入OpenCV计算机视觉库
  7. import cv2
  8. # 导入数据处理库
  9. import numpy as np
  10. # 导入物体分类模型
  11. print("导入模型中...")
  12. model_name = "object_classification_model.h5"
  13. model = tf.keras.models.load_model(model_name)
  14. print("{}模型导入完成".format(model_name))
  15. # 图像预处理
  16. def preprocess_img(frame):
  17.     img = tf.image.resize(frame, (96, 96))                 # 重置尺寸
  18.     img_array = keras.preprocessing.image.img_to_array(img)  # 将图像转为数组
  19.     img_array = tf.expand_dims(img_array, 0)                 # 将图像数组增加一维,匹配模型输入
  20.     img_array = img_array/255.                               # 归一化
  21.     return img_array                                         # 返回预处理后的图像数据
  22. # 绘制分类结果
  23. def add_data(frame,predictions):
  24.     res = frame                                        # 获取一帧图像
  25.     box_startpoint = (30,10)                           # 定义坐标
  26.     class_names = ["01Apple","02Banana","03Watermelon","04Others"]    # 定义分类结果
  27.    
  28.     # # 在屏幕左上方,绘制各个分类结果的置信度直方图
  29.     # for idx,pred in enumerate(predictions.numpy()[0]):
  30.         # # 绘制文字
  31.         # res = cv2.putText(res,  
  32.         #     str(class_names[idx]),
  33.         #     (box_startpoint[0]-20, box_startpoint[1]+idx*40+10), #+20
  34.         #     cv2.FONT_HERSHEY_SIMPLEX, 0.5,
  35.         #     (0, 0, 255),
  36.         #     2,
  37.         #     cv2.LINE_4)
  38.         # # 绘制直方图
  39.         # res = cv2.rectangle(res,
  40.         #     (box_startpoint[0]+70,box_startpoint[1]+idx*40),
  41.         #     (int(box_startpoint[0]+100*np.around(predictions.numpy(),2)[0][idx])+70,box_startpoint[1]+idx*40+15),
  42.         #     (0,0,255),
  43.         #     -1)
  44.     # 绘制直方图
  45.     res = cv2.rectangle(res,
  46.         (0,0),
  47.         (160,35),
  48.         (255,255,255),
  49.         -1)   
  50.     # 在屏幕下方,绘制预测结果"predicted result :"+
  51.     res = cv2.putText(res,str(class_names[predictions.numpy().argmax()]),
  52.         (0,25), # coor
  53.         cv2.FONT_HERSHEY_SIMPLEX, 1,
  54.         (255, 0, 0),
  55.         2,
  56.         cv2.LINE_4)
  57.     res = str(class_names[predictions.numpy().argmax()])
  58.     return res
  59.    
  60. # 初始化屏幕
  61. window_name = 'frame'
  62. cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
  63. cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
  64. # whole_frame = np.zeros((480,800,3), dtype="uint8")
  65. # 初始化摄像头
  66. while True:
  67.     cap = cv2.VideoCapture(0)            # 获取摄像头图像
  68.     cap.set(cv2.CAP_PROP_FRAME_WIDTH, 240)
  69.     cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)
  70.     cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)  # 设置内部缓冲存储器中的帧数量
  71.     if cap is not None:                  # 如果没有连接摄像头,就等待
  72.         break
  73. while True:
  74.     # 逐帧捕获摄像头的图像
  75.     ret, frame = cap.read() # ret为True或False,表示有没有读到图像,frame表示当前截取一帧的图像
  76.     img_array = preprocess_img(frame)         # 对一帧图像做预处理
  77.     predictions = model.predict(img_array)    # 模型预测(整体概率)
  78.     predictions = tf.nn.softmax(predictions)  # 输出预测结果
  79.     new_frame = add_data(frame,predictions)   # 对每一帧图像绘制分类结果
  80.     # frame=cv2ImgAddText(frame,new_frame, (10, 30),(0, 255, 0), 30)
  81.     print(new_frame)
  82.     # 显示图像   
  83.     cv2.imshow('frame',frame)
  84.    
  85.     # 按下熊猫键盘“A”键,退出程序
  86.     if cv2.waitKey(1) & 0xFF == ord('b'):
  87.         break
  88. #清空显示
  89. cap.release()
  90. cv2.destroyAllWindows()
复制代码
三、运行程序
过程视频


小结
由于时间有限,对于程序的解释较为简单,但关于物体分类的总体操作思路不变,即“采集图像--训练模型--预测图像”,这也是很多人工智能项目普遍的操作流程。最后,希望本文能给你带来一些收获和启发,如果对相关的技术感兴趣,也欢迎作进一步研究并将你的成果开源出来。(PS:最后的最后,也感谢一下在原“智能快递柜机器人”项目中一起研讨并提供help的小伙伴。)















基于行空板的物体分类项目(水果识别).zip

2.73 MB, 下载次数: 289

Forgotten  版主

发表于 2022-11-25 14:36:24

回复

使用道具 举报

曾剑波  初级技匠

发表于 2023-3-2 23:36:53

来学习一下!看看跟二哈有什么大区别
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail