-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimg-annotate.json
1 lines (1 loc) · 7.47 KB
/
img-annotate.json
1
[{"id":"6d1a118a3f3e0ff1","type":"subflow","name":"[IMG] Annotate","info":"","category":"Tequ-API Client","in":[{"x":120,"y":140,"wires":[{"id":"1f46fb3d041df00d"}]}],"out":[{"x":1080,"y":140,"wires":[{"id":"5b7163097e9b52b6","port":0}]}],"env":[{"name":"box_colors","type":"json","value":"{\"fish\":\"#FFFFFF\",\"pike\":\"#006400\",\"perch\":\"#008000\",\"smolt\":\"#ADD8E6\",\"salmon\":\"#0000FF\",\"trout\":\"#0000FF\",\"cyprinidae\":\"#808080\",\"zander\":\"#009000\",\"bream\":\"#008800\"}","ui":{"type":"input","opts":{"types":["json"]}}},{"name":"image_settings","type":"json","value":"{\"quality\":0.8}","ui":{"type":"input","opts":{"types":["json"]}}},{"name":"image_type","type":"str","value":"image/jpeg","ui":{"type":"select","opts":{"opts":[{"l":{"en-US":"JPG"},"v":"image/jpeg"},{"l":{"en-US":"PNG"},"v":"image/png"}]}}},{"name":"bbox_lineWidth","type":"num","value":"5","ui":{"type":"spinner","opts":{"min":0,"max":10}}},{"name":"bbox_text_color","type":"str","value":"white","ui":{"type":"select","opts":{"opts":[{"l":{"en-US":"white"},"v":"white"},{"l":{"en-US":"black"},"v":"black"},{"l":{"en-US":"blue"},"v":"blue"},{"l":{"en-US":"green"},"v":"green"},{"l":{"en-US":"yellow"},"v":"yellow"},{"l":{"en-US":"red"},"v":"red"},{"l":{"en-US":"orange"},"v":"orange"}]}}},{"name":"bbox_font","type":"str","value":"30px Arial","ui":{"type":"select","opts":{"opts":[{"l":{"en-US":"5px Arial"},"v":"5 px Arial"},{"l":{"en-US":"10px Arial"},"v":"10px Arial"},{"l":{"en-US":"15px Arial"},"v":"15px Arial"},{"l":{"en-US":"20px Arial"},"v":"20px Arial"},{"l":{"en-US":"25px Arial"},"v":"25px Arial"},{"l":{"en-US":"30px Arial"},"v":"30px Arial"},{"l":{"en-US":"35px Arial"},"v":"35px Arial"},{"l":{"en-US":"40px Arial"},"v":"40px Arial"},{"l":{"en-US":"45px Arial"},"v":"45px Arial"},{"l":{"en-US":"50px Arial"},"v":"50px Arial"}]}}},{"name":"label_offset_x","type":"num","value":"0","ui":{"type":"input","opts":{"types":["num"]}}},{"name":"label_offset_y","type":"num","value":"30","ui":{"type":"input","opts":{"types":["num"]}}},{"name":"threshold","type":"num","value":"0.75","ui":{"type":"spinner","opts":{"min":0,"max":1}}},{"name":"thumbnail","type":"bool","value":"false","ui":{"type":"input","opts":{"types":["bool","env"]}}},{"name":"thumbnail_width","type":"num","value":"200","ui":{"type":"input","opts":{"types":["num","env"]}}}],"meta":{"module":"[IMG] Annotate","version":"0.0.1","author":"[email protected]","desc":"Annotates prediction results from [AI] Detect subflows.","license":"MIT"},"color":"#87A980","icon":"font-awesome/fa-pencil-square-o","status":{"x":1080,"y":200,"wires":[{"id":"5e4e117baee7e1d7","port":0}]}},{"id":"5e4e117baee7e1d7","type":"status","z":"6d1a118a3f3e0ff1","name":"","scope":["1f46fb3d041df00d"],"x":620,"y":200,"wires":[[]]},{"id":"5b7163097e9b52b6","type":"function","z":"6d1a118a3f3e0ff1","name":"resize","func":"let input = msg.data.properties.object.data.annotated.image;\nlet create_thumbnail = env.get(\"thumbnail\");\nlet width = env.get(\"thumbnail_width\");\nconst start = Date.now();\nlet thumbnail_time_ms=0;;\n\nif (create_thumbnail){\n if (msg.objects_found) {\n let resized = await sharp(input)\n .metadata()\n .then(({ width }) => sharp(input)\n .resize({ width: width })\n .toBuffer()\n ); \n msg.data.properties.object.data.annotated.thumbnail = resized.toString('base64');\n thumbnail_time_ms = Date.now() - start;\n msg.data.properties.object.data.annotated.thumbnail_ms = thumbnail_time_ms;\n }\n}\nmsg.data.properties.object.data.annotated.image = (msg.data.properties.object.data.annotated.image).toString('base64')\nnode.status({ fill: \"green\", shape: \"dot\", text: thumbnail_time_ms + \" ms\" });\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"sharp","module":"sharp"}],"x":630,"y":140,"wires":[[]]},{"id":"1f46fb3d041df00d","type":"function","z":"6d1a118a3f3e0ff1","name":"Annotate with canvas","func":"const start_ms = Date.now();\nconst img = msg.payload;\nconst objects = msg.data.properties.computer_vision.result\nconst labels = msg.data.properties.computer_vision.labels\nconst image_type = env.get(\"image_type\");\nconst image_settings = env.get(\"image_settings\");\nconst bbox_lineWidth = env.get(\"bbox_lineWidth\");\nconst bbox_text_color = env.get(\"bbox_text_color\");\nconst label_offset_x = env.get(\"label_offset_x\");\nconst label_offset_y = env.get(\"label_offset_y\");\nconst bbox_font = env.get(\"bbox_font\");\nconst COLORS = env.get(\"box_colors\");\n\n//Define threshold\nlet threshold = 0;\nlet diff_ms=0;\nlet do_annotate = false;\n\nconst global_settings = global.get(\"settings\") || undefined\nlet thresholdType = \"\"\n\nif(global_settings !== undefined){\n if(\"threshold\" in global_settings){\n threshold = global_settings[\"threshold\"]\n thresholdType = \"global\";\n }\n}\n\nelse if(\"threshold\" in msg){\n threshold = msg.threshold;\n thresholdType = \"msg\";\n if(threshold < 0){\n threshold = 0\n }\n else if(threshold > 1){\n threshold = 1\n }\n}\n\nelse{\n threshold = env.get(\"threshold\");\n thresholdType = \"env\";\n}\n\nmsg.thresholdUsed = threshold;\nmsg.thresholdTypeUsed = thresholdType;\n\nasync function annotateImage(image) {\n const localImage = await canvas.loadImage(image); \n const cvs = canvas.createCanvas(localImage.width, localImage.height);\n const ctx = cvs.getContext('2d'); \n ctx.drawImage(localImage, 0, 0); \n \n objects.forEach((obj) => {\n if(labels.includes(obj.class) && obj.score >= threshold){\n let [x, y, w, h] = obj.bbox;\n ctx.lineWidth = bbox_lineWidth;\n ctx.strokeStyle = COLORS[obj.class];\n ctx.strokeRect(x, y, w, h);\n ctx.fillStyle = bbox_text_color;\n ctx.font = bbox_font;\n ctx.fillText(obj.class+\" \"+Math.round(obj.score*100)+\" %\",x+label_offset_x,y+label_offset_y);\n }\n });\n \n return cvs.toBuffer(image_type, image_settings);\n}\n\nif(objects.length > 0){\n \n for(let i=0;i<objects.length;i++){\n if (objects[i].score >= threshold){\n do_annotate = true; \n }\n }\n\n if(do_annotate){\n msg.data.properties.object.data.annotated.image = await annotateImage(img)\n msg.objects_found = true\n diff_ms = Date.now() - start_ms \n msg.annotated_image = msg.data.properties.object.data.annotated.image;\n node.status({ fill: \"green\", shape: \"dot\", text: diff_ms + \" ms\" });\n }\n else{\n diff_ms = Date.now() - start_ms\n msg.annotated_image = img;\n node.status({ fill: \"red\", shape: \"dot\", text: \"No objects over threshold\" }); \n } \n}\nelse{\n msg.objects_found = false\n diff_ms = Date.now() - start_ms \n msg.annotated_image = img;\n node.status({ fill: \"red\", shape: \"dot\", text: \"No objects to annotate\"});\n}\n\nmsg.data.properties.object.data.annotated.annotation_ms = diff_ms\ndelete msg.thresholdUsed;\ndelete msg.start;\ndelete msg.thresholdTypeUsed;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"canvas","module":"canvas"}],"x":320,"y":140,"wires":[["5b7163097e9b52b6"]]},{"id":"66aadb967c7c9fa2","type":"subflow:6d1a118a3f3e0ff1","z":"7b248573a2bd55b0","name":"","env":[{"name":"box_colors","value":"{\"tuolihissi\":\"#0000FF\"}","type":"json"},{"name":"image_settings","value":"{\"quality\":1}","type":"json"},{"name":"bbox_lineWidth","value":"3","type":"num"}],"x":1160,"y":220,"wires":[["9ec26d9d61933e6f","bcd83448bf116acb"]]}]