51784| 49
|
[进阶] Mathematica+Arduino 摄像头检测人脸并跟随 |
本帖最后由 mmaer 于 2017-8-14 18:44 编辑 通过USB摄像头获取图像,如果检测到人脸将计算出中心坐标,把坐标通过串口发送给Arduino,算出人脸坐标偏离画面中心点的距离,然后根据这个偏离值驱动舵机带动摄像头修正指向,从而可以跟随人脸移动。 软件 Mathematica 10/11 Arduino IDE 硬件 Arduino开发板 USB摄像头 9g舵机 舵机云台 连接线若干 连接 把摄像头固定在舵机云台上,在Arduino开发板上插上IO传感器扩展板,舵机接在传感器扩展板的第9个数字引脚上。 注意: 如果选用的是大功率的云台和舵机,需要为舵机独立供电。 本文使用的云台为一个自由度(水平移动),知道了原理后扩展为两个自由度也很简单(水平+垂直)。 ![]() 演示 ![]() Mathematica 代码 [mw_shl_code=applescript,true]$ImagingDevice = $ImagingDevices[[2]]; dev = DeviceOpen["Serial", "COM3"] Dynamic[ i = CurrentImage[]; boxes = FindFaces; If[boxes =!= {}, {X, Y} = Round[Mean @@ boxes]; Column@ { HighlightImage[i, Circle[{X, Y}, 50], ImageSize -> {320, 240}], DeviceWrite[dev, ToString[X]] }, i] ][/mw_shl_code] Arduino 代码 [mw_shl_code=c,true]#include <Servo.h> #define servomaxx 180 // max degree servo horizontal (x) can turn #define screenmaxx 320 // max screen horizontal (x)resolution #define screenmaxy 240 // max screen vertical (y) resolution #define servocenterx 90 // center po#define of x servo #define servopinx 9 // digital pin for servo x #define baudrate 9600 // com port speed. Must match your setting #define distancex 2 // x servo rotation steps int valx = 0; // store x data from serial port int posx = 0; int incx = 10; // significant increments of horizontal (x) camera movement Servo servox; void setup() { Serial.begin(baudrate); // connect to the serial port Serial.setTimeout(20); Serial.println("Starting Cam-servo Face tracker"); pinMode(servopinx, OUTPUT); // declare the LED's pin as output servox.attach(servopinx); // center servos servox.write(servocenterx); delay(200); } void loop () { while (Serial.available() <= 0); // wait for incoming serial data if (Serial.available() >= 1) { // get X axis 2-byte integer from serial valx = Serial.parseInt(); // read last servos positions posx = servox.read(); //Find out if the X component of the face is to the left of the middle of the screen. if (valx < (screenmaxx / 2 - incx)) { if ( posx >= incx ) posx += distancex; //Update the pan position variable to move the servo to the left. } //Find out if the X component of the face is to the right of the middle of the screen. else if (valx > screenmaxx / 2 + incx) { if (posx <= servomaxx - incx) posx -= distancex; //Update the pan position variable to move the servo to the right. } // Servos will rotate accordingly servox.write(posx); } }[/mw_shl_code] |
© 2013-2021 Comsenz Inc. Powered by Discuz! X3.4 Licensed