Basler Vision Connector: ZMQ JSON Test File with Image Viewer#
This ZMQ sample demonstrates how to use the Basler Vision Connector to open or close a camera and pre-viewing images of the camera in the image viewer by injecting JSON commands via the ZMQ protocol.
Info
Before you start the sample script: If you want to run the script in the Siemens ecosystem, make sure that you have installed the following nodes:
Also, replace the camera ID in JSON commands according to your camera. For further possible JSON commands, refer to the Messaging topics in this documentation.
[{"id":"4439601ca240ab0e","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"08dd196094de4ee6","type":"group","z":"4439601ca240ab0e","name":"Image Viewer","style":{"stroke":"#00457C","fill":"#F59D21","label":true,"color":"#00457C"},"nodes":["46316e67be47a571","743b7a4060ec2c74","da0d0e83e0311c49","91021863b76d9c46","aad40d0878b0ea7f"],"x":864,"y":359,"w":312,"h":142},{"id":"a15b8a9bdb1dd320","type":"group","z":"4439601ca240ab0e","name":"Step 1: Get Connected Devices","style":{"stroke":"#00457C","fill":"#F59D21","label":true,"color":"#00457C"},"nodes":["c5b9ca4503385cfd"],"x":514,"y":199,"w":252,"h":82},{"id":"13dba5f6169ea22e","type":"group","z":"4439601ca240ab0e","name":"Step 2: Open Desired Camera","style":{"label":true,"fill":"#F59D21","stroke":"#00457C","color":"#00457C"},"nodes":["03c4a7175a858618","744e687f5b1183d3"],"x":514,"y":319,"w":212,"h":122},{"id":"f680217c27365bd8","type":"group","z":"4439601ca240ab0e","name":"Step 3: Set Parameters","style":{"fill":"#F59D21","label":true,"stroke":"#00457C","color":"#00457C"},"nodes":["827fc4bc6437ee4e","e9ecfa108fe2adce"],"x":514,"y":479,"w":232,"h":122},{"id":"75469372ead30c41","type":"group","z":"4439601ca240ab0e","name":"Step 4: Start Streaming","style":{"fill":"#F59D21","label":true,"stroke":"#00457C","color":"#00457C"},"nodes":["d1f367f29f67972b","9e981d05d3086101"],"x":514,"y":639,"w":232,"h":122},{"id":"c5b9ca4503385cfd","type":"inject","z":"4439601ca240ab0e","g":"a15b8a9bdb1dd320","name":"EnumerateDevices","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"EnumerateDevices\"}","payloadType":"json","x":650,"y":240,"wires":[["4477a70441e0a6e2"]]},{"id":"f10a9f60cdbeb27f","type":"debug","z":"4439601ca240ab0e","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1125,"y":240,"wires":[],"l":false},{"id":"4477a70441e0a6e2","type":"zeromq request","z":"4439601ca240ab0e","name":"","fields":"payload","server":"tcp://baslervisionconnector-multi-x86-64:5555","output":"string","isserver":false,"intype":"req","x":1020,"y":240,"wires":[["f10a9f60cdbeb27f"]]},{"id":"03c4a7175a858618","type":"inject","z":"4439601ca240ab0e","g":"13dba5f6169ea22e","name":"OpenDevice","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"OpenDevice\",\"DeviceID\":\"1\"}","payloadType":"json","x":630,"y":360,"wires":[["59b0af73730b5f7e"]]},{"id":"744e687f5b1183d3","type":"inject","z":"4439601ca240ab0e","g":"13dba5f6169ea22e","name":"CloseDevice","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"CloseDevice\",\"DeviceID\":\"1\"}","payloadType":"json","x":630,"y":400,"wires":[["59b0af73730b5f7e"]]},{"id":"743b7a4060ec2c74","type":"zeromq in","z":"4439601ca240ab0e","g":"08dd196094de4ee6","name":"","topic":"40062774/stream","fields":"topic,image,metadata","server":"tcp://baslervisionconnector-multi-x86-64:5556","output":"buffer","isserver":false,"intype":"sub","x":970,"y":400,"wires":[["46316e67be47a571","da0d0e83e0311c49"]]},{"id":"d1f367f29f67972b","type":"inject","z":"4439601ca240ab0e","g":"75469372ead30c41","name":"StartStreaming","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"StartStreaming\",\"DeviceID\":\"1\"}","payloadType":"json","x":640,"y":680,"wires":[["59b0af73730b5f7e"]]},{"id":"9e981d05d3086101","type":"inject","z":"4439601ca240ab0e","g":"75469372ead30c41","name":"StopStreaming","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"StopStreaming\",\"DeviceID\":\"1\"}","payloadType":"json","x":640,"y":720,"wires":[["59b0af73730b5f7e"]]},{"id":"46316e67be47a571","type":"debug","z":"4439601ca240ab0e","g":"08dd196094de4ee6","name":"Raw Data","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1115,"y":400,"wires":[],"l":false},{"id":"da0d0e83e0311c49","type":"function","z":"4439601ca240ab0e","g":"08dd196094de4ee6","name":"extract data","func":"const meta = JSON.parse(String.fromCharCode.apply(String, msg.image)) \n\nif ((meta.detail[0].format == \"RGB8\") || (meta.detail[0].format == \"BGR8\")) \n{\nreturn {\n height: meta.detail[0].height,\n width: meta.detail[0].width,\n image: msg.metadata,\n\n };\n} \n\nif (meta.detail[0].format == \"Mono8\") \n{\n return {\n height: meta.detail[0].height,\n width: meta.detail[0].width,\n ...msg,\n image: Buffer.from([...msg.metadata].flatMap((pixel) => [pixel, pixel, pixel]))\n };\n}\n\nif (meta.detail[0].format == \"BayerRG8\") {\n // Convert Bayer RG8 to RGB (Demosaicing process)\n let bayerImage = msg.metadata;\n let width = meta.detail[0].width;\n let height = meta.detail[0].height;\n let rgbImage = [];\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n // Calculate the index of the Bayer pixel\n let index = y * width + x;\n\n let red = 0, green = 0, blue = 0;\n\n // Bayer RG8 pattern:\n // Odd x rows: Green at odd x, Red at even x\n // Even x rows: Green at even x, Blue at odd x\n\n if (x % 2 === 0 && y % 2 === 0) {\n // Red pixel (even x, even y)\n red = bayerImage[index];\n // Interpolate green (check boundary conditions)\n green = (y + 1 < height ? bayerImage[index + width] : bayerImage[index - width]) +\n (x + 1 < width ? bayerImage[index + 1] : bayerImage[index - 1]);\n green /= 2;\n // Interpolate blue (check boundary conditions)\n blue = (y + 1 < height && x + 1 < width) ? bayerImage[index + width + 1] : bayerImage[index - width - 1];\n } else if (x % 2 === 1 && y % 2 === 1) {\n // Green pixel (odd x, odd y)\n green = bayerImage[index];\n // Interpolate red (check boundary conditions)\n red = (y - 1 >= 0 && x - 1 >= 0) ? (bayerImage[index - 1] + bayerImage[index - width]) / 2 : bayerImage[index + 1];\n // Interpolate blue (check boundary conditions)\n blue = (y + 1 < height && x + 1 < width) ? bayerImage[index + width + 1] : bayerImage[index - width - 1];\n } else if (x % 2 === 0 && y % 2 === 1) {\n // Green pixel (even x, odd y)\n green = bayerImage[index];\n // Interpolate red (check boundary conditions)\n red = (y - 1 >= 0 && x - 1 >= 0) ? (bayerImage[index - 1] + bayerImage[index - width]) / 2 : bayerImage[index + 1];\n // Interpolate blue (check boundary conditions)\n blue = (y + 1 < height && x + 1 < width) ? bayerImage[index + width + 1] : bayerImage[index - width - 1];\n } else if (x % 2 === 1 && y % 2 === 0) {\n // Blue pixel (odd x, even y)\n blue = bayerImage[index];\n // Interpolate green (check boundary conditions)\n green = (y + 1 < height ? bayerImage[index + width] : bayerImage[index - width]) +\n (x + 1 < width ? bayerImage[index + 1] : bayerImage[index - 1]);\n green /= 2;\n // Interpolate red (check boundary conditions)\n red = (y - 1 >= 0 && x - 1 >= 0) ? bayerImage[index - 1] : bayerImage[index + 1];\n }\n\n // Push the interpolated RGB values to the output array\n rgbImage.push(red, green, blue);\n }\n }\n\n // Return the RGB image\n return {\n height: meta.detail[0].height,\n width: meta.detail[0].width,\n image: Buffer.from(rgbImage),\n };\n}\n\n\nelse \n{\n node.error(meta.detail[0].format + \" Pixel format is not supported\");\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":975,"y":460,"wires":[["91021863b76d9c46"]],"l":false},{"id":"91021863b76d9c46","type":"jpeg-turbo","z":"4439601ca240ab0e","g":"08dd196094de4ee6","name":"","action":"encode","image":"image","imageWidth":"width","imageWidthType":"msg","imageHeight":"height","imageHeightType":"msg","result":"payload","format":"rgb","quality":40,"subSampling":"gray","x":1025,"y":460,"wires":[["aad40d0878b0ea7f"]],"l":false},{"id":"aad40d0878b0ea7f","type":"image","z":"4439601ca240ab0e","g":"08dd196094de4ee6","name":"Image Viewer","width":"400","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":true,"outputs":1,"x":1075,"y":460,"wires":[[]],"inputLabels":["JPEG Image"],"l":false},{"id":"59b0af73730b5f7e","type":"mp-function","z":"4439601ca240ab0e","name":"DeviceID","rqs":"","func":"let jsonMessage = msg.payload;\njsonMessage.DeviceID = \"40062774\";\n\nmsg.payload = jsonMessage;\n\nreturn msg;","persistent":false,"outputs":1,"threads":1,"noerr":0,"x":920,"y":320,"wires":[["4477a70441e0a6e2"]]},{"id":"827fc4bc6437ee4e","type":"inject","z":"4439601ca240ab0e","g":"f680217c27365bd8","name":"SetPixelFormat","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"SetParameters\",\"DeviceID\":\"1\",\"ParameterList\":[{\"Name\":\"PixelFormat\",\"Value\":\"RGB8\"}]}","payloadType":"json","x":640,"y":520,"wires":[["59b0af73730b5f7e"]]},{"id":"e9ecfa108fe2adce","type":"inject","z":"4439601ca240ab0e","g":"f680217c27365bd8","name":"SetFPS","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Action\":\"SetParameters\",\"DeviceID\":\"1\",\"ParameterList\":[{\"Name\":\"AcquisitionFrameRateEnable\",\"Value\":true},{\"Name\":\"AcquisitionFrameRate\",\"Value\":15}]}","payloadType":"json","x":610,"y":560,"wires":[["59b0af73730b5f7e"]]},{"id":"84e32ea6df0299b3","type":"comment","z":"4439601ca240ab0e","name":"Supported pixel formats: RGB8, BGR8, Mono8, BayerRG8","info":"","x":730,"y":120,"wires":[]}]