这次我们来看一个基于 Arduino 的仿生眼球交互装置,重点是它实现了视觉人脸跟踪功能。这是一个非常适合学生、创客和硬件爱好者的 DIY 科创项目,它将人工智能中的计算机视觉技术,通过 Arduino 微控制器和舵机等硬件实体化,制作出一个能“看”着人转动的机械眼球。项目核心在于利用摄像头捕捉人脸,通过算法计算出人脸位置,再驱动舵机模仿眼球运动,完成实时跟踪。
对于想入门 AIoT(人工智能物联网)或嵌入式视觉的同学来说,这个项目价值很高。它避开了复杂的深度学习模型训练,直接从应用层入手,让你快速搭建一个能跑起来的视觉交互系统。整个过程涉及硬件组装、环境搭建、代码烧录和效果调试,是一个完整的工程实践。
本文将带你从零开始,复现这个“视觉人脸跟踪版本的仿生眼球”。我们会详细拆解其核心能力、所需硬件清单、软件环境配置步骤、关键的代码逻辑,并完成从摄像头调试到舵机跟踪的完整功能测试。最后,还会分享调试过程中常见的坑和解决方案,确保你能一次成功。
1. 核心能力速览
在动手之前,先快速了解这个项目的关键信息,判断是否适合你。
| 能力项 | 说明 |
|---|---|
| 项目类型 | 嵌入式视觉交互装置 / 学生科创DIY套件 |
| 核心功能 | 通过摄像头实时检测人脸,并驱动二自由度舵机云台(仿生眼球)转动,实现人脸跟踪 |
| 主控芯片 | 通常为 Arduino Uno / Mega 或 ESP32-CAM 等带摄像头的开发板 |
| 视觉处理 | 基于 OpenCV 或轻量级人脸检测库(如 Haar Cascade)在 PC 端或开发板上运行 |
| 硬件门槛 | 较低。需要基础电子元件(舵机、摄像头、杜邦线等)和一台电脑。无需高端显卡。 |
| 软件门槛 | 中等。需要安装 Arduino IDE、Python、OpenCV 及相关库,涉及简单的代码编写和烧录。 |
| 通信方式 | 串口通信(USB)。PC处理视觉数据,通过串口发送指令给 Arduino 控制舵机。 |
| 是否支持“脱机”运行 | 可以。若使用 ESP32-CAM 等自带处理能力的板子,可脱离电脑独立运行。 |
| 适合场景 | 人工智能/物联网教学、科创比赛、创客作品、互动艺术装置、机器人视觉入门 |
2. 适用场景与使用边界
这个仿生眼球项目并不仅仅是一个玩具,它在多个场景下都有实际的应用价值和教学意义。
它非常适合:
- 教育学习:作为“人工智能+硬件”的入门实践,直观理解计算机视觉(人脸检测)与执行器(舵机)的闭环控制。
- 科创竞赛:作为智能交互装置或机器人项目的子模块,增加项目的科技感和互动性。
- 创客DIY:爱好者用于制作智能家居伴侣、互动雕塑或机器人头部,增加趣味性。
- 原型验证:验证视觉跟踪方案在特定场景(如简易云台)下的可行性。
需要注意的使用边界:
- 性能限制:基于 Haar Cascade 的传统方法在复杂光照、侧脸或多人场景下跟踪效果会下降。它不是工业级解决方案。
- 实时性:处理帧率和舵机响应速度存在延迟,不适合对实时性要求极高的高速跟踪场景。
- 隐私与伦理:装置搭载摄像头,务必在私人或教学实验环境内使用,不得在未经同意的情况下对他人进行拍摄或跟踪,尊重他人隐私。
- 安全操作:舵机在运行时有一定力度,请勿将手指或其他物体放入运动机构中,防止夹伤或损坏设备。
3. 环境准备与前置条件
开始制作前,请确保你已准备好以下软硬件环境。
3.1 硬件清单
这是完成本项目所需的核心硬件,你可以根据“PC处理”或“嵌入式处理”两种方案进行选择。
| 组件 | 数量 | 说明 | 备注 |
|---|---|---|---|
| 方案A:PC处理视觉(推荐入门) | |||
| Arduino Uno / Mega 开发板 | 1 | 主控制器,负责接收指令并控制舵机。 | 最常用,资料丰富。 |
| USB 数据线 (A to B) | 1 | 为 Arduino 供电并通信。 | |
| 二自由度舵机云台 | 1套 | 包含2个舵机,实现上下(俯仰)和左右(偏航)转动。 | SG90 舵机常见。 |
| 普通USB摄像头 | 1 | 连接电脑,用于捕获视频流。 | 720P即可。 |
| 杜邦线(公对公、公对母) | 若干 | 连接电路。 | |
| 面包板 | 1 | 方便电路搭建和测试。 | |
| 舵机扩展板或独立电源 | 1 | 为舵机提供充足电流(5V/2A),避免 Arduino 板载电源过载。 | 非常重要! |
| 方案B:嵌入式处理(进阶) | |||
| ESP32-CAM 开发板 | 1 | 集成摄像头和Wi-Fi/蓝牙,可独立运行视觉算法。 | 需注意其引脚和供电特殊性。 |
| FTDI 编程器或USB转TTL模块 | 1 | 用于给 ESP32-CAM 烧录程序。 | |
| 二自由度舵机云台 | 1套 | 同上。 | |
| 杜邦线 | 若干 | 同上。 | |
| 稳压电源模块(如 AMS1117-3.3V) | 1 | 为 ESP32-CAM 和舵机提供稳定电源。 | ESP32-CAM 需稳定5V输入。 |
3.2 软件环境准备
我们将以更常见的方案A(PC处理)为例,展开后续步骤。
安装 Arduino IDE
- 访问 Arduino 官网,下载并安装最新版 Arduino IDE。
- 安装后,打开 IDE,在
工具->开发板->开发板管理器中,确保已选择对应的 Arduino 板型(如 Arduino Uno)。
安装 Python 及必要库
- 建议安装 Python 3.8 或以上版本。
- 打开命令行(CMD 或 Terminal),使用 pip 安装以下核心库:
pip install opencv-python pip install pyserial pip install numpy- 验证安装:在 Python 环境中运行
import cv2和import serial,不报错即成功。
4. 硬件连接与电路搭建
正确的硬件连接是项目成功的基础。请严格按照以下步骤操作,特别注意电源部分。
4.1 连接舵机云台
二自由度云台通常有两个舵机:
- 舵机1(水平/Yaw):控制左右转动。
- 舵机2(垂直/Pitch):控制上下转动。
- 将两个舵机分别安装到云台支架上。
- 使用杜邦线连接舵机信号线(通常是橙色或黄色)到 Arduino 的数字引脚。例如:
- 水平舵机信号线 ->引脚 9
- 垂直舵机信号线 ->引脚 10
- 将两个舵机的电源线(红色)和地线(棕色/黑色)连接到舵机扩展板或外部独立电源的 5V 和 GND 输出端。
- 关键步骤:将外部电源的 GND 与 Arduino 板上的 GND 用一根杜邦线连接起来,确保共地。
重要提醒:切勿将多个舵机直接接在 Arduino 板载的 5V 引脚上,板载稳压器无法提供大电流,会导致 Arduino 重启或损坏。
4.2 连接摄像头
将 USB 摄像头插入电脑的 USB 端口。在 Windows 上,通常会被自动识别。你可以在“设备管理器”中查看摄像头是否正常工作。
4.3 最终检查
- Arduino 通过 USB 线连接电脑。
- 舵机电源已正确连接且共地。
- 所有接线牢固,无短路风险。
- 摄像头已插入电脑。
5. Arduino 端程序烧录
Arduino 在这里扮演“执行者”的角色,它等待来自电脑的指令,并解析指令来控制舵机角度。
5.1 编写舵机控制程序
打开 Arduino IDE,新建一个项目,粘贴以下代码。这段代码使用了Servo库来控制两个舵机。
#include <Servo.h> // 定义两个舵机对象 Servo servoYaw; // 水平舵机 Servo servoPitch; // 垂直舵机 // 定义舵机连接的引脚 const int pinServoYaw = 9; const int pinServoPitch = 10; // 存储当前舵机角度 int currentYaw = 90; // 初始居中位置 (0-180度) int currentPitch = 90; // 初始居中位置 (0-180度) void setup() { // 初始化串口通信,波特率与Python端必须一致 Serial.begin(9600); // 将舵机对象绑定到对应引脚 servoYaw.attach(pinServoYaw); servoPitch.attach(pinServoPitch); // 初始化舵机到居中位置 servoYaw.write(currentYaw); servoPitch.write(currentPitch); delay(1000); // 等待舵机就位 Serial.println("Arduino Servo Controller Ready."); } void loop() { // 检查串口是否有数据可读 if (Serial.available() > 0) { // 读取一行数据,格式预期为 "Yaw,Pitch",例如 "100,80" String data = Serial.readStringUntil('\n'); data.trim(); // 去除首尾空白字符 // 查找逗号分隔符 int commaIndex = data.indexOf(','); if (commaIndex != -1) { // 解析Yaw和Pitch值 int targetYaw = data.substring(0, commaIndex).toInt(); int targetPitch = data.substring(commaIndex + 1).toInt(); // 安全限制,防止舵机超范围运动损坏 targetYaw = constrain(targetYaw, 0, 180); targetPitch = constrain(targetPitch, 0, 180); // 平滑移动到目标角度(可选,直接写入也可) // 这里采用直接写入,响应更快 servoYaw.write(targetYaw); servoPitch.write(targetPitch); // 更新当前角度 currentYaw = targetYaw; currentPitch = targetPitch; // 可选:回传确认信息 // Serial.print("Moved to: "); // Serial.print(currentYaw); // Serial.print(", "); // Serial.println(currentPitch); } } // 短暂延迟,避免过于频繁地读取串口 delay(10); }5.2 烧录程序到 Arduino
- 在 Arduino IDE 顶部的
工具菜单中,选择正确的开发板(如 Arduino Uno)和端口(如 COM3)。 - 点击“上传”按钮(向右的箭头)。
- 等待编译和上传完成,看到“上传成功”的提示。
- 上传后,可以打开
工具->串口监视器,将波特率设置为 9600,如果看到 “Arduino Servo Controller Ready.” 的输出,说明 Arduino 端程序已就绪。
6. Python 端视觉处理与跟踪程序
这是项目的“大脑”,运行在电脑上。它负责打开摄像头、检测人脸、计算人脸中心位置、映射成舵机角度,并通过串口发送给 Arduino。
6.1 编写 Python 主程序
创建一个新的 Python 文件,例如face_tracker.py,并粘贴以下代码。请根据注释修改串口号。
import cv2 import serial import time import numpy as np # ==================== 配置区域 ==================== # 1. 修改为你的 Arduino 串口号 SERIAL_PORT = 'COM3' # Windows 示例,Linux/Mac 可能是 '/dev/ttyUSB0' 或 '/dev/ttyACM0' # 2. 确保波特率与 Arduino 程序一致 BAUD_RATE = 9600 # 摄像头索引,通常 0 代表默认摄像头 CAMERA_INDEX = 0 # 处理帧的尺寸,减小可提高速度 FRAME_WIDTH = 640 FRAME_HEIGHT = 480 # 舵机角度范围 (度) SERVO_YAW_RANGE = (0, 180) # 水平 SERVO_PITCH_RANGE = (0, 180) # 垂直 # 图像中心区域死区(像素),防止人脸在中心微小晃动导致舵机抖动 DEAD_ZONE = 30 # 人脸检测器路径(使用OpenCV自带的Haar Cascade) # 通常位于OpenCV安装目录的 `data/haarcascades/` 下,这里使用绝对路径或确保文件存在 FACE_CASCADE_PATH = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml' # ==================== 配置结束 ==================== def map_value(value, in_min, in_max, out_min, out_max): """将输入值从一个线性范围映射到另一个线性范围""" # 先约束在输入范围内 value = max(in_min, min(value, in_max)) # 线性映射 return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min) def main(): # 初始化串口连接 try: ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1) time.sleep(2) # 等待串口稳定 print(f"成功连接到串口 {SERIAL_PORT}") except serial.SerialException as e: print(f"无法打开串口 {SERIAL_PORT}: {e}") print("请检查:1. 串口号是否正确 2. Arduino是否连接 3. 串口是否被其他程序占用") return # 加载人脸检测分类器 face_cascade = cv2.CascadeClassifier(FACE_CASCADE_PATH) if face_cascade.empty(): print("错误:无法加载人脸检测分类器文件!") print(f"请检查文件路径: {FACE_CASCADE_PATH}") ser.close() return # 打开摄像头 cap = cv2.VideoCapture(CAMERA_INDEX) if not cap.isOpened(): print("错误:无法打开摄像头!") ser.close() return cap.set(cv2.CAP_PROP_FRAME_WIDTH, FRAME_WIDTH) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT) print("摄像头已开启,开始人脸跟踪... (按 'q' 键退出)") # 初始化舵机角度(居中) current_yaw = 90 current_pitch = 90 while True: # 读取一帧 ret, frame = cap.read() if not ret: print("无法读取帧,退出。") break # 转换为灰度图(人脸检测需要) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 检测人脸 faces = face_cascade.detectMultiScale( gray, scaleFactor=1.1, # 图像缩放比例,越小越慢但越准 minNeighbors=5, # 候选框最少邻居数,越大要求越高 minSize=(30, 30) # 最小人脸尺寸 ) # 在图像中心画一个十字和死区框,便于观察 center_x = FRAME_WIDTH // 2 center_y = FRAME_HEIGHT // 2 cv2.line(frame, (center_x - 20, center_y), (center_x + 20, center_y), (0, 255, 0), 2) cv2.line(frame, (center_x, center_y - 20), (center_x, center_y + 20), (0, 255, 0), 2) cv2.rectangle(frame, (center_x - DEAD_ZONE, center_y - DEAD_ZONE), (center_x + DEAD_ZONE, center_y + DEAD_ZONE), (0, 255, 255), 2) # 处理检测到的人脸(这里只跟踪最大的一个) if len(faces) > 0: # 取面积最大的人脸 (x, y, w, h) = max(faces, key=lambda rect: rect[2] * rect[3]) # 绘制人脸矩形框 cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) # 计算人脸中心点坐标 face_center_x = x + w // 2 face_center_y = y + h // 2 cv2.circle(frame, (face_center_x, face_center_y), 5, (0, 0, 255), -1) # 判断人脸中心是否在死区内 if (abs(face_center_x - center_x) > DEAD_ZONE or abs(face_center_y - center_y) > DEAD_ZONE): # 将人脸中心坐标映射到舵机角度 # 注意:图像坐标原点在左上角,X向右增加,Y向下增加。 # 舵机Yaw:人脸中心X坐标 -> 水平舵机角度 target_yaw = map_value(face_center_x, 0, FRAME_WIDTH, SERVO_YAW_RANGE[1], SERVO_YAW_RANGE[0]) # 注意方向,可能需要互换 # 舵机Pitch:人脸中心Y坐标 -> 垂直舵机角度 target_pitch = map_value(face_center_y, 0, FRAME_HEIGHT, SERVO_PITCH_RANGE[0], SERVO_PITCH_RANGE[1]) # 发送指令给 Arduino,格式为 "Yaw,Pitch\n" command = f"{target_yaw},{target_pitch}\n" ser.write(command.encode('utf-8')) # print(f"Sent: {command.strip()}") # 调试时可打开 current_yaw, current_pitch = target_yaw, target_pitch else: # 人脸在中心死区内,不发送指令,保持当前位置 pass else: # 未检测到人脸,可以发送一个归中指令或保持不动 # command = "90,90\n" # ser.write(command.encode('utf-8')) pass # 在画面上显示当前舵机角度 cv2.putText(frame, f"Yaw: {current_yaw}, Pitch: {current_pitch}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) # 显示画面 cv2.imshow('Face Tracker', frame) # 按 'q' 键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() cv2.destroyAllWindows() ser.close() print("程序已退出。") if __name__ == "__main__": main()6.2 关键代码逻辑解析
- 串口初始化:程序首先尝试连接 Arduino。请务必根据你的系统修改
SERIAL_PORT。 - 人脸检测:使用 OpenCV 的 Haar Cascade 分类器进行人脸检测。
detectMultiScale参数可调整检测灵敏度和速度。 - 坐标映射:
map_value函数将人脸在图像中的像素坐标,线性映射到舵机的角度范围(0-180度)。注意方向:摄像头里人脸偏左,舵机可能需要向右转,映射时可能需要交换out_min和out_max。 - 死区控制:为了避免人脸在画面中心微小移动导致舵机频繁抖动,设置了
DEAD_ZONE。只有当人脸中心超出这个方形区域,才发送新的移动指令。 - 指令发送:将计算出的 Yaw 和 Pitch 角度格式化为
"角度1,角度2\n"的字符串,通过串口发送。
7. 功能测试与效果验证
现在,让我们启动整个系统,看看仿生眼球是否能“看”着你动。
7.1 启动与测试步骤
- 硬件上电:确保所有硬件连接正确,为舵机外部电源和 Arduino 上电。
- 运行 Python 程序:在命令行中,进入你的代码目录,运行:
python face_tracker.py - 观察启动信息:
- 程序应打印“成功连接到串口 COMx”。
- 接着打印“摄像头已开启,开始人脸跟踪...”。
- 一个名为 “Face Tracker” 的窗口会弹出,显示摄像头画面。
- 初始画面观察:画面中央应有一个绿色的十字和一个黄色的矩形框(死区)。
- 人脸检测测试:将你的脸对准摄像头。如果检测成功,你的脸上会被一个蓝色矩形框标出,并且脸部中心有一个红点。
- 跟踪功能验证:
- 缓慢左右移动你的头部。水平舵机(Yaw)应跟随你的脸转动。
- 缓慢上下移动你的头部。垂直舵机(Pitch)应跟随你的脸转动。
- 尝试在画面中快速移动,观察舵机跟踪的平滑度和延迟。
- 走到画面边缘,观察舵机是否移动到极限角度。
7.2 判断成功的标准
- 基础成功:人脸出现在画面中时,能被蓝色框稳定检测到。
- 核心成功:当你的脸在画面中移动时,舵机云台能跟随转动,使你的脸始终趋向于画面中心区域。
- 体验良好:跟踪过程相对平滑,没有剧烈抖动或明显卡顿;当人脸停留在中心死区内时,舵机保持静止。
7.3 常见失败原因与排查
如果测试不成功,请按以下顺序排查:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Python程序报错“无法打开串口” | 1. 串口号错误。 2. Arduino未连接或未上电。 3. 串口被其他软件(如Arduino IDE串口监视器)占用。 | 1. 检查设备管理器(Windows)或ls /dev/tty*(Mac/Linux)确认端口号。2. 检查Arduino指示灯是否亮起。 3. 关闭所有可能占用串口的程序。 | 修改代码中的SERIAL_PORT变量为正确的端口号。确保Arduino IDE的串口监视器已关闭。 |
| 摄像头窗口未弹出或黑屏 | 1. 摄像头索引错误。 2. 摄像头被其他程序占用。 3. 摄像头驱动问题。 | 1. 尝试将CAMERA_INDEX改为 1 或 2。2. 关闭其他使用摄像头的软件(微信、QQ等)。 3. 在系统设置中测试摄像头是否正常。 | 更换摄像头索引,或重启电脑。 |
| 能打开摄像头,但检测不到人脸(无蓝框) | 1. Haar Cascade 文件路径错误。 2. 光线太暗或人脸角度不正。 3. detectMultiScale参数过于严格。 | 1. 检查FACE_CASCADE_PATH指向的文件是否存在。2. 调整环境光线,正对摄像头。 3. 调整参数,如降低 scaleFactor(如1.05),减少minNeighbors(如3)。 | 确保分类器文件路径正确。改善光照条件。调整检测参数。 |
| 能检测到人脸,但舵机不转动 | 1. 串口指令未成功发送或格式错误。 2. 舵机电源未接或供电不足。 3. Arduino程序未正确烧录或引脚定义错误。 | 1. 在Python代码中取消print(f”Sent:...”)的注释,看是否有指令输出。2. 检查舵机电源线是否接好,用万用表测量电压是否为5V左右。 3. 打开Arduino串口监视器,看是否能收到Python发来的数据。 | 检查电源连接,确保共地。核对Arduino代码中的引脚定义与接线是否一致。检查串口指令格式是否为”角度,角度\n”。 |
| 舵机转动方向相反或范围不对 | 图像坐标到舵机角度的映射关系反了。 | 观察人脸向左移动时,舵机是向左转(跟随)还是向右转(反向)。 | 修改map_value函数中的out_min和out_max顺序。例如,将SERVO_YAW_RANGE[1], SERVO_YAW_RANGE[0]对调。 |
| 舵机抖动严重 | 1. 死区(DEAD_ZONE)设置过小。 2. 检测不稳定,人脸框跳动。 3. 发送指令过于频繁。 | 观察人脸在中心附近时,红点是否在黄色死区框内轻微跳动。 | 1. 增大DEAD_ZONE的值(如从30改为50)。2. 优化人脸检测参数,或使用更稳定的检测器(如Dlib)。 3. 在循环末尾增加 time.sleep(0.05)略微降低发送频率。 |
8. 进阶优化与扩展思路
基础功能跑通后,你可以尝试以下优化,让项目更完善、更智能。
8.1 性能与稳定性优化
- 使用更优的人脸检测器:Haar Cascade 速度虽快,但精度和稳定性一般。可以尝试:
- Dlib 的 HOG + 线性 SVM 或 CNN 人脸检测器:精度更高,但需要安装 dlib 库(安装稍复杂)。
- 轻量级深度学习模型:如 OpenCV 自带的
face_detector(基于 Caffe)或使用 MediaPipe 的人脸检测,在保持实时性的同时提升侧脸、遮挡下的检测能力。
- 加入移动平滑滤波:直接发送原始计算角度会导致运动不平滑。可以加入移动平均滤波或卡尔曼滤波,对连续的多帧角度数据进行平滑处理,再发送给舵机。
- PID控制:将人脸中心与画面中心的偏差作为误差,使用 PID 控制器来计算舵机的调整角度,可以使跟踪更加平稳和精准。
8.2 功能扩展
- 增加表情或手势识别:在检测到人脸的基础上,使用 MediaPipe 或 OpenCV 扩展库来识别张嘴、眨眼、点头、手势(如挥手、点赞),并触发不同的舵机动作或灯光效果。
- 实现“脱机”运行:采用方案B(ESP32-CAM)。将人脸检测算法(如轻量级的 Tiny-YOLO 或专为人脸优化的模型)部署到 ESP32 上,使其完全脱离电脑,成为一个独立的跟踪装置。这需要学习 ESP32 的编程和模型部署。
- 增加无线通信:为 Arduino 连接蓝牙(HC-05/06)或 Wi-Fi(ESP8266/ESP32)模块,让 Python 程序可以通过无线方式发送控制指令,摆脱线缆束缚。
- 设计外壳与结构:使用 3D 打印或激光切割为舵机云台和摄像头制作一个仿生眼球外壳,让外观更具科技感和完整性。
9. 项目总结与资源
这个 Arduino 仿生眼球人脸跟踪项目,成功地将软件(OpenCV视觉算法)与硬件(Arduino、舵机)结合,构建了一个生动的 AI 交互实体。它不仅是学习计算机视觉和嵌入式系统的绝佳入门项目,其模块化的设计(视觉处理、串口通信、舵机控制)也为后续更复杂的机器人或交互装置开发打下了基础。
最关键的成功因素:
- 正确的硬件连接与供电:舵机独立供电并共地是稳定运行的前提。
- 可靠的串口通信:确保波特率一致、指令格式正确。
- 合理的参数调试:人脸检测参数和死区大小需要根据实际环境微调。
- 耐心的调试过程:遇到问题时,按照“电源 -> 通信 -> 检测 -> 控制”的顺序分段排查。
建议下一步:
- 首先确保基础版本稳定运行。
- 然后尝试更换更稳定的人脸检测算法。
- 最后挑战“脱机”运行的 ESP32-CAM 版本。
这个项目的所有代码和思路都是开源的,你可以在此基础上自由修改和创造。希望这篇详细的指南能帮助你顺利点亮这个“会看人”的仿生眼球,开启你的硬件 AI 创作之旅。如果在制作过程中遇到新的问题,欢迎在社区分享和讨论,共同进步。