Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

imagezmq.py 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. """ imagezmq: Transport OpenCV images via ZMQ.
  2. Classes that transport OpenCV images from one computer to another. For example,
  3. OpenCV images gathered by a Raspberry Pi camera could be sent to another
  4. computer for displaying the images using cv2.imshow() or for further image
  5. processing. See API and Usage Examples for details.
  6. Copyright (c) 2017 by Jeff Bass.
  7. License: MIT, see LICENSE for more details.
  8. """
  9. import zmq
  10. import numpy as np
  11. import cv2
  12. class ImageSender():
  13. """Opens zmq REQ socket and sends images.
  14. Opens a zmq REQ socket on the image sending computer, often a
  15. Raspberry Pi, that will be sending OpenCV images and
  16. related text messages to the hub computer. Provides methods to
  17. send images or send jpg compressed images.
  18. Arguments:
  19. connect_to: the tcp address:port of the hub computer.
  20. """
  21. def __init__(self, connect_to='tcp://127.0.0.1:63128'):
  22. """Initializes zmq socket for sending images to the hub.
  23. Expects an open socket at the connect_to tcp address; it will
  24. connect to that remote socket after setting up the REQ
  25. socket on this computer.
  26. """
  27. self.zmq_context = SerializingContext()
  28. self.zmq_socket = self.zmq_context.socket(zmq.REQ)
  29. self.zmq_socket.connect(connect_to)
  30. def send_image(self, msg, image):
  31. """Sends OpenCV image and msg to hub computer.
  32. Arguments:
  33. msg: text message or image name.
  34. image: OpenCV image to send to hub.
  35. Returns:
  36. A text reply from hub.
  37. """
  38. if image.flags['C_CONTIGUOUS']:
  39. # if image is already contiguous in memory just send it
  40. self.zmq_socket.send_array(image, msg, copy=False)
  41. else:
  42. # else make it contiguous before sending
  43. image = np.ascontiguousarray(image)
  44. self.zmq_socket.send_array(image, msg, copy=False)
  45. hub_reply = self.zmq_socket.recv() # receive the reply message
  46. return hub_reply
  47. def send_jpg(self, msg, jpg_buffer):
  48. """Sends msg text and jpg buffer to hub computer.
  49. Arguments:
  50. msg: image name or message text.
  51. jpg_buffer: bytestring containing the jpg image to send to hub.
  52. Returns:
  53. A text reply from hub.
  54. """
  55. self.zmq_socket.send_jpg(msg, jpg_buffer, copy=False)
  56. hub_reply = self.zmq_socket.recv() # receive the reply message
  57. return hub_reply
  58. class ImageHub():
  59. """Opens zmq REP socket and receives images.
  60. Opens a zmq REP socket on the hub compuer, for example,
  61. a Mac, that will be receiving and displaying or processing OpenCV images
  62. and related text messages. Provides methods to receive images or receive
  63. jpg compressed images.
  64. Arguments:
  65. open_port: (optional) the socket to open for receiving REQ requests.
  66. """
  67. def __init__(self, open_port='tcp://*:63128'):
  68. """Initializes zmq REP socket to receive images and text.
  69. """
  70. self.zmq_context = SerializingContext()
  71. self.zmq_socket = self.zmq_context.socket(zmq.REP)
  72. self.zmq_socket.bind(open_port)
  73. def recv_image(self, copy=False):
  74. """Receives OpenCV image and text msg.
  75. Arguments:
  76. copy: (optional) zmq copy flag.
  77. Returns:
  78. msg: text msg, often the image name.
  79. image: OpenCV image.
  80. """
  81. msg, image = self.zmq_socket.recv_array(copy=False)
  82. return msg, image
  83. def recv_jpg(self, copy=False):
  84. """Receives text msg, jpg buffer.
  85. Arguments:
  86. copy: (optional) zmq copy flag
  87. Returns:
  88. msg: text message, often image name
  89. jpg_buffer: bytestring jpg compressed image
  90. """
  91. msg, jpg_buffer = self.zmq_socket.recv_jpg(copy=False)
  92. return msg, jpg_buffer
  93. def send_reply(self, reply_message=b'OK'):
  94. """Sends the zmq REP reply message.
  95. Arguments:
  96. reply_message: reply message text, often just string 'OK'
  97. """
  98. self.zmq_socket.send(reply_message)
  99. class SerializingSocket(zmq.Socket):
  100. """Numpy array serialization methods.
  101. Modelled on PyZMQ serialization examples.
  102. Used for sending / receiving OpenCV images, which are Numpy arrays.
  103. Also used for sending / receiving jpg compressed OpenCV images.
  104. """
  105. def send_array(self, A, msg='NoName', flags=0, copy=True, track=False):
  106. """Sends a numpy array with metadata and text message.
  107. Sends a numpy array with the metadata necessary for reconstructing
  108. the array (dtype,shape). Also sends a text msg, often the array or
  109. image name.
  110. Arguments:
  111. A: numpy array or OpenCV image.
  112. msg: (optional) array name, image name or text message.
  113. flags: (optional) zmq flags.
  114. copy: (optional) zmq copy flag.
  115. track: (optional) zmq track flag.
  116. """
  117. md = dict(
  118. msg=msg,
  119. dtype=str(A.dtype),
  120. shape=A.shape,
  121. )
  122. self.send_json(md, flags | zmq.SNDMORE)
  123. return self.send(A, flags, copy=copy, track=track)
  124. def send_jpg(self,
  125. msg='NoName',
  126. jpg_buffer=b'00',
  127. flags=0,
  128. copy=True,
  129. track=False):
  130. """Send a jpg buffer with a text message.
  131. Sends a jpg bytestring of an OpenCV image.
  132. Also sends text msg, often the image name.
  133. Arguments:
  134. msg: image name or text message.
  135. jpg_buffer: jpg buffer of compressed image to be sent.
  136. flags: (optional) zmq flags.
  137. copy: (optional) zmq copy flag.
  138. track: (optional) zmq track flag.
  139. """
  140. md = dict(msg=msg, )
  141. self.send_json(md, flags | zmq.SNDMORE)
  142. return self.send(jpg_buffer, flags, copy=copy, track=track)
  143. def recv_array(self, flags=0, copy=True, track=False):
  144. """Receives a numpy array with metadata and text message.
  145. Receives a numpy array with the metadata necessary
  146. for reconstructing the array (dtype,shape).
  147. Returns the array and a text msg, often the array or image name.
  148. Arguments:
  149. flags: (optional) zmq flags.
  150. copy: (optional) zmq copy flag.
  151. track: (optional) zmq track flag.
  152. Returns:
  153. msg: image name or text message.
  154. A: numpy array or OpenCV image reconstructed with dtype and shape.
  155. """
  156. md = self.recv_json(flags=flags)
  157. msg = self.recv(flags=flags, copy=copy, track=track)
  158. A = np.frombuffer(msg, dtype=md['dtype'])
  159. return (md['msg'], A.reshape(md['shape']))
  160. def recv_jpg(self, flags=0, copy=True, track=False):
  161. """Receives a jpg buffer and a text msg.
  162. Receives a jpg bytestring of an OpenCV image.
  163. Also receives a text msg, often the image name.
  164. Arguments:
  165. flags: (optional) zmq flags.
  166. copy: (optional) zmq copy flag.
  167. track: (optional) zmq track flag.
  168. Returns:
  169. msg: image name or text message.
  170. jpg_buffer: bytestring, containing jpg image.
  171. """
  172. md = self.recv_json(flags=flags) # metadata text
  173. jpg_buffer = self.recv(flags=flags, copy=copy, track=track)
  174. return (md['msg'], jpg_buffer)
  175. class SerializingContext(zmq.Context):
  176. _socket_class = SerializingSocket