基于行空板边缘AI的桌面微环境与植物健康看护站

2026-10-085

一、项目简介

 

桌面盆栽经常出现养死的情况,市面上普通的植物监测设备只能读取土壤湿度、温湿度等环境数据,无法观察植株本身的叶片状态。

本项目使用行空板,融合多类环境传感器 + 本地AI视觉识别,同时采集环境参数与植株叶片状态,双维度综合推理植物健康状况。

当植物出现黄叶、土壤过干/过湿、光照不适等问题时,屏幕显示状态,并语音播报对应的养护建议;同时自动保存植株照片,记录植物生长变化,实现桌面盆栽的智能看护。

 

二、硬件清单

 

1. 行空板 m10

2. DHT11温湿度传感器

3. 土壤湿度传感器

5. 面包板、杜邦线若干

 

三、设计思路

 

1. 环境感知层:通过DHT11读取空气温湿度;土壤湿度传感器读取盆土干湿;光敏传感器采集环境光照强度。

2. AI视觉感知层:行空板摄像头定时拍摄盆栽画面,通过颜色阈值识别叶片发黄枯萎区域,判断植株叶片健康情况。

3. 综合推理逻辑:把传感器环境数据和叶片视觉结果结合,生成养护建议。

4. 输出反馈层:行空板屏幕展示全部实时数据、植物状态;异常时语音播报养护提示;定时保存植株照片,留存生长记录。

 

四、工作原理

 

1. 程序循环读取各类传感器数值;

2. 调用摄像头获取画面,做HSV颜色空间处理,统计画面中黄色像素占比,判断是否存在黄叶;

3. 将土壤湿度、温湿度、光照、叶片状态四个信息综合判断,输出养护提示;

4. 屏幕刷新全部信息,异常触发语音提醒;

5. 每隔一段时间保存一张植株照片,用于后续对比植物生长变化。

 

五、核心代码

导入库与硬件初始化

from unihiker import GUI
import time
import os
from pinpong.board import Board, Pin, DHT11
import cv2
import numpy as np

Board().begin()
gui = GUI()

dht11 = DHT11(Pin(Pin.P16))
soil_pin = Pin(Pin.P27, Pin.ANALOG)

save_dir = "/sdcard/plant_photo"
if not os.path.exists(save_dir):
    os.mkdir(save_dir)

编写黄叶识别核心函数

def detect_yellow_leaf(img):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_yellow = np.array([20, 80, 80])
    upper_yellow = np.array([35, 255, 255])
    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
    yellow_pixel = np.sum(mask > 0)
    total_pixel = img.shape[0] * img.shape[1]
    yellow_ratio = yellow_pixel / total_pixel
    return yellow_ratio > 0.12

设计界面,绘制固定静态UI

TITLE_COLOR = "#00AA00"
TEXT_COLOR = "#ffffff"
WARN_COLOR = "#ff4444"
OK_COLOR = "#00ff00"
LINE_COLOR = "#444444"
gui.draw_text(text="🌿 AI植物看护站", x=20, y=8, font_size=22, color=TITLE_COLOR)
gui.draw_line(x0=5, y0=38, x1=235, y1=38, color=LINE_COLOR, width=2)
photo_count = 0

循环采集传感器数据、获取摄像头图像并自动拍照

while True:
     temp = dht11.temp_c()
     hum = dht11.humidity()
     soil_val = soil_pin.read_analog()
     light_val = gui.get_light()
     if temp is None or hum is None or np.isnan(temp) or np.isnan(hum):
         temp = "---"
         hum = "---"
     frame = gui.get_camera_frame()
     has_yellow = detect_yellow_leaf(frame)
     if photo_count % 10 == 0:
         save_path = f"{save_dir}/plant_{photo_count}.jpg"
         cv2.imwrite(save_path, frame)
     photo_count += 1

状态判断、屏幕刷新与语音预警

    gui.fill_rect(x=0, y=45, w=240, h=275, color="#000000")

    gui.draw_text(text=f"🌡温度: {temp} ℃", x=12, y=55, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"💨空气湿度: {hum} %", x=12, y=85, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"☀光照强度: {light_val}", x=12, y=115, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"🪴土壤湿度: {soil_val}", x=12, y=145, font_size=15, color=TEXT_COLOR)
    gui.draw_line(x0=5, y0=170, x1=235, y1=170, color=LINE_COLOR, width=1)

    tip_text = ""
    tip_color = OK_COLOR
    if has_yellow:
        tip_text = "⚠检测黄叶!少浇水、加强通风"
        tip_color = WARN_COLOR
    elif soil_val < 300:
        tip_text = "💧土壤偏干,请及时浇水"
        tip_color = WARN_COLOR
    elif soil_val > 820:
        tip_text = "⚠土壤过湿,请暂停浇水"
        tip_color = WARN_COLOR
    elif light_val < 200:
        tip_text = "☀光照不足,请移至明亮处"
        tip_color = WARN_COLOR
    else:
        tip_text = "✅植物各项状态良好"
        tip_color = OK_COLOR

    gui.draw_text(text=tip_text, x=10, y=185, font_size=14, color=tip_color)
    gui.draw_text(text=f"照片计数:{photo_count}", x=10, y=220, font_size=12, color="#aaaaaa")

    if "⚠" in tip_text or "💧" in tip_text:
        gui.speak(tip_text)

    time.sleep(3)

完整可移植代码

from unihiker import GUI
import time
import os
from pinpong.board import Board, Pin, DHT11
import cv2
import numpy as np

Board().begin()
gui = GUI()

dht11 = DHT11(Pin(Pin.P16))
soil_pin = Pin(Pin.P27, Pin.ANALOG)

save_dir = "/sdcard/plant_photo"
if not os.path.exists(save_dir):
    os.mkdir(save_dir)

TITLE_COLOR = "#00AA00"
TEXT_COLOR = "#ffffff"
WARN_COLOR = "#ff4444"
OK_COLOR = "#00ff00"
LINE_COLOR = "#444444"

gui.draw_text(text="🌿 AI植物看护站", x=20, y=8, font_size=22, color=TITLE_COLOR)
gui.draw_line(x0=5, y0=38, x1=235, y1=38, color=LINE_COLOR, width=2)


def detect_yellow_leaf(img):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_yellow = np.array([20, 80, 80])
    upper_yellow = np.array([35, 255, 255])
    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
    yellow_pixel = np.sum(mask > 0)
    total_pixel = img.shape[0] * img.shape[1]
    yellow_ratio = yellow_pixel / total_pixel
    return yellow_ratio > 0.12


photo_count = 0

while True:
    temp = dht11.temp_c()
    hum = dht11.humidity()
    soil_val = soil_pin.read_analog()
    light_val = gui.get_light()

    if temp is None or hum is None or np.isnan(temp) or np.isnan(hum):
        temp = "---"
        hum = "---"

    frame = gui.get_camera_frame()
    has_yellow = detect_yellow_leaf(frame)

    if photo_count % 10 == 0:
        save_path = f"{save_dir}/plant_{photo_count}.jpg"
        cv2.imwrite(save_path, frame)
    photo_count += 1

    gui.fill_rect(x=0, y=45, w=240, h=275, color="#000000")

    gui.draw_text(text=f"🌡温度: {temp} ℃", x=12, y=55, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"💨空气湿度: {hum} %", x=12, y=85, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"☀光照强度: {light_val}", x=12, y=115, font_size=15, color=TEXT_COLOR)
    gui.draw_text(text=f"🪴土壤湿度: {soil_val}", x=12, y=145, font_size=15, color=TEXT_COLOR)

    gui.draw_line(x0=5, y0=170, x1=235, y1=170, color=LINE_COLOR, width=1)

    tip_text = ""
    tip_color = OK_COLOR
    if has_yellow:
        tip_text = "⚠检测黄叶!少浇水、加强通风"
        tip_color = WARN_COLOR
    elif soil_val < 300:
        tip_text = "💧土壤偏干,请及时浇水"
        tip_color = WARN_COLOR
    elif soil_val > 820:
        tip_text = "⚠土壤过湿,请暂停浇水"
        tip_color = WARN_COLOR
    elif light_val < 200:
        tip_text = "☀光照不足,请移至明亮处"
        tip_color = WARN_COLOR
    else:
        tip_text = "✅植物各项状态良好"
        tip_color = OK_COLOR

    gui.draw_text(text=tip_text, x=10, y=185, font_size=14, color=tip_color)
    gui.draw_text(text=f"照片计数:{photo_count}", x=10, y=220, font_size=12, color="#aaaaaa")

    if "⚠" in tip_text or "💧" in tip_text:
        gui.speak(tip_text)

    time.sleep(3)

这里的模型大家可以在mind+V2中自己训练需要的检测植物。

 

由于我的行空板有问题,为大家做了模拟处理,但放心,行空板预览效果和下图大差不差。

基于行空板边缘AI的桌面微环境与植物健康看护站_image_1.webp

 

六、调试踩坑记录(这里为大家列出来防止大家重蹈覆辙)

1. 光照干扰问题:强光环境下,叶片反光会造成黄叶误识别。

解决:调整摄像头角度,避开直射阳光,适当调低黄色识别阈值。

2. 土壤湿度读数漂移:土壤传感器容易接触不良。

解决:传感器探针插入土壤深度保持一致,每次上电重新读取校准。

3. 摄像头画面卡顿:循环间隔设置为3秒,不要频繁拍照,避免行空板性能占用过高。

 

八、未来改进方向(为大家提供以下方向参考)

1. 增加微型水泵,实现自动浇水;

2. 训练专用植物识别AI模型,提升叶片病害识别准确度;

3. 实现WiFi上传,在电脑端查看植物生长历史记录;

4. 生成植物延时生长视频。

创作许可协议

本项目采用 CC BY(署名) 进行许可。

评论(0)
- 没有更多了 -