第1步:我們需要什么
物理計算
伺服(我使用parralax標準伺服)
Red led
220k電阻
5x電線
Javascript
P5.js
P5 DOM庫
P5串行庫
P5串行控制(處理串行通信的小程序)
ML5.js
對象
MDF 4mm
底漆噴涂
白色噴漆
淺灰色噴涂油漆
黑色噴漆
黑色太陽鏡鏡片(或其他)
第2步:進行姿勢估計工作
首先我們要編寫識別人類的草圖并在它的鼻子上放一個點。目標是從這一點獲取水平X數據并將其發送到Arduino。
讓我們開始吧!
在這個項目中,我們需要一些文件或庫來使一切正常工作:
p5.js (您可以下載完整的軟件包,因為這包括DOM庫)
p5 DOM
p5串口(我使用了包中包含的示例中的p5.serialport.js文件) )
ML5.js(您可以將其作為鏈接包含在內,或者您可以通過這種方式下載整個本地庫,這樣您就不需要連接互聯網以使一切正常工作)
我們擁有所有這些,我們可以將所有內容鏈接到一個簡單的HTML文件中:
接下來是我們的sketch.js文件,其中所有的魔法都發生了!
var serial;
var portName = ‘COM6’; // fill in your serial port name here, you can check the right port in Arduino or P5 serial control
var options = {
baudrate: 19200 //baudrate has to be the same in arduino
};
// this is the message that will be sent to the Arduino:
var oneMessage;
let video;
let poseNet;
let poses = [];
var noseX = []
var ifPerson = true;
//var flipHorizontal = false;
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(width, height);
frameRate(10);
//--------------------------------------
serial = new p5.SerialPort();
// Get a list the ports available
// You should have a callback defined to see the results. See gotList, below:
serial.list();
// Assuming our Arduino is connected, open the connection to it
serial.open(portName, options);
// When you get a list of serial ports that are available
serial.on(‘list’, gotList);
// When you some data from the serial port
serial.on(‘data’, gotData);
//-----------------------------------------
// Create a new poseNet method with a single detection
poseNet = ml5.poseNet(video, {
flipHorizontal: true,
detectionType: ‘single’
}, modelReady);
// This sets up an event that fills the global variable “poses”
// with an array every time new poses are detected
poseNet.on(‘pose’, function (results) {
poses = results;
if (results.length == 0) {
ifPerson = false;
}
//console.log(‘results: ’ + results);
});
// Hide the video element, and just show the canvas
video.hide();
}
function modelReady() {
select(‘#status’).html(‘Model Loaded’);
}
function draw() {
image(video, 0, 0, width, height);
// We can call both functions to draw all keypoints
drawKeypoints();
if (ifPerson == false) {
serial.write(‘c’);
console.log(“X”);
ifPerson = true;
} else {
oneMessage = map(oneMessage, 1, 640, 65, 115);
serial.write(oneMessage);
console.log(“browser: ” + oneMessage);
}
}
//---------------------------------
// Got the list of ports
function gotList(thelist) {
console.log(“List of Serial Ports:”);
// theList is an array of their names
for (var i = 0; i 《 thelist.length; i++) {
// Display in the console
console.log(i + “ ” + thelist[i]);
}
}
// Called when there is data available from the serial port
function gotData() {
var currentString = serial.readLine();
console.log(currentString);
}
//-------------------------------------
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
// Loop through all the poses detected
for (let i = 0; i 《 poses.length; i++) {
// For each pose detected, loop through all the keypoints
for (let j = 0; j 《 poses[i].pose.keypoints.length; j++) {
// A keypoint is an object describing a body part (like rightArm or leftShoulder)
let keypoint = poses[i].pose.keypoints[“0”];
noseX[i] = keypoint.position.x.toFixed(0);
oneMessage = (parseInt(noseX[0],10));
//console.log(typeof(oneMessage));
select(‘#noseX_1’).html(noseX.toString());
//console.log(typeof(oneMessage))
// Only draw an ellipse is the pose probability is bigger than 0.2
if (keypoint.score 》 0.2) {
fill(255, 0, 0);
noStroke();
ellipse(keypoint.position.x, keypoint.position.y, 10, 10);
}
}
}
}
就是這樣!如果您打開html文件,您將看到網絡攝像頭鏡頭上方有一個紅點但鏡像(否則您的伺服將遠離您)。您還將看到發送到Arduino的X數據
第3步:使用P5.serialcontrol
這是一個快速的。為了建立我的草圖和Arduino之間的串行通信,我們需要一個處理所有串行數據的中間人將它發送到另一個。以前人們會使用不太友好的Node.js,p5.serialcontrol修復了這個問題。你可以在這里下載p5.serialcontrol。對于Windows用戶,請查看Alpha 5版本。
可悲的是,p5.serialcontrol并不完美,有時會崩潰。所以要小心你發送了多少數據。
步驟4:一切Arduino
接下來是Arduino代碼并連接伺服和LED。
#include
Servo myservo;
const int redPin = 12;
int newval1, oldval1;
int servoValue;
int space = 2;
int ledState = LOW;
int pos = 0;
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis = 0; // the time when the servo was last moved
unsigned long previousMillis = 0;
const long interval = 500;
int servoPosition = 90;
int servoSlowInterval = 60; // millisecs between servo moves
int servoFastInterval = 10;
int servoInterval = servoSlowInterval; // initial millisecs between servo moves
int servoDegrees = 2; // amount servo moves at each step
int servoMinDegrees = 45; // will be changed to negative value for movement in the other direction
int servoMaxDegrees = 135;
int increment; // increment to move for each interval
int updateInterval; // interval between updates
unsigned long lastUpdate; // last update of position
int counter = 0;
bool executed = false;
void servoSweep() {
if (currentMillis - previousServoMillis 》= servoInterval) {
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition 《= servoMinDegrees) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval == servoSlowInterval) {
servoInterval = servoSlowInterval; //servoFastInterval
}
else {
servoInterval = servoSlowInterval;
}
}
if ((servoPosition 》= servoMaxDegrees) || (servoPosition 《= servoMinDegrees)) {
// if the servo is at either extreme change the sign of the degrees to make it move the other way
servoDegrees = - servoDegrees; // reverse direction
// and update the position to ensure it is within range
servoPosition = servoPosition + servoDegrees;
}
// make the servo move to the next position
myservo.write(servoPosition);
digitalWrite(redPin, LOW);
// and record the time when the move happened
}
void ledBlink () {
if (currentMillis - previousMillis 》= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(redPin, ledState);
}
}
void setup() {
myservo.attach(9); // servo
Serial.begin(19200); // initialize serial communication
//Serial.setTimeout(10);
pinMode(redPin, OUTPUT);
myservo.write(90);
}
void loop() {
currentMillis = millis();
if (executed == false) {
servoSweep();
delay(50);
}
}
void serialEvent () {
while (Serial.available()) {
newval1 = Serial.read(); //read it
//Serial.println(newval1);
if (newval1 》 0 && newval1 != ‘c’) {
executed = true;
ledBlink();
//if (newval1 《 (oldval1 - space) || newval1 》 (oldval1 + space)) { //dead band setup
myservo.write(newval1);
delay(15);
//oldval1 = newval1;
//}
}
if (newval1 == ‘c’) {
executed = false;
}
}
}
正如您所看到的,我使用了不使用delay()的代碼,因此可以隨時停止掃描功能,即如果某人被識別。
在此之后,您可以測試整個系統。首先插入你的Arduino與led和伺服(我在我的箭頭上進行測試),然后啟動p5.serialcontrol然后打開html文件。如果一切正常,箭頭將始終指向您。如果您走出網絡攝像頭捕獲的圖像,伺服將掃描。
第5步:制作安全攝像頭
所有這些軟件和代碼都讓我們開始制作東西!
我模仿了安全攝像頭的這個原型,并為激光切割機設計了它。我用木膠組裝了這些碎片。相機內部有足夠的空間容納Arduino,它需要一些額外的孔才能將所有電線都放入其中。我還將LED放置在正確的位置,并在前面安裝了黑色鏡頭,以提供額外的安全攝像頭效果。我用一些塑料薄膜消除了led燈的光線。
接下來,我準備整個事情并用典型的安全攝像頭顏色繪制它。
步驟6:安裝備注
關于在某處設置此安裝的最后一些評論。安全攝像頭本身沒有攝像頭攝像頭,可以看到前面的人。我所做的是將網絡攝像頭隱藏在支柱中并在其前面放置一個帶孔的海報,以隱藏相機,這對于創造正確的效果至關重要。
您還可以做的就是放置相機處于一個更典型的安全攝像頭位置,就像掛在天花板或墻壁上一樣。但你可以用它做任何你想做的事!
第7步:結束結果
-
監控攝像機
+關注
關注
0文章
47瀏覽量
12777
發布評論請先 登錄

索尼攝像機系統的應用功能

安森美圖像傳感器在安防和監控攝像機中的應用
索尼推出首款攝像機跟蹤系統OCELLUS
什么是多光譜智能光譜監控攝像機,它的用途是什么?
AI智能識別監測攝像機

SONY模組FCB-EV9500L一體化攝像機:安防監控領域的新標桿
MS41928M——網絡攝像機·監控攝像機用鏡頭驅動芯片(內置光圈控制)

車輛沖洗監測攝像機

行為分析智能監測攝像機

評論