Telegram Object Detection Bot using Node-RED and TensorFlow Object Detection on macOS

Fun project!

The GitHub project page for Node-RED node with a TensorFlow.js Object Detection model cautions that their demo code only works with the Raspberry PI. However, today I got it working (quite easily) with macOS.

It's fairly accurate too! However, LOL, there was no airplane in our condo today!!!; but maybe that reading happened when I was moving the camera around, haha. Here is a quick screen grab from Telegram on the desktop.

Here is my Node-RED flow for this caper:

To build this, just follow the README.md file on the GitHub page above and here (again):

https://github.com/IBM/node-red-tensorflowjs

It might also help to watch the YT Video:

Creating A Machine Learning IoT App on Raspberry Pi with Node-RED and TensorFlow.js. Jan 7, 2020

The instructions are easy to follow, and so I will not repeat them here. However, here are the steps to get it to work on macOS:

teps:

  1. Install rpi-gpio into Node-RED (so we can disable those nodes easily when we import the flow from the demo code);
  2. Install node-red-tensorflowjs in Node-RED
  3. brew install imagesnap;
  4. audio node in Node-RED: change aplay to afplay;
  5. adjust full paths as needed;

I modified most of the flow to create this logic, at a high level

  • Turn On and Off the WebCam using Telegram
  • Turn On and Off the "nothing detected" message with Telegram (debugging when away)
  • Retooled the detection logic.

New detection logic (function) as follows:

var onoff = global.get("onoff") || "on";
let newMsg = {};
var chat = "your_telegram_chat_id_here";
var type = "message";
var message = "";
var count = 0;
var score = 0.0;
var onoi = ["chair", "couch", "bench"];   // onoi = "objects not of interest"

if (onoff == "on" || onoff == "all") {
  for (let object of msg.payload) {
    if (object.class.length > 2) {
      if (onoi.includes(object.class)) {
      } else {
        count++;
        score = (100 * object.score).toFixed(1);
        message =
          'TF CamBot detected a "' +
          object.class +
          '" with ' +
          score +
          "% confidence.";
        newMsg = { payload: { chatId: chat, type: type, content: message } };
        //console.log(newMsg.payload);
        node.send([[newMsg]]);
      }
    }
  }

  if (count < 1 && onoff == "all") {
    message = "TF CamBot detected nothing!";
    newMsg = { payload: { chatId: chat, type: type, content: message } };
    node.send([[newMsg]]);
  }
}

Here is the Node-RED flow:

[{"id":"21dff30d.cdd83c","type":"tab","label":"NEO DETECT","disabled":false,"info":""},{"id":"940a9a8d.367588","type":"inject","z":"21dff30d.cdd83c","name":"Take Photo","topic":"","payload":"","payloadType":"date","repeat":"15","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":180,"wires":[["f2a273c5.fc849"]]},{"id":"71a92361.dbad0c","type":"debug","z":"21dff30d.cdd83c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1000,"y":280,"wires":[]},{"id":"339bc42f.3b72fc","type":"tfjs-object-detection","z":"21dff30d.cdd83c","name":"","modelUrl":"","x":760,"y":180,"wires":[["71a92361.dbad0c","5ff0aa2f.76ba54"]]},{"id":"4442c40d.9bc1dc","type":"usbcamera","z":"21dff30d.cdd83c","filemode":"0","filename":"image01.jpg","filedefpath":"1","filepath":"/Users/Tim","fileformat":"jpeg","resolution":"2","name":"","x":530,"y":180,"wires":[["339bc42f.3b72fc","518f1480.b2223c"]]},{"id":"518f1480.b2223c","type":"image","z":"21dff30d.cdd83c","name":"","width":"240","data":"payload","dataType":"msg","thumbnail":true,"active":false,"x":760,"y":280,"wires":[]},{"id":"cddbc39f.fb82c","type":"comment","z":"21dff30d.cdd83c","name":"Check detected classes for specific object.","info":"","x":210,"y":280,"wires":[]},{"id":"6dc534c0.7946ac","type":"telegram sender","z":"21dff30d.cdd83c","name":"CamBot Send","bot":"995ad6d2.ff8ae8","x":1240,"y":100,"wires":[[]]},{"id":"5ff0aa2f.76ba54","type":"function","z":"21dff30d.cdd83c","name":"Detection Logic","func":"var onoff =global.get('onoff') || 'on';\nlet personDetected = false;\nlet newMsg = {};\nvar chat = 727630977;\nvar type = \"message\";\nvar message = \"\";\nvar count = 0;\nvar score = 0.0;\nvar onoi = [\"chair\", \"couch\", \"bench\"];\n\nif(onoff ==\"on\" ||onoff == \"all\")\n{\nfor (let object of msg.payload) {\n    if (object.class.length >  2 ) {\n        if (onoi.includes(object.class)) {\n        }\n        else {\n        count++;\n        score = (100*object.score).toFixed(1);\n         message = 'TF CamBot detected a \"'+ object.class+'\" with '+score+'% confidence.';\n         newMsg = {payload:{chatId:chat,type:type,content:message}};\n        //console.log(newMsg.payload);\n        node.send([ [ newMsg] ]);\n        }\n    }\n}\n\nif(count < 1 &&  onoff == \"all\"){\n    message = 'TF CamBot detected nothing!';\n       newMsg = {payload:{chatId:chat,type:type,content:message}};\n       node.send([ [ newMsg] ]);\n}\n}\n","outputs":1,"noerr":0,"x":1010,"y":180,"wires":[["6dc534c0.7946ac"]]},{"id":"492a7004.57b96","type":"telegram receiver","z":"21dff30d.cdd83c","name":"CamBot In","bot":"995ad6d2.ff8ae8","saveDataDir":"","x":110,"y":100,"wires":[["f2c0ca3b.61eac8"],[]]},{"id":"f2c0ca3b.61eac8","type":"change","z":"21dff30d.cdd83c","name":"Global: On/Off/All ","rules":[{"t":"set","p":"onoff","pt":"global","to":"payload.content","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":100,"wires":[["168875ba.43431a"]]},{"id":"168875ba.43431a","type":"function","z":"21dff30d.cdd83c","name":"Confirm C2","func":"let newMsg = {};\nvar chat = 111111111;\nvar type = \"message\";\nmessage = \"TF CamBot is \"+msg.payload.content;\nnewMsg = {payload:{chatId:chat,type:type,content:message}};\nnode.send([ [ newMsg] ]);\n","outputs":1,"noerr":0,"x":530,"y":100,"wires":[["6dc534c0.7946ac"]]},{"id":"f2a273c5.fc849","type":"function","z":"21dff30d.cdd83c","name":"On || Off ?","func":"var onoff =global.get('onoff') || 'on';\nif(onoff =='on' || onoff =='all')\n{\nreturn msg;\n}\n\n","outputs":1,"noerr":0,"x":310,"y":180,"wires":[["4442c40d.9bc1dc"]]},{"id":"995ad6d2.ff8ae8","type":"telegram bot","z":"","botname":"YourCoolCambot","usernames":"","chatids":"","baseapiurl":"","updatemode":"polling","pollinterval":"300","usesocks":false,"sockshost":"","socksport":"6667","socksusername":"anonymous","sockspassword":"","bothost":"","localbotport":"8443","publicbotport":"8443","privatekey":"","certificate":"","useselfsignedcertificate":false,"sslterminated":false,"verboselogging":false}]

Works like a charm so far, just needs some fine tuning.

Enjoy!

My plan is to try to detect the seagulls which sometimes fly into our condo since the window are open most of the time! Those bird go a bit crazy when they fly into the condo (normally only one at a time) looking for food, and cannot fly out so easily!

Well, it's a good life if that is the main problem we want to detect, for sure!

3 Likes

Now that all is working "OK"... I moved this Node-RED image detection app to a MacBook Air, using the built-in web cam, and am now trying to detect the seagulls when they fly into my "balcony bonsai tree", LOL. USB cord for the Logitech HD cam was not long enough from the trash can mac on my desktop.

So far, no birds! Waiting..... waiting...... cyberstalking ..... tensorflowing.....

If it works, first we will try playing some "qwaaawk... qwaaaak " or "brraaapp... braaapp" audio clip loudly ... haha

This is funny... the sun is setting over the ocean, and "Mr. Smart TensorFlow Muppet Bot"... id's this as "oven"... LOL

So, my wife bursts out laughing tell me "it's trying to tell you it's hot, but does not have the words..... " so funny around here ... hahaha

Had this Node-RED, COCO-SSD, TensorFlow contraption out on the balcony hunting for birds today. Then was busy on some other project, and got this incoming.

So, not sure if the gizmo I made actually identified an airplane or it is confusing birds with planes! LOL

Anyway, I have heard so many "bad stories" about these AI algos are used for evil; but today it was really fun detecting various things and laughing at what my MacBook Air thought was a "airplane" or a "flower pot" or some other crazy idea from an image detection bot.....

"It's a bird! It's a plane! No! It's MuppetBot!"

1 Like

Success!

After running for 4 days (LOL) and detecting the sun as "oven" and moving leaves on a bonsai tree as "airplane" and "keyboard", a small bird flew in and perched itself right on the balcony rail, and my MuppetBot detected "bird".... LOL

My wife was watching the coronavirus updates on the local news and excitedly yelled "A bird is in your camera view! Did you get it!"... hahah. I checked, and sure enough, "bird". LOL

Little MuppetBot is certainly far from perfect (I need to install a more robust (large, slower) TF object detection model, but have been busy on the test migration project....).

Check it out :slight_smile:

1 Like

FYI,

Here is the current way "MuppetBot" is situated....