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