_SKU_SEN0314__小MU视觉传感器 - jimaobian/DFRobotWikiCn GitHub Wiki
打开智能时代,从视觉开始。一款内置深度学习引擎的图像识别传感器来了,拥有和四枚一元硬币大小相当的小巧体积,采用30W广角镜头,含有多种视觉算法,能够实现机器人自主智能(比如寻球投篮,沿着箭头指示走完规定路线等),让机器人面对环境中的随机事件时能自主触发适合的行为。 传感器可以识别多种目标物体,例如颜色检测,球体检测,人体检测,卡片识别等,检测结果可通过UART或I2C方式进行输出。内置算法均在本地处理,无需联网就可进行图像识别,而且通过板载USB串口即可实现传感器模块的参数设定和固件更新,支持UART,I2C,WIFI通讯方式。适用于Arduino及micro:bit嵌入式平台,提供图形化编程软件Mind+的支持,无论你是哪个平台的创客爱好者,我们都能让你体验到它的能力。 通过小MU视觉传感器可完成一些智能化应用,比如智能打印扫描小车、智能无人车、寻球投篮机器人等,可广泛应用于智能玩具、人工智能教具、创客产品等领域。 图像识别是对光源、色彩、背景、物体移动速度等因素十分敏感的技术,使用环境的差异会对图像检测结果将产生不同的影响,为了获取较好的识别结果: (1)避免在过暗、过亮、强逆光的环境下使用,比如昏暗的房间,具有强烈光亮差别的窗边等; (2)避免让灯光或强烈阳光直射目标物体,避免造成物体反光; (3)避免在彩色灯光或可变换的灯光下使用,稳定均匀的白色是最好的光源; (4)避免正对光源使用; (5)颜色敏感型算法不要在有近似颜色的背景下使用,比如绿色网球不要在绿色地毯上使用; (6)避免在有类似目标物体的环境下使用,避免误报,比如球体检测旁边有一个橙子;
注意:本传感器支持Mind+图形化编程,详细教程见本页面后续章节。点击直达 |
小MU视觉传感器具有如下优点:
- 能够做出丰富多样的视觉课程应用
- 智能打印扫描小车
- 智能无人车
- 寻球投篮机器人等
- 体积小巧,功耗极低
- 易于使用:支持UART,I2C,WIFI通讯方式,适用于Arduino及micro:bit嵌入式平台
- 应用广泛
- 安全可靠,无需网络:所有视觉识别算法都于本地进行处理,无须联网,不受网络状况所限制,无需担忧隐私泄露
- 处理器:双核,240MHz
- 摄像头:Omnivision ov7725
- 摄像头分辨率:640x480
- 视场角:90°(对角线)
- 辅助灯:2个LED辅助灯
- 尺寸:3.2cm*3.2cm*1.2cm
- 数据输出接口:UART/I2C
- 供电电压:5V
- 可识别目标
- 人(依据上半身轮廓)
- 球(乒乓球与网球)
- 定制的卡片20张(3组-----5张交通卡片、5张形状、10张数字)
- 颜色(视野内指定位置输出指定颜色,指定颜色输出在视野内的位置)
- 开发中功能
- wifi图传(模块做为AP)
- 运动轨迹检测(检测手部上下左右运动轨迹,非手势检测)
- 人脸的记忆与识别
- 二维码识别
| {| | | |
|
| | | | | |
编号 |
G |
V |
TX |
RX |
SCL |
SDA |
|}
无分类标签
分类标签 | 目标物体 |
1 | 2 |
橙色乒乓球 | 绿色网球 |
分类标签 | 目标物体 | 分类标签 | 目标物体 |
1 | 黑色(深灰色) | 2 | 白色(浅灰色) |
3 | 红色 | 4 | 黄色(橙色) |
5 | 绿色 | 6 | 青色(蓝绿色) |
7 | 蓝色 | 8 | 紫色 |
0 | 未知 | / | / |
分类标签 | 目标物体 | 分类标签 | 目标物体 |
1 | 对号图案 | 2 | 叉号图案 |
3 | 圆形图案 | 4 | 方形图案 |
5 | 三角形图案 | 0 | 无效 |
分类标签 | 目标物体 | 分类标签 | 目标物体 |
1 | 前进 | 2 | 左转 |
3 | 右转 | 4 | 掉头 |
5 | 停止 | 0 | 无效 |
分类标签 | 目标物体 | 分类标签 | 目标物体 |
1 | 数字1 | 2 | 数字2 |
3 | 数字3 | 4 | 数字4 |
5 | 数字5 | 6 | 数字6 |
7 | 数字7 | 8 | 数字8 |
9 | 数字9 | 0 | 数字0 |
传感器有UART和I2C两种输出模式,不同模式下需通过拨码开关进行调整,开关下方标有Output的为输出模式拨码开关 传感器有4种地址可选择,地址范围为0x60-0x63,该范围内的地址在两种模式下通用,不同地址需通过拨码开关进行调整,开关下方标有Address的为地址拨码开关
采用 2 位拨码开关来选择信号输出类型,定义见下表:
拨码1 | wifi开关 | 拨码2 | 信号输出类型 |
0 | 禁止使用Wifi功能* | 0 | UART通讯方式 |
1 | 允许使用Wifi功能* | 1 | I2C通讯方式 |
注1:*所示功能,当前版本尚不具备 注2:向上拨动为1,向下拨动为0
采用 2 位拨码开关来选择信号输出类型,定义见下表:
拨码1 | 拨码2 | 设备地址 |
0 | 0 | 0x60 |
0 | 1 | 0x61 |
1 | 0 | 0x62 |
1 | 1 | 0x63 |
注1:UART模式下可使用0x00作为广播地址 注2:向上拨动为1,向下拨动为0
START | LEN | ADDR | CMD | DATA | CHK | END |
START:起始码,始终为0xFF LEN:长度,从起始码到结束码所有的字节数 ADDR:设备地址,范围0x60~0x63,初次使用默认地址为0x60,特别的:0x00为广播地址,所有设备都会接收 CMD:指令码/应答码 DATA:数据,详见各指令码介绍 CHK:校验码,从START至DATA所有字节累加求和 例:FF 08 60 01 20 03 8B ED 其中8B为校验码,0xFF+0x08+0x60+0x01+0x20+0x03 = 0x8B END:结束码,始终为0xED
应答正确 | 应答错误 | 未知错误 | 超时错误 | 校验错误 | 长度错误 | 指令错误 | 地址错误 | 参数错误 | 写入错误 |
0xE0 | 0xE1 | 0xE2 | 0xE3 | 0xE4 | 0xE5 | 0xE6 | 0xE7 | 0xE8 | 0xE9 |
写寄存器 | 读寄存器 | 数据报文 | 请求报文 |
0x01 | 0x02 | 0x11 | 0x12 |
以上均是发送指令的代码,操作成功或操作失败会返回相对应的应答码
(1) 设置 Address 地址 (2) 设置 Output 模式 (3) 版本校验 (4) 配置硬件参数 (5) 配置算法参数 (6) 读取检测结果
通过拨码开关来设定 MU 的设备地址,详见6.2地址选择
通过拨码开关来设定通讯方式,详见6.1输出模式选择 注:需要在设定完 Address 和 Output 之后再上电,已经上电的则需要按 reset 重启
查询 PROTOCOL_VER 和 FIRMWARE_VER 寄存器来判断固件是否与手册一致,不一致则可能导致寄存器功能不同或算法版本区别
根据实际应用场景和需求寄存器相应的寄存器参数,主要涉及 CAMERA_CONF1,LED1,LED2 寄存器。
每个算法 VISION_ID 都具有相应的寄存器,在设置算法参数前需要先设置 VISION_ID(即选取识别对象类别)
可通过UART或I2C读取检测结果
(1)id:算法类型编号 (2)num:目标物体数量 (2)x:水平中心坐标 (3)y:垂直中心坐标 (4)width:物体边缘宽度 (5)height:物体边缘高度 (6)label:分类标签编号,部分算法适用,详见分类标签
-
硬件
- UNO x1
- 小MU视觉传感器 x1
- 连接线 x1
-
软件
- Arduino IDE 点击下载Arduino IDE
点击下载库文件库文件和示例
/*
****************************************************
* @brief MU Vision Sensor
* @copyright [DFRobot](http://www.dfrobot.com), 2016
* @copyright GNU Lesser General Public License
* @author [WWZ]([email protected])
* @version V1.0
* @date 2019-03-11
* GNU Lesser General Public License.
* All above must be included in any redistribution
* ***************************************************
*/
#include <Wire.h>
#include "MuVisionSensor.h"
#include <SoftwareSerial.h>
//#define I2C_MODE
#define SERIAL_MODE
#define MU_ADDRESS 0x60
// change vision type here, VISION_TYPE:VISION_COLOR_DETECT
// VISION_COLOR_RECOGNITION
// VISION_BALL_DETECT
// VISION_BODY_DETECT
// VISION_SHAPE_CARD_DETECT
// VISION_TRAFFIC_CARD_DETECT
// VISION_NUM_CARD_DETECT
//#define VISION_TYPE VISION_BALL_DETECT
//#define VISION_TYPE VISION_BODY_DETECT
//#define VISION_TYPE VISION_SHAPE_CARD_DETECT
#define VISION_TYPE VISION_TRAFFIC_CARD_DETECT
//#define VISION_TYPE VISION_NUM_CARD_DETECT
//#define VISION_TYPE VISION_COLOR_DETECT
//#define VISION_TYPE VISION_COLOR_RECOGNITION
#ifdef SERIAL_MODE
#define TX_PIN 2
#define RX_PIN 3
SoftwareSerial mySerial(RX_PIN, TX_PIN);
#endif
MuVisionSensor Mu(MU_ADDRESS);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(500);
#ifdef I2C_MODE
Wire.begin();
Mu.begin(&Wire, kI2CMode);
#elif defined SERIAL_MODE
mySerial.begin(9600);
Mu.begin(&mySerial, kSerialMode);
#endif
Mu.VisionBegin(VISION_TYPE);
if (VISION_TYPE == VISION_COLOR_DETECT
|| VISION_TYPE == VISION_COLOR_RECOGNITION) {
Mu.CameraSetAwb(kLockWhiteBalance); // lock AWB
delay(1000); // waiting for AWB lock.
if (VISION_TYPE == VISION_COLOR_DETECT
|| VISION_TYPE == VISION_COLOR_RECOGNITION) {
Mu.write(VISION_TYPE, kXValue, 50);
Mu.write(VISION_TYPE, kYValue, 50);
Mu.write(VISION_TYPE, kWidthValue, 5);
Mu.write(VISION_TYPE, kHeightValue, 5);
}
}
}
void loop() {
// put your main code here, to run repeatedly:
long time_start = millis();
// read result
if (Mu.GetValue(VISION_TYPE,kStatus)) {
Serial.println("vision detected:");
switch (VISION_TYPE) {
case VISION_BALL_DETECT:
case VISION_BODY_DETECT:
case VISION_SHAPE_CARD_DETECT:
case VISION_TRAFFIC_CARD_DETECT:
case VISION_NUM_CARD_DETECT:
case VISION_COLOR_DETECT:
Serial.print("x = ");
Serial.println(Mu.GetValue(VISION_TYPE, kXValue));
Serial.print("y = ");
Serial.println(Mu.GetValue(VISION_TYPE, kYValue));
Serial.print("width = ");
Serial.println(Mu.GetValue(VISION_TYPE, kWidthValue));
Serial.print("height = ");
Serial.println(Mu.GetValue(VISION_TYPE, kHeightValue));
if (VISION_TYPE != VISION_COLOR_DETECT) {
Serial.print("label = ");
Serial.println(Mu.GetValue(VISION_TYPE, kLabel));
} else {
Serial.print("color = ");
Serial.println(Mu.GetValue(VISION_TYPE, kLabel));
}
break;
case VISION_COLOR_RECOGNITION:
Serial.print("r = ");
Serial.println(Mu.GetValue(VISION_TYPE, kRValue));
Serial.print("g = ");
Serial.println(Mu.GetValue(VISION_TYPE, kGValue));
Serial.print("b = ");
Serial.println(Mu.GetValue(VISION_TYPE, kBValue));
Serial.print("color = ");
Serial.println(Mu.GetValue(VISION_TYPE, kLabel));
break;
default:
break;
}
} else {
Serial.println("vision undetected.");
}
Serial.print("fps = ");
Serial.println(1000/(millis()-time_start));
Serial.println();
}
输出结果:识别颜色时可输出颜色的RGB值及颜色分类标签;识别其它目标时输出其中心坐标值和其所围成的区域大小 上述程序识别的是交通卡片,串口输出信息为卡片中心坐标,卡片外框大小及分类标签(即和识别卡片的下方label数值保持一致),识别其它类型需在程序#define VISION_TYPE处更换识别种类,方能识别其它物体。
-
硬件
- UNO x1
- 小MU视觉传感器 x1
- 连接线 x1
-
软件
- Arduino IDE 点击下载Arduino IDE
/*
****************************************************
* @brief MU Vision Sensor
* @copyright [DFRobot](http://www.dfrobot.com), 2016
* @copyright GNU Lesser General Public License
* @author [WWZ]([email protected])
* @version V1.0
* @date 2019-03-11
* GNU Lesser General Public License.
* All above must be included in any redistribution
* ***************************************************
*/
#include <Wire.h>
#define MU_ADDRESS 0x60
#define PROTOCOL_VER 0x03
#define VISION_ID 0x03 // ball
// register define
#define REG_PROTOCOL_VER 0x01
#define REG_LED1_CONF 0x06
#define REG_LED2_CONF 0x07
#define REG_LED_LEVEL 0x08
#define REG_CAMERA_CONF1 0x10
#define REG_FRAME_CNT 0x1F
#define REG_VISION_ID 0x20
#define REG_VISION_CONF1 0x21
#define REG_PARAM_VALUE5 0x29
#define RESULT_NUM 0x34
#define RESULT_DATA1 0x40
#define RESULT_DATA2 0x41
#define RESULT_DATA3 0x42
#define RESULT_DATA4 0x43
#define RESULT_DATA5 0x44
// color
#define MU_COLOR_BLACK 0x01U
#define MU_COLOR_WHITE 0x02U
#define MU_COLOR_RED 0x03U
#define MU_COLOR_YELLOW 0x04U
#define MU_COLOR_GREEN 0x05U
#define MU_COLOR_CYAN 0x06U
#define MU_COLOR_BLUE 0x07U
#define MU_COLOR_PURPLE 0x08U
int i2c_read8(uint8_t reg) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MU_ADDRESS, 1);
return Wire.read();
}
void i2c_write8(const uint8_t reg, const uint8_t value) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t reg[][2] = {
{ REG_VISION_ID, VISION_ID }, // set vision type = vision_detect
{ REG_VISION_CONF1, 0x21 }, // vision begin
};
uint8_t frame_count_last = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
delay(500);
if (i2c_read8(REG_PROTOCOL_VER) == PROTOCOL_VER) {
Serial.println("device initialized.");
} else {
Serial.println("fail to initialize device! Please check protocol version.");
}
for (uint32_t i = 0; i < sizeof(reg)/2; ++i) {
i2c_write8(reg[i][0], reg[i][1]);
}
}
void loop() {
// put your main code here, to run repeatedly:
long time_start = millis();
int frame_count = 0;
// waiting for update
do {
frame_count = i2c_read8(REG_FRAME_CNT);
} while(frame_count == frame_count_last);
frame_count_last = frame_count;
i2c_write8(REG_VISION_ID, VISION_ID);
// read result
if (i2c_read8(RESULT_NUM) > 0) {
Serial.println("ball detected:");
Serial.print("x = ");
Serial.println(i2c_read8(RESULT_DATA1));
Serial.print("y = ");
Serial.println(i2c_read8(RESULT_DATA2));
Serial.print("width = ");
Serial.println(i2c_read8(RESULT_DATA3));
Serial.print("height = ");
Serial.println(i2c_read8(RESULT_DATA4));
Serial.print("label = ");
switch(i2c_read8(RESULT_DATA5)) {
case 1:
Serial.println("Ping-Pong ball");
break;
case 2:
Serial.println("Tennis");
break;
default:
break;
}
} else {
Serial.println("ball undetected.");
}
Serial.print("fps = ");
Serial.println(1000/(millis()-time_start));
Serial.println();
}
输出结果:可识别目标球体,通过串口可观察到球体的中心坐标,球体外边框大小,分类标签
/*
****************************************************
* @brief MU Vision Sensor
* @copyright [DFRobot](http://www.dfrobot.com), 2016
* @copyright GNU Lesser General Public License
* @author [WWZ]([email protected])
* @version V1.0
* @date 2019-03-11
* GNU Lesser General Public License.
* All above must be included in any redistribution
* ***************************************************
*/
#include <Wire.h>
#define MU_ADDRESS 0x60
#define PROTOCOL_VER 0x03
#define VISION_ID 0x05 // body
// register define
#define REG_PROTOCOL_VER 0x01
#define REG_LED1_CONF 0x06
#define REG_LED2_CONF 0x07
#define REG_LED_LEVEL 0x08
#define REG_CAMERA_CONF1 0x10
#define REG_FRAME_CNT 0x1F
#define REG_VISION_ID 0x20
#define REG_VISION_CONF1 0x21
#define REG_PARAM_VALUE5 0x29
#define RESULT_NUM 0x34
#define RESULT_DATA1 0x40
#define RESULT_DATA2 0x41
#define RESULT_DATA3 0x42
#define RESULT_DATA4 0x43
#define RESULT_DATA5 0x44
// color
#define MU_COLOR_BLACK 0x01U
#define MU_COLOR_WHITE 0x02U
#define MU_COLOR_RED 0x03U
#define MU_COLOR_YELLOW 0x04U
#define MU_COLOR_GREEN 0x05U
#define MU_COLOR_CYAN 0x06U
#define MU_COLOR_BLUE 0x07U
#define MU_COLOR_PURPLE 0x08U
int i2c_read8(uint8_t reg) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MU_ADDRESS, 1);
return Wire.read();
}
void i2c_write8(const uint8_t reg, const uint8_t value) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t reg[][2] = {
{ REG_VISION_ID, VISION_ID }, // set vision type = vision_detect
{ REG_VISION_CONF1, 0x21 }, // vision begin
};
uint8_t frame_count_last = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
delay(500);
if (i2c_read8(REG_PROTOCOL_VER) == PROTOCOL_VER) {
Serial.println("device initialized.");
} else {
Serial.println("fail to initialize device! Please check protocol version.");
}
for (uint32_t i = 0; i < sizeof(reg)/2; ++i) {
i2c_write8(reg[i][0], reg[i][1]);
}
}
void loop() {
// put your main code here, to run repeatedly:
long time_start = millis();
int frame_count = 0;
// waiting for update
do {
frame_count = i2c_read8(REG_FRAME_CNT);
} while(frame_count == frame_count_last);
frame_count_last = frame_count;
i2c_write8(REG_VISION_ID, VISION_ID);
// read result
if (i2c_read8(RESULT_NUM) > 0) {
Serial.println("body detected:");
Serial.print("x = ");
Serial.println(i2c_read8(RESULT_DATA1));
Serial.print("y = ");
Serial.println(i2c_read8(RESULT_DATA2));
Serial.print("width = ");
Serial.println(i2c_read8(RESULT_DATA3));
Serial.print("height = ");
Serial.println(i2c_read8(RESULT_DATA4));
} else {
Serial.println("body undetected.");
}
Serial.print("fps = ");
Serial.println(1000/(millis()-time_start));
Serial.println();
}
输出结果:可识别人体,通过串口可观察到人体的中心坐标和所围成的大小,无分类标签
/*
****************************************************
* @brief MU Vision Sensor
* @copyright [DFRobot](http://www.dfrobot.com), 2016
* @copyright GNU Lesser General Public License
* @author [WWZ]([email protected])
* @version V1.0
* @date 2019-03-11
* GNU Lesser General Public License.
* All above must be included in any redistribution
* ***************************************************
*/
#include <Wire.h>
#define MU_ADDRESS 0x60
#define PROTOCOL_VER 0x03
#define VISION_ID 0x02
// register define
#define REG_PROTOCOL_VER 0x01
#define REG_LED1_CONF 0x06
#define REG_LED2_CONF 0x07
#define REG_LED_LEVEL 0x08
#define REG_CAMERA_CONF1 0x10
#define REG_FRAME_CNT 0x1F
#define REG_VISION_ID 0x20
#define REG_VISION_CONF1 0x21
#define REG_PARAM_VALUE1 0x25
#define REG_PARAM_VALUE2 0x26
#define REG_PARAM_VALUE3 0x27
#define REG_PARAM_VALUE4 0x28
#define RESULT_NUM 0x34
#define RESULT_DATA1 0x40
#define RESULT_DATA2 0x41
#define RESULT_DATA3 0x42
#define RESULT_DATA5 0x44
// color
#define MU_COLOR_BLACK 0x01U
#define MU_COLOR_WHITE 0x02U
#define MU_COLOR_RED 0x03U
#define MU_COLOR_YELLOW 0x04U
#define MU_COLOR_GREEN 0x05U
#define MU_COLOR_CYAN 0x06U
#define MU_COLOR_BLUE 0x07U
#define MU_COLOR_PURPLE 0x08U
int i2c_read8(uint8_t reg) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MU_ADDRESS, 1);
return Wire.read();
}
void i2c_write8(const uint8_t reg, const uint8_t value) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t reg[][2] = {
// { REG_LED_LEVEL, 0x00 }, // LED will be closed automatically in this vision type.
// { REG_LED1_CONF, 0x00 }, // LED1 color
// { REG_LED2_CONF, 0x00 }, // LED2 color
{ REG_CAMERA_CONF1, 0x30 }, // lock AWB
{ REG_VISION_ID, VISION_ID }, // set vision type = vision_recognition
{ REG_PARAM_VALUE1, 50 }, // x
{ REG_PARAM_VALUE2, 50 }, // y
// { REG_PARAM_VALUE3, 5 }, // width
// { REG_PARAM_VALUE4, 5 }, // height
{ REG_VISION_CONF1, 0x21 }, // vision begin
};
uint8_t frame_count_last = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
delay(500);
if (i2c_read8(REG_PROTOCOL_VER) == PROTOCOL_VER) {
Serial.println("device initialized.");
} else {
Serial.println("fail to initialize device! Please check protocol version.");
}
for (uint32_t i = 0; i < sizeof(reg)/2; ++i) {
i2c_write8(reg[i][0], reg[i][1]);
}
delay(1000); // waiting for AWB lock.
}
void loop() {
// put your main code here, to run repeatedly:
long time_start = millis();
int frame_count = 0;
// waiting for update
do {
frame_count = i2c_read8(REG_FRAME_CNT);
} while(frame_count == frame_count_last);
frame_count_last = frame_count;
i2c_write8(REG_VISION_ID, VISION_ID);
// read result
if (i2c_read8(RESULT_NUM) > 0) {
Serial.println("color detected:");
Serial.print("color = (");
Serial.print(i2c_read8(RESULT_DATA1));
Serial.print(",");
Serial.print(i2c_read8(RESULT_DATA2));
Serial.print(",");
Serial.print(i2c_read8(RESULT_DATA3));
Serial.print(")\nlabel = ");
switch (i2c_read8(RESULT_DATA5)) {
case 0:
Serial.println("unknow color");
break;
case 1:
Serial.println("black");
break;
case 2:
Serial.println("white");
break;
case 3:
Serial.println("red");
break;
case 4:
Serial.println("yellow");
break;
case 5:
Serial.println("green");
break;
case 6:
Serial.println("cyan");
break;
case 7:
Serial.println("blue");
break;
case 8:
Serial.println("violet");
break;
default:
break;
}
} else {
Serial.println("color undetected.");
}
Serial.print("fps = ");
Serial.println(1000/(millis()-time_start));
Serial.println();
}
输出结果:可识别相对应的颜色,通过串口可观察到目标区域的颜色 R,G,B 的平均值(0~255)及分类标签
/*
****************************************************
* @brief MU Vision Sensor
* @copyright [DFRobot](http://www.dfrobot.com), 2016
* @copyright GNU Lesser General Public License
* @author [WWZ]([email protected])
* @version V1.0
* @date 2019-03-11
* GNU Lesser General Public License.
* All above must be included in any redistribution
* ***************************************************
*/
#include <Wire.h>
#define MU_ADDRESS 0x60
#define PROTOCOL_VER 0x03
#define VISION_ID 0x06 // shape card
//#define VISION_ID 0x07 // traffic card
//#define VISION_ID 0x08 // number card
// register define
#define REG_PROTOCOL_VER 0x01
#define REG_LED1_CONF 0x06
#define REG_LED2_CONF 0x07
#define REG_LED_LEVEL 0x08
#define REG_CAMERA_CONF1 0x10
#define REG_FRAME_CNT 0x1F
#define REG_VISION_ID 0x20
#define REG_VISION_CONF1 0x21
#define REG_PARAM_VALUE5 0x29
#define RESULT_NUM 0x34
#define RESULT_DATA1 0x40
#define RESULT_DATA2 0x41
#define RESULT_DATA3 0x42
#define RESULT_DATA4 0x43
#define RESULT_DATA5 0x44
// color
#define MU_COLOR_BLACK 0x01U
#define MU_COLOR_WHITE 0x02U
#define MU_COLOR_RED 0x03U
#define MU_COLOR_YELLOW 0x04U
#define MU_COLOR_GREEN 0x05U
#define MU_COLOR_CYAN 0x06U
#define MU_COLOR_BLUE 0x07U
#define MU_COLOR_PURPLE 0x08U
int i2c_read8(uint8_t reg) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MU_ADDRESS, 1);
return Wire.read();
}
void i2c_write8(const uint8_t reg, const uint8_t value) {
Wire.beginTransmission(MU_ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t reg[][2] = {
{ REG_VISION_ID, VISION_ID }, // set vision type = vision_detect
{ REG_VISION_CONF1, 0x21 }, // vision begin
};
uint8_t frame_count_last = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
delay(500);
if (i2c_read8(REG_PROTOCOL_VER) == PROTOCOL_VER) {
Serial.println("device initialized.");
} else {
Serial.println("fail to initialize device! Please check protocol version.");
}
for (uint32_t i = 0; i < sizeof(reg)/2; ++i) {
i2c_write8(reg[i][0], reg[i][1]);
}
}
void loop() {
// put your main code here, to run repeatedly:
long time_start = millis();
int frame_count = 0;
// waiting for update
do {
frame_count = i2c_read8(REG_FRAME_CNT);
} while(frame_count == frame_count_last);
frame_count_last = frame_count;
i2c_write8(REG_VISION_ID, VISION_ID);
// read result
if (i2c_read8(RESULT_NUM) > 0) {
Serial.println("card detected:");
Serial.print("x = ");
Serial.println(i2c_read8(RESULT_DATA1));
Serial.print("y = ");
Serial.println(i2c_read8(RESULT_DATA2));
Serial.print("width = ");
Serial.println(i2c_read8(RESULT_DATA3));
Serial.print("height = ");
Serial.println(i2c_read8(RESULT_DATA4));
Serial.print("label = ");
Serial.println(i2c_read8(RESULT_DATA5));
} else {
Serial.println("card undetected.");
}
Serial.print("fps = ");
Serial.println(1000/(millis()-time_start));
Serial.println();
}
输出结果:可识别目标卡片,通过串口可观察到卡片中心坐标,卡片外框大小,分类标签
1、下载及安装软件V1.5.6及以上版本。下载地址:http://mindplus.cc 详细教程:Mind+基础wiki教程-软件下载安装
2、切换到“上传模式”。 详细教程:Mind+基础wiki教程-上传模式编程流程 3、“扩展”中选择“主控板”或“套件”中的“micro:bit”“掌控板”“麦昆”等你的产品。在“传感器”中搜索“摄像头”,加载“SEN0314 视觉摄像头” 。详细教程:Mind+基础wiki教程-加载扩展库流程
4、根据自己选择的产品,进行编程,如下图以micro:bit为例实现数字识别。 5、菜单“连接设备”,“上传到设备” 6、程序上传完毕后,使用配套的数字卡片对准摄像头,即可看到效果。 注意:output开关拨到1下2上,address开关拨到1下2下。
DF创客社区用户提供了大量项目可供大家参考:
-
micro:bit相关应用:
-
掌控板相关应用:
Q:为什么找不到教程中的“颜色检测”? A:从V1.6.0开始,原“颜色检测”的描述改为“色块检测”,因此使用“色块检测”即可。
Q:上传完程序之后摄像头模块为什么没有任何反应? A:如果使用了“恢复默认设置”可以尝试在这条程序后面跟一条“等待1秒”的程序以使恢复完成,上传完毕之后同时按下主控板和摄像头模块上的复位键复位。
| 更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖! |