【Intel 黑客松大赛】基于YOLO的杂草-农作物检测分类系统

news2025/2/26 14:49:22

目录

  • 一、赛题简介:计算机视觉挑战——检测并清除杂草
  • 二、基于YOLO的杂草-农作物检测分类
    • 2.1、YOLO简介
    • 2.2、基于YOLO的杂草-农作物检测分类解决方案
  • 三、基于YOLO的杂草-农作物检测分类系统设计
    • 3.1、基于flask框架的demo应用程序后端
    • 3.2、基于Vue框架的demo应用程序前端
  • 四、Intel oneAPI工具包使用
  • 五、后续待完善的部分

科技是人类历史发展最具革命性的关键力量,而科技创新将是赢得未来发展主动权的必然选择。

如今,新一轮科技革命和产业革命正蓬勃兴起。它不再是单一科学领域、技术领域的突破,而是在信息技术、人工智能、新能源、新材料、生物医药等多领域、多赛道竞相迸发。

在这里插入图片描述

前段时间,基于各种巧合,我荣幸参加了英特尔和C站官方联合举办的oneAPI的人工智能黑客松活动,第一次使用英特尔的官方套件来解决计算机视觉领域的问题,本篇博客将分享下本次比赛的解决方案和心得体会。

一、赛题简介:计算机视觉挑战——检测并清除杂草

在这里插入图片描述
本次的赛题是基于计算机视觉的视觉挑战赛题,赛题如下:

杂草是农业经营中不受欢迎的入侵者,它们通过窃取营养、水、土地和其他关键资源来破坏种植,这些入侵者会导致产量下降和资源部署效率低下。一种已知的方法是使用杀虫剂来清除杂草,但杀虫剂会给人类带来健康风险。

参赛者需运用英特尔® oneAPI AI分析工具包构建一个模型。该模型可以自动检测杂草的存在,并在杂草上而不是在作物上喷洒农药,同时使用针对性的修复技术将其从田地中清除,从而最小化杂草对环境的负面影响。

活动主办方提供了数据集资源源码案例详细文档以及公开课视频教程,并且整体的实现流程也描述的十分清楚,可以方便大家快速上手。

二、基于YOLO的杂草-农作物检测分类

2.1、YOLO简介

YOLO是一种基于深度学习的目标检测算法,全称是you only look once,指只需要浏览一次就可以识别出图中的物体的类别和位置。由Joseph Redmon等人于2016年提出。相比于传统的目标检测算法,如RCNNFast RCNNFaster RCNN等,YOLO算法具有更快的检测速度和更高的准确率,因此在目标检测领域得到了广泛的应用。
在这里插入图片描述

因为只需要看一次,YOLO被称为Region-free方法,相比于Region-based方法,YOLO不需要提前找到可能存在目标的Region

也就是说,一个典型的Region-base方法的流程是这样的:先通过计算机图形学(或者深度学习)的方法,对图片进行分析,找出若干个可能存在物体的区域,将这些区域裁剪下来,放入一个图片分类器中,由分类器分类。

YOLO算法的核心思想是将目标检测问题转化为一个回归问题,即通过一个神经网络直接预测目标的类别和位置。具体来说,YOLO算法将输入图像分成S×S个网格,每个网格预测B个边界框和每个边界框的置信度和类别概率。在预测时,YOLO算法将每个边界框的置信度和类别概率相乘,得到每个边界框的最终得分,然后根据得分进行非极大值抑制,得到最终的目标检测结果。

YOLO算法的优点在于它可以在一个神经网络中同时完成目标检测和分类,而且检测速度非常快,可以达到实时检测的要求。此外,YOLO算法还可以处理多个目标的检测,而且对于小目标的检测效果也比较好。

2.2、基于YOLO的杂草-农作物检测分类解决方案

基于YOLO,可以设计一种杂草-农作物的分类解决方案,具体来说,基于YOLO的杂草-农作物分类解决方案包括以下几个步骤:

  1. 数据采集和处理。首先,需要采集大量的杂草和农作物的图像数据,并对这些数据进行处理和标注,以便后续的模型训练和测试。
  2. 模型训练和测试。在进行杂草-农作物的分类时,需要使用YOLO算法来训练分类模型,并对模型进行测试和评估,以确定其准确率和鲁棒性。
  3. 应用和优化。在进行杂草-农作物的分类时,需要将训练好的模型应用到实际场景中,并优化精度和速度。

数据采集部分:赛道主办方已经为我们准备好了杂草-农作物数据集:https://filerepo.idzcn.com/hack2023/Weed_Detection5a431d7.zip

每张图片还包括一个指示类别和标记框的txt,其中第一个数值表示分类,0表示农作物,1表示杂草,如下所示:

在这里插入图片描述
在这里插入图片描述

模型的训练部分:我们参考ravirajsinh45大佬的代码作为baseline,这是一个深度学习模型Darknet,其中包含了多个卷积层、上采样层、shortcut层、route层和yolo层。其中,卷积层用于提取特征,上采样层用于将特征图的尺寸扩大,shortcut层用于实现跨层连接,route层用于将多个层的特征图拼接在一起,yolo层用于目标检测。模型的前向传播过程中,根据不同的层类型,对输入进行相应的处理,最终输出目标检测结果。模型的参数可以通过load_weights函数加载预训练的权重。

将赛题方提供的数据集导入其中,并进行简单配置,进行训练。

应用和优化:在训练成功后,我们将模型使用后端flask框架部署到服务器中,并写一个前端demo部署到客户端,模拟实际应用场景。

三、基于YOLO的杂草-农作物检测分类系统设计

3.1、基于flask框架的demo应用程序后端

后台需要设计两种功能,一种是上传图片,一种是分析图片

  • /upload:用于上传文件,接收 POST 请求,从请求中获取上传的文件,保存到服务器的 upload 目录下,并返回上传成功的信息。
  • /analyze:用于分析上传的图片,接收 POST 请求,调用 detection 函数(detection函数为调用之前训练好的模型)对上传的图片进行分析,将结果保存为 PNG 图像,并将 PNG 图像转换为 Base64 编码,最后将分析结果和 Base64 编码作为 JSON 格式的响应返回给客户端。

if __name__ == '__main__': 语句中,使用 app.run() 启动 Flask 应用程序,监听本地的 3031 端口,等待客户端的请求。

将其设计如下:

@app.route('/upload', methods=['POST'])
def upload():
    # 获取上传的文件
    if 'file' not in request.files:
        return '请选择文件'
    file = request.files['file']

    # 保存文件
    file.save('upload/'+'image.jpeg')

    # 返回成功信息
    return '文件上传成功'

@app.route('/analyze', methods=['POST'])
def analyze():
    res_cls_name, res_cls_conf = detection('upload/image.jpeg')

    # 打开结果PNG图像
    with open('result.png', 'rb') as f:
        image_data = f.read()

    # 将PNG图像转换为Base64编码
    base64_data = base64.b64encode(image_data).decode('utf-8')


    print(res_cls_name)
    print(res_cls_conf)
    response = {
        'message': 'File uploaded successfully',
        'res_cls_name': res_cls_name,
        'res_cls_conf': str(res_cls_conf.item()),
        'base64_data' : base64_data
    }

    return json.dumps(response), 200


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=3031)

3.2、基于Vue框架的demo应用程序前端

构建一个基于 Vue.js 框架的前端页面,使用 Element Plus 组件库中的 el-upload 组件进行图片上传,分析结果会显示在页面的下侧,包括图片的分类名称、可信度和图片本身。其中,分类名称和可信度是通过调用后端 API 获取的,图片则是通过将后端返回的 Base64 编码转换为图片显示出来的,运行效果如下

在这里插入图片描述

运行效果:

运行后:

在这里插入图片描述

部分核心代码如下:

<template>
  <div class="content-main">
    <h1>Crop And Weed Detection</h1>
    <el-upload
      ref="upload"
      class="upload-demo"
      action="/api/upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
      list-type="picture"
      :limit=1
    >
      <template #trigger>
        <el-button type="primary">select file</el-button>
      </template>
      <!-- <el-button type="primary">Click to upload</el-button> -->
      <el-button type="success" :onclick="analyze">Click to Analyze</el-button>
      <template #tip>
        <div class="el-upload__tip">
          Only one image with a size less than 500kb can be uploaded at a time.
        </div>
        <div class="el-upload__tip">
          Click to Analyze and wait for a while.
        </div>
      </template>
    </el-upload>
  </div>
  <div class="content-result">
    <div><h1>判断结果</h1></div>
    <div><p>{{ "该图像为:" + classname }}</p></div>
    <div><p>{{ "可信度为:" + classconf }}</p></div>
    <el-image style="width: 600px" :src="'data:image/png;base64,'+ classurl"/>
  </div>
 
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { analyzeApi } from '../api/analyzeApi';
import { genFileId } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'

const upload = ref<UploadInstance>()

let classname = ref("Waiting Analyze");
let classconf = ref("Waiting Analyze");
let classurl = ref();

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles)
  classname.value = "Waiting Analyze";
  classconf.value = "Waiting Analyze";
  classurl.value = "";

}
const handleExceed: UploadProps['onExceed'] = (files) => {
  upload.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  upload.value!.handleStart(file)
  upload.value!.submit()
  classname.value = "Waiting Analyze";
  classconf.value = "Waiting Analyze";
  classurl.value = "";
}
const handlePreview: UploadProps['onPreview'] = (file) => {
  console.log(file)
}

const analyze = (): number => {
   analyzeApi().then(function (result) {
     console.log(result.data);
     classname.value = result.data.res_cls_name;
     classconf.value = result.data.res_cls_conf;
     classurl.value = result.data.base64_data;
  });
  return 0;
} 
</script>

四、Intel oneAPI工具包使用

在算法实现过程中,我们使用到了oneAPI工具包,
在这里插入图片描述

具体使用如下:

  • Intel Optimization for PyTorch:使用到了英特尔优化过的PyTorch深度学习框架,以最少的代码更改应用 PyTorch 中尚未应用的最新性能优化,并自动混合 float32bfloat16 之间的运算符数据类型精度,以减少计算工作量和模型大小。
  • Interl Nerual Compressor:使用Nerual Compressor自动执行流行的模型压缩技术,例如跨多个深度学习框架的量化、修剪和知识蒸馏。并通过自动精度驱动的调优策略快速收敛量化模型

使用这些工具可以帮助我们更高效地进行深度学习模型的训练和推理,提高模型的性能和效率。同时,这些工具也可以帮助我们减少模型的大小和计算工作量,从而更好地适应不同的硬件和场景需求。

五、后续待完善的部分

系统集成:原型中只实现了模型训练和测试的基本功能,未能实现完整的系统集成。计划通过系统集成技术,将模型集成到完整的杂草检测系统中,实现端到端的杂草检测功能。

模型优化:原型中使用的模型精度和推理速度还有提升空间。计划继续深入学习Interl Optimization for PyTorch,优化模型计算工作量和模型大小,并继续深入学习Interl Nerual Compressor提高在 CPU 或 GPU 上部署的深度学习推理的速度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/679373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt6.2教程——4.QT常用控件QPushButton

一&#xff0c;QPushButton简介 QPushButton是Qt框架中的一种基本控件&#xff0c;它是用户界面中最常见和最常用的控件之一。QPushButton提供了一个可点击的按钮&#xff0c;用户可以通过点击按钮来触发特定的应用程序操作。比如&#xff0c;你可能会在一个对话框中看到"…

Unity编辑器扩展-第七集-应用键/显示提示词

第六集链接&#xff1a;Unity编辑器扩展-第六集-创建窗口/批量填图_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.我们有时候需要多次使用编辑窗口&#xff0c;但是每次一点执行&#xff0c;就关掉了&#xff0c;就很烦&#xff0c;所以我们希望&#xff0c;点击按钮&…

Spring Bean的实例化过程

一、前言 对于写Java的程序员来说&#xff0c;Spring已经成为了目前最流行的第三方开源框架之一&#xff0c;在我们充分享受Spring IOC容器带来的红利的同时&#xff0c;我们也应该考虑一下Spring这个大工厂是如何将一个个的Bean生产出来的&#xff0c;本期我们就一起来讨论一…

2023年6月GESP能力等级认证Python一级真题

2023-06 GESP等级考Python一级真题 题数&#xff1a;27 分数&#xff1a;100 测试时长&#xff1a;90min 一、单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 1. 以下不属于计算机输出设备的有&#xff08; A&#xff09;。&#xff08;2分&#xff09; A…

几个Arcpy代码应用案例

1 案例一 删除特定记录 使用 arcpy 从 ArcGIS 中的图层中删除特定记录。可以使用更新游标&#xff08;UpdateSursor&#xff09;和 SQL 查询来识别和删除所需的记录。以下是如何删除特定图层记录的示例 import arcpy selectedParcelsselectedParcels expres…

分子碰撞频率和自由程------从一个物理小问题解剖自己的数学思维

物理学12-8节中&#xff0c;关于分子平均碰撞的解说如下&#xff1a; &#xff08;一&#xff09;分子碰撞自由程公式 第一个公式中&#xff0c;lamda v / z中&#xff0c;v的单位是m/s, z的单位是A/s, 其中A是常数。那么lamda描述的结果是m/A, 这正是长度单位。 此公式lamda…

利用正弦定理证明两角和差公式

首先用正弦定理&#xff0c;证明sin(AB)sinAcosBcosAsinB。 另外&#xff0c;其它的两角和差公式&#xff0c;都可以用三角函数奇偶性、诱导公式等推导出来&#xff0c;无需再用正弦定理证明一遍。

耗时一个月!手撸博客系统,主打美观实用!

先附上博客链接RoCBlog 关于博客 关于博客 RoCBlog 完成耗时&#xff1a;20天 起初是想搭建自己的博客&#xff0c;看了网上许多开源框架&#xff0c;感觉没啥意思&#xff0c;于是决定自己写一套 纯手撸VueSpringboot 其实是个我一边学vue一边写出来的东西&#xff0c;前期…

团体程序设计天梯赛-练习集L1篇⑩

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;Hello大家好呀&#xff0c;我是陈童学&#xff0c;一个与你一样正在慢慢前行的普通人。 &#x1f3c0;个人主页&#xff1a;陈童学哦CSDN &#x1f4a1;所属专栏&#xff1a;PTA &#x1f381;希望各…

(贪心) 1221. 分割平衡字符串 ——【Leetcode每日一题】

❓ 1221. 分割平衡字符串 难度&#xff1a;简单 平衡字符串 中&#xff0c;L 和 R 字符的数量是相同的。 给你一个平衡字符串 s&#xff0c;请你将它分割成尽可能多的子字符串&#xff0c;并满足&#xff1a; 每个子字符串都是平衡字符串。 返回可以通过分割得到的平衡字符…

【JAVA反序列化】序列化与反序列化Java反射URLDNS链

文章目录 原生序列化与反序列化概述为什么需要序列化和反序列化&#xff1f;应用场景(涉及到将对象转换成二进制&#xff0c;序列化保证了能够成功读取到保存的对象)涉及的协议好处为什么会产生反序列化漏洞&#xff1f;可能反序列化的形式&#xff1f;代码演示 Java反射基础补…

Java try-catch块

Java的try块用于封装可能会抛出异常的代码。它必须在方法内部使用。 如果在try块中的特定语句处发生异常&#xff0c;后续的代码块将不会执行。因此&#xff0c;建议不要在try块中放置不会抛出异常的代码。 Java的try块必须后跟catch块或finally块。 Java try-catch语法 try…

JDBC ResultSet源码解读

通过Debug方式看下源码&#xff1a; 1.Debug程序&#xff0c;找到返回的 ResultSet 的引用 2. 查看ResultSet中的rowData 3. 查看 rows 我们可以看到rows是一个数组&#xff0c;里面存放了我们查询得到的数据&#xff08;我的表中一共7条数据&#xff09;。 4. 查看rows中的元…

【总结】网页状态码——200、302、304、400、404、405、500

200正常 500异常–服务器异常Java代码 细节&#xff1a;null和空&#xff0c;null调用方法会出现空指针异常 400异常----传参相关的异常 get方法长度限制 400异常&#xff0c;加了RequestParam(value “name”) 必须传值 400异常&#xff0c;后端类型是Integer&#xff0c…

c# 基于微信wechat_qrcode opencv插件,网络二维码图片批量识别(一)

一、基本概念 微信开源了其二维码的解码功能&#xff0c;并贡献给 OpenCV 社区。其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中。从 OpenCV 4.5.2 版本开始&#xff0c;就可以直接使用。 该项目 github 地址&#xff1a; https://github.com/opencv/opencv_contr…

中国电子学会2023年05月份青少年软件编程C++等级考试试卷二级真题(含答案)

一、编程题(共5题&#xff0c;共100分) 1. 数字放大 给定一个整数序列以及放大倍数x&#xff0c;将序列中每个整数放大x倍后输出。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 【输入】 包含三行&#xff1a; 第一行为N&#xff0c;表示整数序列的长度(N ≤ 100)&a…

yandex地图js学习

由于百度地图在国外的某些寻路的场景不太完善&#xff0c;所以试用了一下俄罗斯的开源地图。同google地图一样&#xff0c;规划路线需要申请apikey&#xff0c;但无需绑定信用卡&#xff0c;每天的免费调用次数也非常够用。 yandex maps开发文档 申请apikey 只需要创建账号&…

5.5.4 从IPv4到IPv6过渡——双协议栈

5.5.4 从IPv4到IPv6过渡——双协议栈 与软件版本更新不同&#xff0c;IP协议版本的更新不可能在短时间内完成&#xff0c;只能够采用逐步演进的方法&#xff0c;也就是说在很长一段时间内&#xff0c;必须允许两种协议的网络并存&#xff0c;并且能够确保网络能够互联互通&…

C++11语法杂记(更新中)

文章目录 一. delctype二. default三. delete四. 可变参数模板五. emplace系列六. noexcept七. constexpr 一. delctype delctype和auto类似&#xff0c;也可以自动识别类型 举例如下&#xff1a; 与auto不同的是&#xff0c;auto只能用于定义变量类型&#xff0c;而decltyp…

查看ResultSet中的rowData

之前的dml语句都返回值都是int表示有改动的行数 那么Select可是要展示数据的 SELECT查询的结果 通过这个ResultSet遍历 然后通过next方法来一行行读取数据 类似于迭代器(肯定不是迭代器) 里面还包含获得的数据元素 相当于这个既包含元素&#xff0c;还能迭代自己的元素 具体你…