Capture Images with Webcam on Gateway

I have had a very odd use case for some functionality on a recent job, and thought I would share some things that may be of use to people on here.

My task was to capture an image from a camera local to the gateway and display/use the image directly in ignition.

To do this I have used a few tools and methods.

  • Install Automation Professionals Image Streamer Module Link
  • Follow the instructions to install FFmpeg and OpenCV Link
  • Install your USB webcam so that it works in Windows as normal.
  • Open up Ignition and start some code:

Under Scripting -> Gateway Events I set up a Message Handler called Capture Image

	import base64
	from system import cv2
	logger = system.util.getLogger("ImageLog")
	# initialize the camera
	cam = cv2.VideoCapture(0) # 0 -> index of camera
	cvImg = cv2.Mat()
	buffer = cv2.MatOfByte()
	if not cam.isOpened():
		logger.info("Error: Could not open camera.")
	else:
		s = cam.read(cvImg) #read image
		if s:    # frame captured without any errors
			
			retval = cv2.imgcodecs.imencode('.jpg', cvImg,buffer) #encode the Mat from openCV as a jpeg
			imageBytes = ''.join(map(lambda x: chr(x % 256), buffer.toArray())) #convert the image to a stream of bytes
			jpg_as_text = base64.b64encode(imageBytes) #Encode the image as base64
			b64Image = "data:image/jpeg;base64,%s"%jpg_as_text #Add the image metadata to the string
			system.tag.writeBlocking(["[edge]New Tag"], [b64Image]) #Write the tag
			logger.info("Image Captured")
		cam.release() #Release camera from script

In the above script, you will see I have created a single tag [edge]New Tag
This is tag is a Memory Tag of type String and this will eventually hold a base64 image string. This is not an ideal way to store the image but its a proof of concept that works.

I am working in Perspective, so I have made a view with an Image and a Button on a page together.

In the view, I have bound the Image prop source to the tag with a Direct tag binding to [edge]New Tag
I have added an onClick event to the Button with the following script:

def runAction(self, event):
	system.util.sendMessage("Edge","CaptureImage",payload={})

Now if you save the project and run the view, click the button and in a second or so you should see an image on the screen in the image container.

Enjoy.

1 Like

Note: 3rd party modules (other than Cirrus Link) are not allowed on Edge.

1 Like

It is a little misleading here, my Gateway started off as an Edge gateway and I had to convert it to a normal gateway before I could get this demo to work.

1 Like