Mathematica+Arduino 摄像头检测人脸并跟随

2016-12-0611.2万
精华项目
AI 快速预览详细 收起
本文介绍了如何使用Mathematica 10/11和Arduino开发板,通过USB摄像头实现人脸检测并驱动9g舵机进行摄像头跟随。硬件包括Arduino开发板、USB摄像头、9g舵机和舵机云台。通过Mathematica代码计算人脸中心坐标,并通过串口发送给Arduino,驱动舵机实现摄像头跟随。该项目适用于STEM教育和少儿编程入门,帮助孩子理解图像处理和机械控制的原理。
通过USB摄像头获取图像,如果检测到人脸将计算出中心坐标,把坐标通过串口发送给Arduino,算出人脸坐标偏离画面中心点的距离,然后根据这个偏离值驱动舵机带动摄像头修正指向,从而可以跟随人脸移动。

软件
Mathematica 10/11
Arduino IDE

硬件
Arduino开发板
USB摄像头
9g舵机
舵机云台

连接线若干

连接
把摄像头固定在舵机云台上,在Arduino开发板上插上IO传感器扩展板,舵机接在传感器扩展板的第9个数字引脚上。
注意:
如果选用的是大功率的云台和舵机,需要为舵机独立供电。
本文使用的云台为一个自由度(水平移动),知道了原理后扩展为两个自由度也很简单(水平+垂直)。
Mathematica+Arduino 摄像头检测人脸并跟随图2

演示

Mathematica+Arduino 摄像头检测人脸并跟随图1

Mathematica 代码
  1. $ImagingDevice = $ImagingDevices[[2]];
  2. dev = DeviceOpen["Serial", "COM3"]
  3. Dynamic[
  4. i = CurrentImage[];
  5. boxes = FindFaces;
  6. If[boxes =!= {},
  7.   {X, Y} = Round[Mean @@ boxes];
  8.   Column@
  9.    {
  10.     HighlightImage[i, Circle[{X, Y}, 50], ImageSize -> {320, 240}],
  11.     DeviceWrite[dev, ToString[X]]
  12.     },
  13.   i]
  14. ]
复制代码


Arduino 代码

  1. #include <Servo.h>
  2. #define  servomaxx   180   // max degree servo horizontal (x) can turn
  3. #define  screenmaxx   320   // max screen horizontal (x)resolution
  4. #define  screenmaxy   240    // max screen vertical (y) resolution
  5. #define  servocenterx   90  // center po#define  of x servo
  6. #define  servopinx   9   // digital pin for servo x
  7. #define  baudrate 9600  // com port speed. Must match your setting
  8. #define distancex 2  // x servo rotation steps
  9. int valx = 0;       // store x data from serial port
  10. int posx = 0;
  11. int incx = 10;  // significant increments of horizontal (x) camera movement
  12. Servo servox;
  13. void setup() {
  14.   Serial.begin(baudrate);        // connect to the serial port
  15.   Serial.setTimeout(20);
  16.   Serial.println("Starting Cam-servo Face tracker");
  17.   pinMode(servopinx, OUTPUT);   // declare the LED's pin as output
  18.   servox.attach(servopinx);
  19.   // center servos
  20.   servox.write(servocenterx);
  21.   delay(200);
  22. }
  23. void loop () {
  24.   while (Serial.available() <= 0); // wait for incoming serial data
  25.   if (Serial.available() >= 1)  
  26.   {
  27.     // get X axis 2-byte integer from serial
  28.     valx = Serial.parseInt();
  29.     // read last servos positions
  30.     posx = servox.read();
  31.     //Find out if the X component of the face is to the left of the middle of the screen.
  32.     if (valx < (screenmaxx / 2 - incx)) {
  33.       if ( posx >= incx ) posx += distancex; //Update the pan position variable to move the servo to the left.
  34.     }
  35.     //Find out if the X component of the face is to the right of the middle of the screen.
  36.     else if (valx > screenmaxx / 2 + incx) {
  37.       if (posx <= servomaxx - incx) posx -= distancex; //Update the pan position variable to move the servo to the right.
  38.     }
  39.     // Servos will rotate accordingly
  40.     servox.write(posx);
  41.   }
  42. }
复制代码

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(47)
JOVI
学习学习
耘想
66666666666
花生编程
赞赞赞赞赞
花生编程
厉害厉害!!!
独钓寒江雪
为大神的作品点赞
派大星ym
,,,
派大星ym
牛牛牛牛牛
wx1
这是什么型号摄像头啊
我用 arduino mega 2560 可以实现吗
汤半泛
流弊 但是学习不来呀
陸
挺好的,支持一下
左左
能配合机械臂使用吗?
WUjlxzxu
Mathematica代码输入后怎么不行
JW
“一个未知的边框名字(ToBoxes)被作为BoxForm传给表达式. 检查表达式的格式规则."
我做的时候有这个报错是怎么回事呢?
weiyouwong
毕设
Denon时光
楼主还在吗,看了你的帖子觉得非常有意思,就自己动手做了一下,但是mathematical从来没用过,所以结果不太成功,求楼主给一个详细一点的关于mathematical部分的教程,或加一下我的QQ:1533329711,我向您求教
wan_2
您好,请问有这款USB摄像头的购买链接吗
wan_2
厉害了world哥
蓝鲸
大神,为什么我的arduino串口上接收不到mma发送到串口的信息
lilei8488
厉害了。之前只是用processing 做过类似的项目
Runingsail
这是通过什么来确定人脸中心的坐标?