4.2 色块检测#

4.2.1 算法简介#

5

指定某种检测颜色,判断图像中是否有该颜色的色块,返回其坐标和大小,颜色分类标签与颜色识别中的定义相同。


4.2.2 配置参数#

用户可指定待识别色块同时检测的数量,大小和颜色标签,如未指定新的参数,则以默认值运行,参数定义如下:

模式

含义

1

每种颜色最多同时检测1个色块

2

每种颜色最多同时检测2个色块

3

每种颜色最多同时检测3个色块

4

每种颜色最多同时检测4个色块

5

每种颜色最多同时检测5个色块

代码:

  /* 设置每种颜色的最大检测数量 */
  err = sengo.VisionSetMode(VISION_TYPE, 2);  // 最多检测2个色块

4.2.3 返回数据#

主控器获取检测结果时,算法会返回以下数据:

形参

含义

kXValue

色块中心横坐标x

kYValue

色块中心纵坐标y

kWidthValue

色块宽度w

kHeightValue

色块高度h

kLabel

颜色分类标签

代码:

    // 遍历所有检测到的色块
    for (int i = 1; i <= obj_num; ++i) {
      // 获取色块的位置和尺寸信息
      int x = sengo.GetValue(VISION_TYPE, kXValue, i);      // X坐标
      int y = sengo.GetValue(VISION_TYPE, kYValue, i);      // Y坐标
      int w = sengo.GetValue(VISION_TYPE, kWidthValue, i);  // 宽度
      int h = sengo.GetValue(VISION_TYPE, kHeightValue, i); // 高度
      int l = sengo.GetValue(VISION_TYPE, kLabel, i);      // 颜色标签
      
      // 格式化输出检测结果
      Serial.print("  obj");
      Serial.print(i);
      Serial.print(": ");
      Serial.print("x=");
      Serial.print(x);
      Serial.print(",y=");
      Serial.print(y);
      Serial.print(",w=");
      Serial.print(w);
      Serial.print(",h=");
      Serial.print(h);
      Serial.print(",label=");
      Serial.println(blob_classes[l]);  // 输出颜色名称而非数字
    }

4.2.4 代码#

#include <Arduino.h>
#include <Sentry.h>  // 引入Sentry机器视觉传感器库

typedef Sengo2 Sengo;  // 为Sengo2类型创建别名Sengo,简化后续使用

// 通信方式选择(当前启用I2C)
#define SENGO_I2C
// #define SENGO_UART   // UART备用选项(已注释)

#ifdef SENGO_I2C
#include <Wire.h>       // I2C通信所需的库
#endif

#ifdef SENGO_UART
#include <SoftwareSerial.h>
#define TX_PIN 11       // 自定义TX引脚
#define RX_PIN 10       // 自定义RX引脚
SoftwareSerial mySerial(RX_PIN, TX_PIN);  // 创建软串口对象
#endif

#define VISION_TYPE Sengo::kVisionBlob  // 使用Blob检测(色块识别)
Sengo sengo;  // 创建Sengo传感器对象

// Blob检测结果标签的文本描述
const char* blob_classes[] = {
  "UNKNOWN", "BLACK", "WHITE", "RED", "GREEN", "BLUE", "YELLOW"
};

void setup() {
  sentry_err_t err = SENTRY_OK;  // 错误状态变量

  Serial.begin(9600);  // 初始化串口用于调试输出
  Serial.println("Waiting for sengo initialize...");

// 根据选择的通信方式初始化传感器
#ifdef SENGO_I2C
  Wire.begin();  // 初始化I2C总线
  // 持续尝试连接直到成功
  while (SENTRY_OK != sengo.begin(&Wire)) { 
    yield();  // 在等待时允许其他任务运行
  }
#endif

#ifdef SENGO_UART
  mySerial.begin(9600);
  while (SENTRY_OK != sengo.begin(&mySerial)) { 
    yield();
  }
#endif

  Serial.println("Sengo begin Success.");

  // ============== Blob检测参数配置 ==============
  sengo.SetParamNum(VISION_TYPE, 2);  // 设置检测2种颜色的色块
  
  sentry_object_t param = {0};  // 初始化参数结构体
  
  /* 设置色块最小检测尺寸(像素)*/
  param.width = 5;    // 最小宽度5像素
  param.height = 5;   // 最小高度5像素
  
  /* 配置第一个色块(红色)*/
  param.label = Sengo::kColorRed;  // 设置颜色标签为红色
  err = sengo.SetParam(VISION_TYPE, &param, 1);  // 应用到参数1
  
  // 输出配置结果
  Serial.print("sengo.SetParam[");
  Serial.print(blob_classes[param.label]);  // 打印颜色名称
  if (err) {
    Serial.print("] Error: 0x");
  } else {
    Serial.print("] Success: 0x");
  }
  Serial.println(err, HEX);  // 输出16进制状态码

  /* 配置第二个色块(蓝色)*/
  param.label = Sengo::kColorBlue;  // 设置颜色标签为蓝色
  err = sengo.SetParam(VISION_TYPE, &param, 2);  // 应用到参数2
  
  Serial.print("sengo.SetParam[");
  Serial.print(blob_classes[param.label]);
  if (err) {
    Serial.print("] Error: 0x");
  } else {
    Serial.print("] Success: 0x");
  }
  Serial.println(err, HEX);

  /* 设置每种颜色的最大检测数量 */
  err = sengo.VisionSetMode(VISION_TYPE, 2);  // 最多检测2个色块
  Serial.print("sengo.VisionSetMode");
  if (err) {
    Serial.print(" Error: 0x");
  } else {
    Serial.print(" Success: 0x");
  }
  Serial.println(err, HEX);

  // 启动Blob视觉识别
  err = sengo.VisionBegin(VISION_TYPE);
  Serial.print("sengo.VisionBegin(kVisionBlob) ");
  if (err) {
    Serial.print("Error: 0x");
  } else {
    Serial.print("Success: 0x");
  }
  Serial.println(err, HEX);
}

void loop() {
  // 读取检测到的物体总数
  int obj_num = sengo.GetValue(VISION_TYPE, kStatus);
  
  if (obj_num > 0) {  // 如果检测到物体
    Serial.print("Totally ");
    Serial.print(obj_num);
    Serial.println(" objects");
    
    // 遍历所有检测到的色块
    for (int i = 1; i <= obj_num; ++i) {
      // 获取色块的位置和尺寸信息
      int x = sengo.GetValue(VISION_TYPE, kXValue, i);      // X坐标
      int y = sengo.GetValue(VISION_TYPE, kYValue, i);      // Y坐标
      int w = sengo.GetValue(VISION_TYPE, kWidthValue, i);  // 宽度
      int h = sengo.GetValue(VISION_TYPE, kHeightValue, i); // 高度
      int l = sengo.GetValue(VISION_TYPE, kLabel, i);      // 颜色标签
      
      // 格式化输出检测结果
      Serial.print("  obj");
      Serial.print(i);
      Serial.print(": ");
      Serial.print("x=");
      Serial.print(x);
      Serial.print(",y=");
      Serial.print(y);
      Serial.print(",w=");
      Serial.print(w);
      Serial.print(",h=");
      Serial.print(h);
      Serial.print(",label=");
      Serial.println(blob_classes[l]);  // 输出颜色名称而非数字
    }
  }
}

4.2.5 代码结果#

上传代码后,AI视觉模块将会对摄像头拍到的地方进行分析如果有红色块和蓝色块就会进行框选标记,并且再串口监视器中打印色块再屏幕中的位置坐标xy与宽度高度还有颜色标签值,示例中我们将颜色标签值转换成了颜色名称。

6

25

4.2.6 扩展玩法#

智能分拣助手

  • 玩法简介: 让识别模块区分不同颜色和形状的积木(如红色方块、蓝色圆形),并通过控制两个不同的舵机,将不同的积木推入对应的收集盒。

  • 实现: 编程设定识别目标为“红色圆形”和“蓝色方块”。识别到目标A,则舵机A动作;识别到目标B,则舵机B动作。专注于色块的形状颜色双重属性。