|
[{"id":"a1ec0d46.3fb21","type":"inject","z":"2038339d.f16dfc","name":"Start","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"x":130,"y":40,"wires":[["444593e4.1e35bc"]]},{"id":"91c9965b.8a7898","type":"function","z":"2038339d.f16dfc","name":"LoadCV","func":"var require = global.get('require');\nvar cv = null;\ntry{\n cv = require('opencv');\n} catch (e){\n cv = require.main.require('opencv');\n}\nvar cvdesc = Object.keys(cv);\nnode.send([null, {payload:cvdesc}]);\nflow.set('cv', cv);\n\n var bg = flow.get('bg');\n if (bg){\n delete bg;\n bg = null;\n }\n \n bg = cv.BackgroundSubtractor.createMOG2();\n node.warn(\"made bg \"+util.inspect(bg));\n flow.set('bg', bg);\n \n\nnode.send({payload:1});\nnode.send({payload:'next'});\n","outputs":"2","noerr":0,"x":420,"y":40,"wires":[["ab72f37b.94ad7"],[]]},{"id":"ab72f37b.94ad7","type":"function","z":"2038339d.f16dfc","name":"GetImage","func":"\n\nif (msg.payload === 0){\n flow.set('state', 'stop');\n \n // in case we never hit if(stop), delete in 200ms\n // else can't open camera ever again. \n setTimeout(function(){\n var vid = flow.get('cvvid');\n if (vid){\n // stopping, so delete vid whilst we're not using it.\n node.warn(util.inspect(vid));\n vid.release();\n flow.set('cvvid', null);\n delete vid;\n }\n }, 200);\n}\n\n\nif (msg.payload === 1){\n try{\n flow.set('state', 'run');\n flow.set('start', null);\n flow.set('count', null);\n flow.set('last_s', null);\n \n var cv = flow.get('cv');\n var timings = flow.get('timings') || {};\n timings.startup = {};\n timings.startup.start = Date.now();\n var vid = new cv.VideoCapture(0);\n var fps = vid.setFPS(flow.get('fps'));\n node.warn(fps);\n timings.startup.end = Date.now();\n timings.startup.diff = timings.startup.end - timings.startup.start;\n \n node.warn(vid);\n flow.set('cvvid', vid);\n } catch (e){\n node.warn(e);\n }\n}\n\nif (msg.payload === 'ack'){\n var timings = flow.get('timings');\n timings.imagecidiff = context.imageci - msg.imageci;\n return;\n}\n\n\nif (msg.payload === 'next'){\n var vid = flow.get('cvvid');\n \n if (vid){\n try{\n //node.warn(\"grabbed \" + util.inspect(err) + \" \"+util.inspect(im));\n vid.read(function(err, im){\n try{\n var state = flow.get(\"state\");\n switch(state){\n case 'stop':\n // stopping, so delete vid whilst we're not using it.\n node.warn(util.inspect(vid));\n vid.release();\n flow.set('cvvid', null);\n delete vid;\n return;\n break;\n default:\n break\n }\n \n if (err) {\n node.warn(\"read \" + util.inspect(err) + \" \"+util.inspect(im));\n return;\n }\n \n if ((im.size()[0] === 0) && (im.size()[1] === 0)){\n node.warn(\"image has zero width or height\");\n return; \n }\n \n msg.camera = im;\n msg.flowstarttime = new Date();\n \n msg.framenumber = context.framenum || 0;\n context.framenum = msg.framenumber + 1;\n\n context.lasttime = context.lasttime || 0;\n\n node.send([null, {payload:0}, null]);\n\n var frametime = Date.now();\n if (context.lasttime){\n node.send([null, null, {payload:frametime - context.lasttime, topic:\"inputframeinterval\"}]);\n }\n context.lasttime = frametime;\n \n node.send(msg);\n } catch(e){\n node.warn(e);\n }\n });\n } catch (e){\n node.warn(e);\n }\n }\n}\n","outputs":"3","noerr":0,"x":320,"y":140,"wires":[["23f78acd.d78c66"],["fb976227.4659e"],["8dc10c1c.1e0ff"]]},{"id":"f7b41010.97451","type":"inject","z":"2038339d.f16dfc","name":"Stop","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":130,"y":80,"wires":[["ab72f37b.94ad7"]]},{"id":"6873c74.548ce38","type":"function","z":"2038339d.f16dfc","name":"BackgroundSubtraction","func":"var cv = flow.get('cv');\n\ntry {\n var bg = flow.get('bg');\n if (!bg){\n }\n \n if (bg){\n var bgstart = (new Date()).valueOf();\n \n //node.warn(msg.img.type());\n //node.warn(utils.inspect(msg.img))\n //node.warn(\"refcountbefore addref \"+msg.img.getrefCount());\n //msg.img.addref();\n //node.warn(\"refcountbefore fn \"+msg.img.getrefCount());\n bg.apply(msg.img, function(err, mat){\n //node.warn(\"did mog \"+err+\" \"+util.inspect(mat));\n try{\n var bgend = (new Date()).valueOf();\n var bgtime = bgend - bgstart;\n node.send([null, {payload:bgtime, topic:\"bgtime\"}]);\n \n msg.out = mat;\n //node.warn(\"did mog:\"+util.inspect(mat));\n \n node.send(msg);\n //msg.avg.release(); \n return;\n } catch(e){\n node.warn(\"exception\"+e);\n }\n });\n \n ///********************** test to break it\n //node.warn(\"refcountbefore release2 \"+msg.img.getrefCount());\n msg.img.release();\n delete msg.img;\n }\n \n} catch(e){\n node.warn(e);\n}\n\nreturn;\n\nreturn msg;","outputs":"2","noerr":0,"x":910,"y":100,"wires":[["c5b16a4b.8a7818"],["8dc10c1c.1e0ff"]]},{"id":"fb976227.4659e","type":"function","z":"2038339d.f16dfc","name":"GetNextFrame","func":"setTimeout(function(){\n node.send({payload:'next'});\n}, 10);\nreturn;","outputs":1,"noerr":0,"x":320,"y":220,"wires":[["ab72f37b.94ad7"]]},{"id":"cfd82a72.82b288","type":"multipart-encoder","z":"2038339d.f16dfc","name":"","statusCode":"","ignoreMessages":true,"outputOneNew":true,"outputOneClosed":false,"outputAllClosed":false,"globalHeaders":{"Content-Type":"multipart/x-mixed-replace;boundary=myboundary","Connection":"keep-alive","Expires":"Fri, 01 Jan 1990 00:00:00 GMT","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","Pragma":"no-cache"},"partHeaders":{"Content-Type":"image/jpeg"},"destination":"all","x":920,"y":520,"wires":[["33c1bb6.75dfa44"]]},{"id":"31e6b5c5.433c0a","type":"http in","z":"2038339d.f16dfc","name":"","url":"/test2","method":"get","upload":false,"swaggerDoc":"","x":720,"y":520,"wires":[["cfd82a72.82b288"]]},{"id":"33c1bb6.75dfa44","type":"function","z":"2038339d.f16dfc","name":"","func":"flow.set('enableavg', msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":1070,"y":520,"wires":[[]]},{"id":"a4ee4265.a400d","type":"function","z":"2038339d.f16dfc","name":"encodetojpg","func":"var enable = flow.get('enableavg');\n\nif (1){\n var av = msg.camera;\n //node.warn(util.inspect(av));\n var d = av.toBuffer(function(err, d){\n av.release();\n delete av;\n delete msg.camera;\n var newmsg = {\n payload: d,\n framenumber: msg.framenumber\n };\n delete msg;\n node.send(newmsg);\n });\n} else {\n msg.camera.release();\n delete msg.camera;\n}\n","outputs":1,"noerr":0,"x":710,"y":440,"wires":[["a58c25b3.b31858"]]},{"id":"c5b16a4b.8a7818","type":"function","z":"2038339d.f16dfc","name":"GetContours","func":"var cv = flow.get('cv');\n\nvar starttime = new Date();\nvar cnts = msg.out.findContours(cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);\nmsg.cnts = cnts;\n\nnode.send([null, {payload:(new Date()) - starttime, topic:\"findcontours\"}]);\n\nreturn msg;","outputs":"2","noerr":0,"x":890,"y":220,"wires":[["dfd68181.234c4"],["8dc10c1c.1e0ff"]]},{"id":"dfd68181.234c4","type":"function","z":"2038339d.f16dfc","name":"Draw Boxes","func":"\nvar numcnts = msg.cnts.size();\n//var area = flow.get(\"area\");\n\nvar movementfound = false;\nvar requiredarea = flow.get('area');\n\nvar starttime = new Date();\nif (numcnts){\n var scalex = msg.camera.width()/msg.out.width();\n var scaley = msg.camera.height()/msg.out.height();;\n var areas = [];\n for (var c = 0; c < numcnts; c++){\n var area = { area:msg.cnts.area(c), index:c };\n areas.push(area);\n }\n var fn = function(a, b){\n return (b.area - a.area);\n }\n areas.sort(fn);\n //node.warn(numcnts + ' ' + util.inspect(areas)); \n \n // draw only the three biggest\n for (var i = 0; ((i < 3) && (i < numcnts)); i++){\n var c = areas[i].index;\n //node.error(areas[i].index + ' '+areas[i].area);\n if (areas[i].area > requiredarea){\n var bounding = msg.cnts.boundingRect(c);\n //node.error(bounding);\n \n // draw onto original camera image\n msg.camera.rectangle([bounding.x*scalex, bounding.y*scaley], [bounding.width*scalex, bounding.height*scaley], [0, 0, 255], 2);\n movementfound = true;\n }\n }\n}\nnode.send([null, null, {payload:(new Date()) - starttime, topic:\"drawboxes\"}]);\n\ndelete msg.cnts;\n\nmsg.movement = movementfound;\n\nvar prevmv = flow.get('prevmv');\nif(movementfound){\n node.send([null, {payload:100, topic:'movement'}]);\n if (!prevmv){\n node.send([null, null, null, {payload:100, topic:'movement'}]);\n node.warn(\"movement\");\n }\n} else {\n if (prevmv){\n node.send([null, null, null, {payload:0, topic:'movement'}]);\n node.warn(\"no movement\");\n }\n node.send([null, {payload:0, topic:'movement'}]);\n}\n\nflow.set('prevmv', movementfound);\n\nreturn msg;\n","outputs":"4","noerr":0,"x":890,"y":280,"wires":[["aacfff54.2fdee"],["8dc10c1c.1e0ff"],["8dc10c1c.1e0ff"],["f340dcf5.b7835"]],"outputLabels":["","movement","",""]},{"id":"7ac8ccbf.574b04","type":"ui_chart","z":"2038339d.f16dfc","name":"","group":"85a18620.7d76d8","order":0,"width":"6","height":"5","label":"chart","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"200","removeOlder":"2","removeOlderPoints":"100","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":true,"x":470,"y":420,"wires":[[],[]]},{"id":"8dc10c1c.1e0ff","type":"function","z":"2038339d.f16dfc","name":"","func":"context.values = context.values || {};\ncontext.avgs = context.avgs || {};\n\nif (msg.topic === 'reset'){\n context.avgs = {};\n return;\n}\n\nif (msg.topic){\n context.values[msg.topic] = msg.payload;\n if (!context.avgs[msg.topic+'avg']){\n context.avgs[msg.topic+'avg'] = msg.payload;\n } else {\n context.avgs[msg.topic+'avg'] *= 0.999;\n context.avgs[msg.topic+'avg'] += msg.payload*0.001;\n }\n return;\n}\n\nvar keys = Object.keys(context.values);\nfor (var i=0; i < keys.length; i++){\n var newmsg = {\n payload:context.values[keys[i]],\n topic:keys[i]\n };\n node.send([newmsg, null]);\n \n}\n\nvar keys = Object.keys(context.avgs);\nfor (var i=0; i < keys.length; i++){\n var newmsg = {\n payload:context.avgs[keys[i]],\n topic:keys[i]\n };\n node.send([null, newmsg]);\n \n}","outputs":"2","noerr":0,"x":300,"y":440,"wires":[["7ac8ccbf.574b04"],["96e4f92a.d3a5e8"]]},{"id":"b98efa63.7c9988","type":"inject","z":"2038339d.f16dfc","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":150,"y":440,"wires":[["8dc10c1c.1e0ff"]]},{"id":"444593e4.1e35bc","type":"function","z":"2038339d.f16dfc","name":"Variables","func":"\n\nflow.set(\"writerframes\", 200);\nflow.set(\"writerframe\", -1);\n\nflow.set(\"fps\", 30);\nflow.set(\"area\", 200);\nflow.set(\"width\", 350);\nflow.set(\"height\", ((flow.get('width')*3/4/2)>>0)*2);\n\nvar timings = {};\nflow.set('timings', timings);\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":40,"wires":[["91c9965b.8a7898"]]},{"id":"23f78acd.d78c66","type":"function","z":"2038339d.f16dfc","name":"resize","func":"\nvar starttime = new Date();\nvar AfterResize = function(err, img){\n try{\n var resizetime = (new Date()) - starttime;\n node.send([null, {payload:resizetime, topic:\"resizetime\"}]);\n msg.img = img;\n node.send([msg, null]);\n } catch (e) {\n node.warn(e);\n }\n};\n\n \n\ntry{\nvar Async = true;\nif (Async){\n // note - generates a new image\n msg.camera.resize(flow.get('width'), flow.get('height'), AfterResize);\n} else {\n // sync - note - modifies the input image\n msg.camera.resize(flow.get('width'), flow.get('height'));\n AfterResize(null, msg.camera);\n}\n} catch (e) {\n node.warn(e);\n}\n\n","outputs":"2","noerr":0,"x":490,"y":120,"wires":[["72e7f9a5.396508"],["8dc10c1c.1e0ff"]]},{"id":"1951b990.48edc6","type":"function","z":"2038339d.f16dfc","name":"split","func":"node.send([msg, null]);\nnode.send([null, msg]);\n","outputs":"2","noerr":0,"x":730,"y":400,"wires":[["a4ee4265.a400d"],["a92355b1.261b38"]]},{"id":"ba6daa76.7bd578","type":"multipart-encoder","z":"2038339d.f16dfc","name":"","statusCode":"","ignoreMessages":true,"outputOneNew":true,"outputOneClosed":false,"outputAllClosed":false,"globalHeaders":{"Content-Type":"multipart/x-mixed-replace;boundary=myboundary","Connection":"keep-alive","Expires":"Fri, 01 Jan 1990 00:00:00 GMT","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","Pragma":"no-cache"},"partHeaders":{"Content-Type":"image/jpeg"},"destination":"all","x":920,"y":620,"wires":[["b730beb9.488e7"]]},{"id":"ec18119.26142f","type":"http in","z":"2038339d.f16dfc","name":"","url":"/mvmt","method":"get","upload":false,"swaggerDoc":"","x":720,"y":620,"wires":[["ba6daa76.7bd578"]]},{"id":"b730beb9.488e7","type":"function","z":"2038339d.f16dfc","name":"","func":"flow.set('enablepic', msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":1070,"y":620,"wires":[[]]},{"id":"2558fee6.bd3f22","type":"function","z":"2038339d.f16dfc","name":"encodetojpg","func":"var enable = flow.get('enablepic');\n\nif (1){\n //var av = flow.get('mask1');//msg.out;\n var av = msg.out;\n //node.warn(util.inspect(av));\n var d = av.toBuffer(function(err, d){\n delete av;\n delete msg.out;\n var newmsg = {\n payload: d\n };\n node.send(newmsg);\n });\n} else {\n delete msg.out;\n}\n","outputs":1,"noerr":0,"x":790,"y":560,"wires":[["ba6daa76.7bd578"]]},{"id":"96e4f92a.d3a5e8","type":"ui_chart","z":"2038339d.f16dfc","name":"","group":"96dbe569.b5e008","order":0,"width":"6","height":"5","label":"avgs","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"200","removeOlder":"2","removeOlderPoints":"100","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":true,"x":470,"y":460,"wires":[[],[]]},{"id":"aacfff54.2fdee","type":"function","z":"2038339d.f16dfc","name":"split","func":"node.send([msg, null]);\nnode.send([null, msg]);\n","outputs":"2","noerr":0,"x":730,"y":360,"wires":[["2ac933df.20042c"],["1951b990.48edc6"]]},{"id":"2ac933df.20042c","type":"function","z":"2038339d.f16dfc","name":"endtime","func":"var endtime = new Date();\n\nvar newmsg = {\n payload:endtime - msg.flowstarttime,\n topic:'flowtime'\n}\n\nreturn newmsg;","outputs":1,"noerr":0,"x":930,"y":380,"wires":[["8dc10c1c.1e0ff"]]},{"id":"4b3e964c.137d58","type":"function","z":"2038339d.f16dfc","name":"VideoWriter","func":"\nvar writerframe = flow.get('writerframe');\nvar writerframes = flow.get('writerframes');\n\nif (writerframe >= 0){\n //node.warn(\"writerframe \"+ writerframe);\n \n var writer = flow.get('writer');\n //node.warn(writerframe);\n \n if (writerframe === 0){\n // start writer\n var cv = flow.get('cv');\n var filename = '/home/pi/output-'+new Date().getTime()+'.avi';\n var FPS = 5;\n writer = new cv.VideoWriter(filename, 'MP42' /*'DIVX'*/, FPS, msg.camera.size(), true); \n flow.set('writer', writer);\n node.warn(\"started writer\"+util.inspect(writer));\n }\n\n if (writer){\n writerframe++;\n flow.set('writerframe', writerframe);\n writer.writeSync(msg.camera);\n }\n\n if (writerframe >= writerframes){\n // stop writer\n if (writer){\n writer.release();\n flow.set('writer', null);\n node.warn(\"stopped writer\");\n }\n flow.set('writerframe', -1);\n }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":1050,"y":460,"wires":[[]]},{"id":"a92355b1.261b38","type":"function","z":"2038339d.f16dfc","name":"split","func":"node.send([msg, null]);\nnode.send([null, msg]);\n","outputs":"2","noerr":0,"x":850,"y":420,"wires":[["2558fee6.bd3f22"],[]]},{"id":"f340dcf5.b7835","type":"function","z":"2038339d.f16dfc","name":"start-stop-VideoRecord","func":"if (msg.payload){\n var writerframe = flow.get('writerframe');\n node.warn(\"movement started \"+writerframe);\n if (writerframe < 0) {\n // start writer\n flow.set('writerframe', 0);\n writerframe = flow.get('writerframe');\n node.warn(\"set writerframe to \"+writerframe);\n }\n} else {\n var writerframe = flow.get('writerframe');\n node.warn(\"movement stopped \"+writerframe);\n if (writerframe >= 0) {\n // start writer\n var writerframes = flow.get('writerframes');\n flow.set('writerframe', writerframes);\n writerframe = flow.get('writerframe');\n node.warn(\"set writerframe to \"+writerframe);\n }\n \n}\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":320,"wires":[[]]},{"id":"b051acc0.7a02d","type":"inject","z":"2038339d.f16dfc","name":"","topic":"reset","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":130,"y":480,"wires":[["8dc10c1c.1e0ff"]]},{"id":"72e7f9a5.396508","type":"function","z":"2038339d.f16dfc","name":"FrameOrder","func":"\nvar framestore = flow.get('framestore') || {};\nvar currentframe = flow.get('currentframe') || 0;\n\n// keep the input msg\nif (msg.framenumber){\n var framediff = (msg.framenumber - currentframe)\n //node.warn(\"framediff \"+framediff);\n\n if (framediff > 5){\n framestore = {};\n currentframe = msg.framenumber;\n node.warn(\"**** reset framediff \"+framediff + \" len \"+Object.keys(framestore).length);\n } else {\n if (framediff > 1){\n node.warn(\"framediff \"+framediff + \" len \"+Object.keys(framestore).length);\n }\n }\n\n framestore['frame'+msg.framenumber] = msg;\n flow.set('framestore', framestore);\n}\n\n\nvar moreframes = 3;\nvar framessent = 0;\ndo {\n if (framestore['frame'+currentframe] != undefined){\n var newmsg = framestore['frame'+currentframe];\n delete framestore['frame'+currentframe];\n currentframe++;\n flow.set('currentframe', currentframe);\n //node.warn();\n node.send(newmsg);\n framessent++;\n moreframes --;\n } else {\n moreframes = 0;\n }\n} while (moreframes);\n\nif (framessent > 2){\n node.warn(\"frames sent \"+framessent);\n}","outputs":1,"noerr":0,"x":690,"y":100,"wires":[["6873c74.548ce38"]]},{"id":"a58c25b3.b31858","type":"function","z":"2038339d.f16dfc","name":"FrameOrder2","func":"\nvar framestore = flow.get('framestore2') || {};\nvar currentframe = flow.get('currentframe2') || 0;\n\n// keep the input msg\nif (msg.framenumber){\n var framediff = (msg.framenumber - currentframe)\n //node.warn(\"framediff \"+framediff);\n\n if (framediff > 5){\n framestore = {};\n currentframe = msg.framenumber;\n node.warn(\"**** reset framediff2 \"+framediff + \" len \"+Object.keys(framestore).length);\n } else {\n if (framediff > 1){\n node.warn(\"framediff2 \"+framediff + \" len \"+Object.keys(framestore).length);\n }\n }\n\n framestore['frame'+msg.framenumber] = msg;\n flow.set('framestore2', framestore);\n}\n\n\nvar moreframes = 3;\nvar framessent = 0;\ndo {\n if (framestore['frame'+currentframe] != undefined){\n var newmsg = framestore['frame'+currentframe];\n delete framestore['frame'+currentframe];\n currentframe++;\n flow.set('currentframe2', currentframe);\n //node.warn();\n var timetosend = (newmsg.time_in + 500) - (new Date());\n if (timetosend < 0)\n timetosend = 0;\n \n setTimeout(function(){node.send(newmsg);}, timetosend);\n \n framessent++;\n moreframes --;\n } else {\n moreframes = 0;\n }\n} while (moreframes);\n\nif (framessent > 2){\n node.warn(\"frames2 sent \"+framessent);\n}","outputs":1,"noerr":0,"x":860,"y":480,"wires":[["cfd82a72.82b288"]]},{"id":"85a18620.7d76d8","type":"ui_group","z":"","name":"Default","tab":"82abaa61.322da8","disp":true,"width":"6"},{"id":"96dbe569.b5e008","type":"ui_group","z":"","name":"avgs","tab":"82abaa61.322da8","disp":true,"width":"6"},{"id":"82abaa61.322da8","type":"ui_tab","z":"","name":"newstuff","icon":"dashboard"}] |