通过机器学习检测叶子颜色并对其健康状态作出判断

描述

前提

就像人类一样,植物也可能染病,比如植物的叶子可能会因真菌或其他病原体而发黄或出现斑点。因此,通过机器学习的力量,可以扫描颜色,然后将其用于训练一个模型,该模型可以检测叶子的颜色并对其健康状态作出判断。

硬件

这个项目主要用Arduino Nano 33 BLE Sense,它之所以被选中主要是它具有一组功能强大的传感器,包括9DoF IMU,APDS-9960(颜色,手势,接近度和亮度),麦克风以及温度/湿度/压力传感器组合。为了使电路板围绕植物的叶子移动并进行测量,将一对步进电机与一对DRV8825驱动器板配合使用。

设置TinyML

对于此项目,列出的针对Arduino Nano 33 BLE Sense on Edge Impulse的内置传感器将不起作用,这意味着将我们必须使用data forwarder而不是serial daemon。

首先,创建一个新项目并将其命名。接下来需要通过Node.js以及NPM来安装EdgeImpulse CLI。然后运行:

npm install -g edge-impulse-cli

如果找不到安装路径,则可能需要将其安装路径添加到PATH环境变量中。接下来,运行

edge-impulse-data-forwarder

并确保其有效,然后按Ctrl + C退出。

机器学习

颜色识别

APDS-9960的工作原理是:通过物体表面所反射的光线波长来读取颜色。为了与传感器通信,最好安装Arduino APDS9960库,该库可以访问一些有用的功能。

在代码中,首先初始化APDS-9960,然后程序进入循环功能,等待直到有颜色数据出现。如果有读数,则使用

APDS.readColor()

以及与表面的接近程度来读取颜色。每个RGB分量都从0-2 ^ 16-1数转换为其值与总和的比率。

扫描仪

扫描叶子的颜色是通过在两个轴上移动装备以使叶子在车载APDS-9960下方经过的各个位置进行的。通过沿顺时针或逆时针方向旋转丝杠来移动每个轴,以使程序段沿任一方向平移。整个系统是在Fusion 360中设计的,下面是这些设计的一些渲染图:

X轴位于Y轴的顶部,从而使顶部程序段在两个轴上移动。Y轴上有一个附加的V轮,以支撑步进电机的重量。零件是使用PLA打印的,填充量约为45%。

收集数据

当系统首次启动时,步进电机是不知道它的初始位置的,因此我们必须进行原点复位,(可通过限位开关实现)。接下来初始化APDS-9960。有一个定义为两个元素的数组的边界框,它们包含一个框的相对角。在这两个位置之间选择一个随机点,然后将步进器运行到该位置,同时读取它们之间的颜色。

处理和发送颜色信息

如前所述,使用

APDS.readColor()

来读取颜色。计算总和后,将计算百分比,然后通过调用

Serial.printf()

的方法通过USB发送百分比。值用逗号分隔,每个读数用换行符分隔。数据转发器程序接收到数据后,会将其作为带有给定标签(健康或不健康)的训练数据发送到Edge Impulse云端。

训练模型

收集完所有训练数据后,就该建立一个可以区分健康叶子和不健康叶子的模型了。我使用了由三轴时间序列,频谱分析模块和Keras模块组成的脉冲。查看以下屏幕截图可以了解我如何从数据中生成这些功能:

测验

为了测试新模型,这次我收集了一些新的测试数据,这是不健康的。该模型的准确性约为63%,并且在通过一些测试功能后,能够在大多数时间正确地对叶子进行分类。

可以通过添加更多训练数据并减慢训练速度来提高此准确性。

代码

#include 《Arduino_APDS9960.h》#include 《AccelStepper.h》#include 《MultiStepper.h》#include “pinDefs.h” int r, g, b, c, p;

float sum;

AccelStepper xStepper(AccelStepper::DRIVER, STEPPER_1_STEP, STEPPER_1_DIR);

AccelStepper yStepper(AccelStepper::DRIVER, STEPPER_2_STEP, STEPPER_2_DIR);

MultiStepper steppers;// a random location will be chosen within the bounding box

const long boundingBox[2][2] = { {0,0}, {40,40}};

void setup(){ Serial.begin(115200); while(!Serial);

if(!APDS.begin()) { Serial.println(“Could not init APDS9960”); while(1); }

pinMode(X_AXIS_HOMING_SW, INPUT_PULLUP); pinMode(Y_AXIS_HOMING_SW, INPUT_PULLUP); //Serial.println(digitalRead(X_AXIS_HOMING_SW) + digitalRead(Y_AXIS_HOMING_SW)); xStepper.setPinsInverted(X_AXIS_DIR); yStepper.setPinsInverted(Y_AXIS_DIR); xStepper.setMaxSpeed(150); yStepper.setMaxSpeed(150); steppers.addStepper(xStepper); steppers.addStepper(yStepper); homeMotors();}

void loop(){ long randomPos[2]; randomPos[0] = random(boundingBox[0][0], boundingBox[1][0]) * STEPS_PER_MM; randomPos[1] = random(boundingBox[0][1], boundingBox[1][1]) * STEPS_PER_MM; steppers.moveTo(randomPos);

while(steppers.run()) { if(!APDS.colorAvailable() || !APDS.proximityAvailable()){} else { APDS.readColor(r, g, b, c); sum = r + g + b; p = APDS.readProximity();

if(!p && c 》 10 && sum 》= 0) { float rr = r / sum, gr = g / sum, br = b / sum; Serial.printf(“%1.3f,%1.3f,%1.3f

”, rr, gr, br); } } }}

void homeMotors(){ // home x //Serial.println(“Now homing x”); while(digitalRead(X_AXIS_HOMING_SW))

xStepper.move(-1);

// home y //Serial.println(“Now homing y”); while(digitalRead(Y_AXIS_HOMING_SW)) yStepper.move(-1); xStepper.setCurrentPosition(0); yStepper.setCurrentPosition(0);}

原理图

机器学习

原文标题:Arduino使用TinyML扫描植物的叶子确定植物的健康

文章出处:【微信公众号:FPGA入门到精通】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分