雑メモ
- 送信するときに大きい画像とだとエラーになる場合がある。その場合はデータを分割して送りましょう
- 分割して送った場合、1つのデータがどこからどこまでなのか、受信側は判断する必要がある。今回のコードは任意の文字列で判断していますが、よく考えたら、プロトコルってbytes数とかで判断しているの多いからbytes数とかがいいと思った
import socket import numpy as np import cv2 udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) to_send_addr = ('127.0.0.1', 9999) img = np.zeros([500, 500], np.uint) # テスト画像作成 with closing(udp): jpg_str = cv2.imencode('.jpeg', img) # 画像を分割する for i in np.array_split(jpg_str[1], 10): # 画像の送信 udp.sendto(i.tostring(), to_send_addr) # 1つのデータが終了したよを伝えるために判断できる文字列を送信する # -> チェックするなら送信する画像のbytes数のほうがいいと思った udp.sendto(b'__end__', to_send_addr) udp.close()
受信側
import socket import numpy as np import cv2 def recive(udp): buff = 1024 * 64 while True: recive_data = bytes() while True: # 送られてくるデータが大きいので一度に受け取るデータ量を大きく設定 jpg_str, addr = udp.recvfrom(buff) is_len = len(jpg_str) == 7 is_end = jpg_str == b'__end__' if is_len and is_end: break recive_data += jpg_str if len(recive_data) == 0: continue # string型からnumpyを用いuint8に戻す narray = np.fromstring(recive_data, dtype='uint8') # uint8のデータを画像データに戻す img = cv2.imdecode(narray, 1) yield img udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp.bind(('127.0.0.1', 9999)) # 画像を取り続ける for img in recive(udp): # 送信された画像の処理を行う # ...
encode, decodeをOpenCVではなくて、pillowでできないか模索中