[Solved] Connecting Cognex to Halcon

I have problems connecting the Cognex camera to Halcon, as Cognex is a closed module which does not communicate or is not seen as camera using Halcon. I heard there was a script around that quickly saves files as alternative for a live feed, can anyone provide this code? (Mathijs? :smiley:)

There are three ways to do this.

The easy way

You can browse to ftp://[CAMERA_IP]/ and look for image.jpg and image.bmp. You can test this on the emulator on your laptop by visiting ftp://localhost/

The harder way

You can use the WriteImageFTP function. This way the camera will write an image to a specified FTP server. Cons with this option are that it is not really working from the emulator, and you have to set up an FTP server first (And the camera is already acting like an FTP server, so if you just need the current image without any extra info go for the easy way)

The hardest way

You can use the DataChannel Communications (look for it in the help file) to get raw pixel data and get an image that way. Below is a script for Python 2 (Should work if you add parentheses to the PRINT commands)

What it basically does is get some data about the image (first 60 bytes) and then 800x600x3 pixels (1440000 bytes). This is put into an image.

Python 3

import socket
import sys
from PIL import Image
from xml.dom import minidom

def recvall(s):
	data = b""
	part = None
	l = 1440060		# Changing this value might break the script. It looks like there is 800x600x3 bytes of data, 1.440.000 + an extra 60 bytes as header
	while part != "":
		part = s.recv(4096) 	# This value might or might not change the transfer speed
		data += part
		l -= len(part)
		if l == 0:
			break
	return data

def createsocket(host, port):
	#create an INET, STREAMing socket
	try:
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	except socket.error:
		print('Failed to create socket')
		sys.exit()
	print('Socket Created')
	 
	try:
		remote_ip = socket.gethostbyname( host )

	except socket.gaierror:
		print('Hostname could not be resolved. Exiting')
		sys.exit()
	
	s.connect((remote_ip , port)) 	#Connect to remote server
	print('Socket Connected to ' + host + ' on ip ' + remote_ip + ' port 50000')

	message = "admin\r\n\r\nimg\r\n" #Send username enter enter img enter, sets the datachannel mode to image
	try :
		s.send(message.encode('utf-8'))
	except socket.error:
		print('Send failed')
		sys.exit()
	print('Message send successfully')

	reply = s.recv(4096)
	reply = str(reply,'utf-8') # Convert the reply to string
	xmlstr = minidom.parseString(reply).toprettyxml(indent="	")
	print(xmlstr)

	return s

#Init variables, change them to camera IP and DataChannel port (50000 by default)
host = 'localhost'
port = 50000

s = createsocket(host, port)	#Connect to Cognex DataChannel
x = 0							#Counter for the images

while(x<20):
	reply = recvall(s) #This process should be threaded for increased performance, might be able to get +- 30fps

	if len(reply) == 1440060: 					#Check again for the reply length, if it is not the right size it will aquire again
		print(len(reply))

		img = Image.frombytes('RGB', (800, 600), reply[60:], decoder_name='raw')
		b, g, r = img.split()					#Split the different color channels because BGR (Halcon and opencv also have functions for that I guess)
		img = Image.merge("RGB", (r, g, b))		#Merge different color channels back to RGB
		img.save(str(x) + '.bmp')				#Save the image to file, or put it directly in your vision application
		x += 1

Python 3 - Greyscale

import socket
import sys
from PIL import Image
from xml.dom import minidom

def recvall(s):
	data = b""
	part = None
	l = 480060		# Changing this value might break the script. It looks like there is 800x600x3 bytes of data, 1.440.000 + an extra 60 bytes as header
	while part != "":
		part = s.recv(4096) 	# This value might or might not change the transfer speed
		data += part
		l -= len(part)
		if l == 0:
			break
	return data

def createsocket(host, port):
	#create an INET, STREAMing socket
	try:
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	except socket.error:
		print('Failed to create socket')
		sys.exit()
	print('Socket Created')
	 
	try:
		remote_ip = socket.gethostbyname( host )

	except socket.gaierror:
		print('Hostname could not be resolved. Exiting')
		sys.exit()
	
	s.connect((remote_ip , port)) 	#Connect to remote server
	print('Socket Connected to ' + host + ' on ip ' + remote_ip + ' port 50000')

	message = "admin\r\n\r\nimg\r\n" #Send username enter enter img enter, sets the datachannel mode to image
	try :
		s.send(message.encode('utf-8'))
	except socket.error:
		print('Send failed')
		sys.exit()
	print('Message send successfully')

	reply = s.recv(4096)
	reply = str(reply,'utf-8') # Convert the reply to string
	xmlstr = minidom.parseString(reply).toprettyxml(indent="	")
	print(xmlstr)

	return s

#Init variables, change them to camera IP and DataChannel port (50000 by default)
host = 'localhost'
port = 50000

s = createsocket(host, port)	#Connect to Cognex DataChannel
x = 0							#Counter for the images

while(x<20):
	reply = recvall(s) #This process should be threaded for increased performance, might be able to get +- 30fps

	if len(reply) == 480060: 					#Check again for the reply length, if it is not the right size it will aquire again
		print(len(reply))

		img = Image.frombytes('L', (800, 600), reply[60:], decoder_name='raw')
		#b, g, r = img.split()					#Split the different color channels because BGR (Halcon and opencv also have functions for that I guess)
		#img = Image.merge("RGB", (r, g, b))		#Merge different color channels back to RGB
		img.save(str(x) + '.bmp')				#Save the image to file, or put it directly in your vision application
		x += 1

Python 2


import socket
import sys
from PIL import Image

def recvall(s):
	data = ""
	part = None
	junk = ""
	l = 1440060		#Changing this value might break the script
	while part != "":
		part = s.recv(4096) 	#This value might or might not change the transfer speed
		data += part
		l -= len(part)
		if l == 0:
			break
	return data

def createsocket(host, port):
	#create an INET, STREAMing socket
	try:
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	except socket.error:
		print 'Failed to create socket'
		sys.exit()
	print 'Socket Created'
	 
	try:
		remote_ip = socket.gethostbyname( host )

	except socket.gaierror:
		print 'Hostname could not be resolved. Exiting'
		sys.exit()
	
	s.connect((remote_ip , port)) 	#Connect to remote server
	print 'Socket Connected to ' + host + ' on ip ' + remote_ip + ' port 50000'

	message = "admin\r\n\r\nimg\r\n" #Send username enter enter img enter, sets the datachannel mode to image
	try :
		s.sendall(message)
	except socket.error:
		print 'Send failed'
		sys.exit()
	print 'Message send successfully'

	reply = s.recv(4096)
	print reply

	return s

#Init variables, change them to camera IP and DataChannel pot (50000 by default)
host = 'localhost'
port = 50000

s = createsocket(host, port)	#Connect to Cognex DataChannel
x = 0							#Counter for the images

while(1):
	reply = recvall(s) #This process should be threaded for increased performance, might be able to get +- 30fps

	if len(reply) == 1440060: 					#Check again for the reply length, if it is not the right size it will aquire again
		print len(reply)

		img = Image.frombytes('RGB', (800, 600), reply[60:], decoder_name='raw')
		b, g, r = img.split()					#Split the different color channels because BGR (Halcon and opencv also have functions for that I guess)
		img = Image.merge("RGB", (r, g, b))		#Merge different color channels back to RGB
		img.save(str(x) + '.bmp')				#Save the image to file, or put it directly in your vision application
		x += 1

Conclusion

If you just want this to work I would strongly advise to just download the BMP or JPG file from the camera’s built in FTP server. If you are using python and for some reason you feel the need to use the datachannel feel free to do so.

Also, the datachannel can be used to:

  • Retrieve images
  • Retrieve data from cells
  • Specify to only receive data when values update

If you decide to use the datachannel you should read the help file topics about Put and SetWatch. Good luck!