diff --git a/client.py b/client.py index 3b37c01..d9dc69b 100644 --- a/client.py +++ b/client.py @@ -2,7 +2,7 @@ import cv2 import socket import numpy as np -from common import Packet +from common import StdPacket, InterlacedPacket UDP_IP = "127.0.0.1" UDP_PORT = 5005 @@ -20,6 +20,31 @@ def send_packet(sock, packet): sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP +def breakdown_image_norm(frame): + (cols, rows, colors) = frame.shape + # break the array down into 16x16 chunks, then transmit them as UDP packets + for i in range(0, cols, 16): + for j in range(0, rows, 16): + # print("Sending frame segment (%d, %d)", i, j) + pkt = StdPacket(j, i, frame[i:i + 16, j:j + 16]) + send_packet(sock, pkt.to_bytestr()) + +def breakdown_image_interlaced(frame): + (cols, rows, colors) = frame.shape + # break the array into 16x32 chunks. we'll split those further into odd and even rows + # and send each as UDP packets. this should make packet loss less obvious + for i in range(0, cols, 32): + for j in range(0, rows, 16): + # print("Sending frame segment (%d, %d)", i, j) + pkt = InterlacedPacket(j, i, False, frame[i:i + 32:2, j:j + 16]) + send_packet(sock, pkt.to_bytestr()) + + for i in range(0, cols, 32): + for j in range(0, rows, 16): + # print("Sending frame segment (%d, %d)", i, j) + pkt = InterlacedPacket(j, i, True, frame[i + 1:i + 32:2, j:j + 16]) + send_packet(sock, pkt.to_bytestr()) + while True: # Capture frame-by-frame ret, frame = cap.read() @@ -29,15 +54,7 @@ while True: print("Can't receive frame (stream end?). Exiting ...") break - (cols, rows, colors) = frame.shape - - # break the array down into 16-bit chunks, then transmit them as UDP packets - for i in range(0, cols, 16): - for j in range(0, rows, 16): - print("Sending frame segment (%d, %d)", i, j) - pkt = Packet(j, i, frame[i:i+16, j:j+16]) - send_packet(sock, pkt.to_bytestr()) - + breakdown_image_interlaced(frame) # Release the capture and close all windows cap.release() \ No newline at end of file diff --git a/common.py b/common.py index 47d07bb..daec585 100644 --- a/common.py +++ b/common.py @@ -1,7 +1,7 @@ import numpy as np -class Packet: +class StdPacket: def __init__(self, x: int, y: int, array: np.ndarray): self.x = x self.y = y @@ -14,9 +14,34 @@ class Packet: bytestr += self.array.tobytes() return bytestr -def from_bytes(b: bytes) -> Packet: +def from_bytes_std(b: bytes) -> StdPacket: x = int.from_bytes(b[0:4], signed = False) y = int.from_bytes(b[4:8], signed = False) array = np.frombuffer(b[8:], np.uint8).reshape(16, 16, 3) - return Packet(x, y, array) \ No newline at end of file + return StdPacket(x, y, array) + + +class InterlacedPacket: + def __init__(self, x: int, y: int, even: bool, array: np.ndarray): + self.x = x + self.y = y + self.even = even + self.array = array + + def to_bytestr(self) -> bytes: + bytestr = b"" + bytestr += self.x.to_bytes(length=4, signed=False) + bytestr += self.y.to_bytes(length=4, signed=False) + bytestr += self.even.to_bytes(length=4) + bytestr += self.array.tobytes() + return bytestr + + +def from_bytes_int(b: bytes) -> InterlacedPacket: + x = int.from_bytes(b[0:4], signed=False) + y = int.from_bytes(b[4:8], signed=False) + even = bool.from_bytes(b[8:12]) + array = np.frombuffer(b[12:], np.uint8).reshape(16, 16, 3) + + return InterlacedPacket(x, y, even, array) \ No newline at end of file diff --git a/server.py b/server.py index 9766d8e..85e1fb5 100644 --- a/server.py +++ b/server.py @@ -2,9 +2,10 @@ import cv2 import socket import numpy as np -from common import Packet, from_bytes +from common import InterlacedPacket, from_bytes_int -UDP_IP = "127.0.0.1" +# bind any IP address +UDP_IP = "" UDP_PORT = 5005 sock = socket.socket(socket.AF_INET, # Internet @@ -20,15 +21,18 @@ while True: # break the array down into 16-bit chunks, then transmit them as UDP packets for i in range(0, HEIGHT, 16): for j in range(0, WIDTH, 16): - data, addr = sock.recvfrom(776) # buffer size is 768 bytes - print("received packet from", addr) - pkt = from_bytes(data) + data, addr = sock.recvfrom(780) # buffer size is 768 bytes + # print("received packet from", addr) + pkt = from_bytes_int(data) x = pkt.x y = pkt.y arr = pkt.array - frame[y:y+16, x:x+16] = arr + if pkt.even: + frame[y+1:y+32:2, x:x+16] = arr + else: + frame[y:y + 32:2, x:x + 16] = arr # Display the resulting frame cv2.imshow('Frame', frame)