A continuación se han anotado diversos ejemplos para envío de imagen IP de un servidor a un único cliente.

contenido

  1. ...


Una imagen será transferida del cliente al servidor: primero, en el cliente se muestra la imagen a transferir. Entonces presiona una tecla para realizar la transferencia. En el servidor se verá la imagen. Entonces presiona una tecla del servidor para terminar el programa.

  1. La imagen es generada en el cliente
  2. La imagen se divide en bloques de 16x16 pixeles. Por suuesto, se espera que el lector comprenda que las dimensiones de la imagen son múltiplo de 16.
  3. Cada bloque se envía espera un acuse de recibido.


Para enviar una imagen imagen se utiliza el sigiente protocolo:

 
cadena significado
"var": Es una cadena de tres bytes que indica al servidor que prepare sus variables.
"blk": Los datos están enmarcados por la cadena-cabecera "blk" de tres bytes. Esta cabecera indica que se trata de un paquete de datos.
"shw": Es una cadena de tres bytes que indica al servidor mostrar la imagen.
"eol" Es una cadena de tres bytes que indica el fin de la comunicación.


El siguiente programa envía una imagen.

#client.py
#!/usr/bin/python

#Este programa funciona enviando comandos
# frm   : -Indica que se deben preparar las variables para recibir un frame

# blk	: -Indica que se empieza la transmision de los macrobloques
#	  -Ya se tienen contados cuantos macrobloques enviar
# shw	: -Muestra imagen generada
# eol	: -Fin de comunicacion


import cv2
import socket
import struct
import time

#Paquetes de comando
shwpkg='shw'+260*'x'
eolpkg="eol"+260*'x'

#La imagen
frameGray=cv2.imread("Ginevra-de-benci_640x640.png",0)
[rows,cols]=frameGray.shape
cv2.imshow("loclaView",frameGray)
cv2.waitKey(0)

#La red: se levanta primero el sistema de comunicciones
socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_client.connect ( ("localhost",9999) )

#Inicializando variables en el servidor.
#Se envia el tamanio de la imagen
varpkg="var"
varpkg+=struct.pack('HH',rows,cols)
varpkg+=256*"x"
socket_client.send(varpkg)
ack=socket_client.recv(3) #ack
print ack

#Envia bloques: el formato es:
# blk | r | c | macroblock_cargo
# blk | r | c | macroblock_cargo
# ...
for r in range (0,640,16):
	for c in range (0,640,16):
		str='blk'
		str+=struct.pack('HH',r,c)
		for k in  frameGray[r:r+16,c:c+16].reshape(16*16).tolist():
			str+=struct.pack('B',k)
		socket_client.send(str)
		ack=socket_client.recv(3) # ack

#Envia senial de "exhibe imagen"
socket_client.send(shwpkg)
ack=socket_client.recv(3) # ack

#Envia el fin comunicacion
socket_client.send("eol")
ack=socket_client.recv(3) # ack

cv2.destroyWindow('loclaView')
capture.release()
socket_client.close()


El siguiente programa recibe una imagen.

#server.py
#!/usr/bin/python

#Este programa funciona recibiendo comandos
# var   : -Indica que se deben preparar las variables para recibir un frame

# blk	: -Indica que se empieza la transmision de los macrobloques
#	  -Ya se tienen contados cuantos macrobloques enviar
#	  - (3 bytes de cabecera) + (2 bytes de renglon) + (2 bytes de columna) + ( 16x16 pieles = 256 bytes )  = 263 bytes


# shw	: -Muestra imagen generada

# eol	: -Fin de comunicacion

import cv2
import socket
import numpy
import struct

#la red: se levanta primero el sistema de comunicaciones
socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.bind( ("0.0.0.0",9999) )
socket_server.listen(1)
socket_client, (host_client,port_client)  = socket_server.accept()
print ("IP cliente ",host_client)  # Imprime la IP del host
print ("Puerto TCP ",port_client)

#El visor de imagen
cv2.namedWindow("remoteView")

#Recepcion de comandos
while True:
	str=socket_client.recv(263)

	# Modo de inicializacion
	if str[0:3]=="var":
		rows,cols=struct.unpack('HH',str[3:7])
		frame=numpy.zeros([rows,cols],dtype=numpy.uint8)
		socket_client.send('ack')

	# Modo de recepcion de bloques
	if str[0:3]=='blk':
		(r,c)=struct.unpack('HH',str[3:7])
		frame[r:r+16,c:c+16]=numpy.array( struct.unpack(16*16*'B',str[7:]) ).reshape([16,16])
		socket_client.send('ack')

	# Modo de exhibicion
	if str[0:3]=="shw":
		cv2.imshow("remoteView",frame)
		key=cv2.waitKey(5) # Esta linea es necesaria para mostrar la imagen
		socket_client.send('ack')

	# Modo de terminacion
	if str[0:3]=="eol":
		socket_client.send('ack')
		break


#Cerrando todo
print("Presione una tecla")
cv2.waitKey(0)
print "Adios"
cv2.destroyWindow("remoteView")
socket_client.close()
socket_server.close()