我们打算做一款帮助盲人“看到”世界的 AI 硬件。
这个想法的起因是某天中午下班,笔者正在路上走着,忽听到后面传来很轻的歌声。回头看,一个戴着墨镜的男人拿着盲杖,正摸索着沿盲道前行。生活中很少遇到盲人,于是特意留意了下。他立得很直,嘴巴轻轻开合发出歌声,虽然走得慢,却每一步都很扎实。笔者和他一起走了一段,看到前方的盲道上停了一辆摩托车。走在我前面另一个女生尝试去搬走摩托车,见状我也快步上前搭了把手,一起移开了它。因为赶时间,移开车后我就走开了,歌声也越来越远。
后来我想,假如没有人把车移开,就算有盲杖探路,可能也会给这位朋友造成一些不大不小的困扰吧。有什么办法可以提前告知他前方的路况吗?巧的是,多模态大模型能通过自然语言对话、理解图像,理论上正好能充当这位朋友的眼睛。
于是有了这个产品的尝试。
按设想,用户交互的流程是佩戴硬件->摄像头拍摄物理世界发给大模型->大模型理解后以语音形式告知用户前方的路况信息。硬件不可少的模块包括:摄像头、麦克风,网络连接先用WIFI,另外可能需要蓝牙连接手机。
选择的开发板是 XIAO ESP32 S3,笔者是 ESP32 开发的纯新人,故而拿到硬件之后先测试各个模块的功能,同时学习开发过程。
开发板真容如下:
测试代码直接选择的官方示例,地址: https://wiki.seeedstudio.com/cn/xiao_esp32s3_camera_usage/
测试摄像头
下方仅摘抄主要流程代码并在其中加上注释,可视作伪代码理解流程。
void photo_save(const char * fileName) {
// 调用摄像头拍摄一帧画面
camera_fb_t *fb = esp_camera_fb_get();
// 保存图像
writeFile(SD, fileName, fb->buf, fb->len);
// 释放图像 buffer
esp_camera_fb_return(fb);
}
// 图像存储到 SD 卡
void writeFile(fs::FS &fs, const char * path, uint8_t * data, size_t len){
File file = fs.open(path, FILE_WRITE);
file.close();
}
// ESP32 的初始化代码
void setup() {
// 初始化串口
Serial.begin(115200);
// 初始化相机
esp_err_t err = esp_camera_init(&config);
}
// ESP32 的循环程序入口
void loop() {
char filename[32];
sprintf(filename, "/image1.jpg");
photo_save(filename);
Serial.printf("Saved picture: %s\r\n", filename);
}
上面的代码执行完毕会在 SD 卡中保存摄像头拍摄的画面,我们在其中找到下图,是笔者电脑屏幕正播放的内容,摄像头功能正常。
测试麦克风
void setup() {
Serial.begin(115200);
// 设置 I2S 接口使用的引脚,并初始化 I2S 接口
I2S.setAllPins(-1, 42, 41, -1, -1);
I2S.begin(PDM_MONO_MODE, SAMPLE_RATE, SAMPLE_BITS)
// 麦克风开始录制音频
record_wav();
}
void loop() {
// 不执行复杂逻辑
}
void record_wav()
{
// 打开要保存的音频文件
File file = SD.open("/"WAV_FILE_NAME".wav", FILE_WRITE);
// 生成 wav 格式文件的头信息
generate_wav_header(wav_header, record_size, SAMPLE_RATE);
// 往 wav 文件写头信息
file.write(wav_header, WAV_HEADER_SIZE);
// 开始记录音频
esp_i2s::i2s_read(esp_i2s::I2S_NUM_0, rec_buffer, record_size, &sample_size, portMAX_DELAY);
// 往 wav 文件保存音频
file.write(rec_buffer, record_size)
// 释放 buffer
free(rec_buffer);
file.close();
}
上面代码执行完毕后,会在 SD 卡中保存麦克风录制的 20 秒音频文件,我们看到确实保存了,且播放正常。
测试蓝牙
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99);
}
void loop() {
// 开始扫描蓝牙信号
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults();
delay(10000);
}
上述代码执行完毕会列出附近扫描到的蓝牙信号,打开 Serial Monitor,可以看到正常扫描得到了结果:
测试 WIFI
void setup() {
Serial.begin(115200);
}
void loop() {
// 开始扫描 WIFI 信号,返回附近的 WIFI 数量
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0) {
Serial.println("no networks found");
} else {
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i) {
// 打印 WIFI 信息
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
delay(10);
}
}
Serial.println("");
// 延迟 5s 进行下一次扫描
delay(5000);
}
上述代码运行完毕会列出周围 WIFI 的信息,实际结果显示工作正常:
测试网络连接
void setup() {
USE_SERIAL.begin(115200);
wifiMulti.addAP("MY WIFI SSID", "PASSWORD");
}
void loop() {
// 当 WIFI 连接上
if((wifiMulti.run() == WL_CONNECTED)) {
// 请求测试网页
http.begin("http://example.com/index.html");
int httpCode = http.GET();
// 成功返回结果
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
http.end();
}
delay(5000);
}
上述代码将请求测试网页,并返回测试网页的代码。从测试结果看功能正常:
测试大模型
最后,我们测试大模型是否能为盲人朋友识别路况,以最简单的图片中盲道被占的图片为例:
我们用 GPT-4o 来进行测试,结果如下:
我们看到大模型将道路中的摩托车、盲道上的铁架和石块都识别出来了,这是影响盲道畅通的关键因素。当然其中还有一些元素识别有问题,作为后续改进的项目。
总结:
本文对购买的 XIAO ESP32 S3 开发板,测试了摄像头、麦克风、蓝牙、WIFI、网络连接以及最后的大模型识别能力,发现基本功能满足需求。后续将以此为基础,进行该硬件的开发。
欢迎关注哦~
希望各位能提提意见,比如这个想法可行性、实用性,或者其它帮助完善的其它想法都可以的。