OpenCVビデオ通信
Python入門学習(文法、threading、PyQT 5)からOpenCVまで、
Android端末がビデオと対話すると仮定し、Android端末はjpg形式の圧縮ファイルを転送する.jpgに圧縮するのではなく元のビデオを送信すると、PC側で受信したバイト数が多すぎて画面表示速度が遅くなるという問題が発生します.jpg形式に圧縮する時間もありますが、これはネットワーク伝送負荷よりも有利だと思います.(測定方法の問題もありますが、jpg圧縮APIも学べます)
PCは通信方式でサーバとしての役割を果たし、通信が開始されるとAndroidはクライアントとして動作し接続を試みる. PCはクライアント接続によりSocketを生成する. クライアントはjpg形式で圧縮されたビデオを送信し、送信されるたびにByte数が異なるため、今後どのくらいのビデオを受信するかを知る必要がある. で認識された数でビデオデータを受信
受信したデータをOpenCV形式に変換します. OpenCV形式に変換された画像を画面に表示し、jgp形式を再生成します.
画面上でマウスボタンを押して移動すると、その領域と同じ矩形が描かれます.矩形を含む画面はjpg形式に圧縮される. 圧縮jpgをクライアントに再送信します. 知るところ
Android端末がビデオと対話すると仮定し、Android端末はjpg形式の圧縮ファイルを転送する.jpgに圧縮するのではなく元のビデオを送信すると、PC側で受信したバイト数が多すぎて画面表示速度が遅くなるという問題が発生します.jpg形式に圧縮する時間もありますが、これはネットワーク伝送負荷よりも有利だと思います.(測定方法の問題もありますが、jpg圧縮APIも学べます)
次のように動作します。
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
server_socket.bind((HOST, PORT))
print('Socket bind complete')
server_socket.listen(10)
print('Socket now listening')
client_socket, addr = server_socket.accept()
print("wait accept to : ", addr[0], ":", str(addr[1]))
print("Accept to : ", addr)
print('wait image')
bytes_buf = receive_all(client_socket, 4)
受信したデータをOpenCV形式に変換します.
bytes_length = bytes_to_int(bytes_buf)
print("Rx Length = {} ".format(bytes_length))
byte_data = receive_all(client_socket, int(bytes_length))
# convert jpg image to matix
g_decode_img = np.frombuffer(byte_data, dtype=np.uint8)
g_decode_img = cv2.imdecode(g_decode_img, cv2.COLOR_RGB2BGR)
画面上でマウスボタンを押して移動すると、その領域と同じ矩形が描かれます.矩形を含む画面はjpg形式に圧縮される.
cv2.imshow('Client', g_copy_img)
cv2.waitKey(1)
# convert Mat to byte for sending to client
ret, imgencoded = cv2.imencode('.jpg', g_copy_img)
byte_img = np.array(imgencoded)
int_len_byte_img = len(byte_img)
bytes_len_img = int_len_byte_img.to_bytes(4, byteorder='big')
client_socket.send(bytes_len_img)
client_socket.send(byte_img)
知るところ
OpenCVではマウスイベントもサポートされています.
OpenCV画面の色は、R G Bシーケンスではなく、B G Rシーケンスである.
圧縮は行われていますが、1280*720画素は通信していても映像表現がかなり遅いです.
? どこに応用すればいいですか?
すべてのソースimport socket
import struct
import threading
import time
from _thread import *
import numpy as np
import cv2
mouse_rectangle = False
def receive_all(sock, count):
buf = bytearray(b'')
while count:
newbuff = sock.recv(count)
if not newbuff: return None
buf += newbuff
count -= len(newbuff)
return buf
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
def int_to_bytes(value, length):
result = []
for i in range(0, length):
result.append(value >> (i * 8) & 0xff)
result.reverse()
return result
def onMouse(event, x, y, flags, parm):
global mouse_rectangle, col, row, g_copy_img, g_decode_img
if event == cv2.EVENT_LBUTTONDOWN:
mouse_rectangle = True
col, row = x, y
elif event == cv2.EVENT_MOUSEMOVE:
if mouse_rectangle:
cv2.rectangle(g_decode_img, (col, row), (x, y), (0, 255, 0), 2)
elif event == cv2.EVENT_LBUTTONUP:
mouse_rectangle = False
def run_server_cv():
global mouse_rectangle, g_copy_img, g_decode_img
HOST = ''
PORT = 20001
cv2.namedWindow('Client') # should create window object first
cv2.setMouseCallback('Client', onMouse, 0)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
server_socket.bind((HOST, PORT))
print('Socket bind complete')
server_socket.listen(10)
print('Socket now listening')
client_socket, addr = server_socket.accept()
# print("wait accept to : ", addr[0], ":", str(addr[1]))
print("Accept to : ", addr)
print('wait image')
while True:
try:
if mouse_rectangle is True:
bytes_buf_null = receive_all(client_socket, 4)
if bytes_buf_null is not None:
bytes_length_null = bytes_to_int(bytes_buf_null)
print("Clr Length = {} ".format(bytes_length_null))
byte_data_null = receive_all(client_socket, int(bytes_length_null))
else:
bytes_buf = receive_all(client_socket, 4)
if bytes_buf is not None:
bytes_length = bytes_to_int(bytes_buf)
print("Rx Length = {} ".format(bytes_length))
byte_data = receive_all(client_socket, int(bytes_length))
# convert jpg image to matix
g_decode_img = np.frombuffer(byte_data, dtype=np.uint8)
g_decode_img = cv2.imdecode(g_decode_img, cv2.COLOR_RGB2BGR)
g_copy_img = np.copy(g_decode_img)
cv2.imshow('Client', g_copy_img)
cv2.waitKey(1)
# convert Mat to byte for sending to client
ret, imgencoded = cv2.imencode('.jpg', g_copy_img)
byte_img = np.array(imgencoded)
int_len_byte_img = len(byte_img)
bytes_len_img = int_len_byte_img.to_bytes(4, byteorder='big')
client_socket.send(bytes_len_img)
client_socket.send(byte_img)
except IOError:
client_socket.close()
print("wait accept")
client_socket, addr = server_socket.accept()
print("accept to : ", addr[0], ":", str(addr[1]))
print('wait image')
server_socket.close()
if __name__ == "__main__":
run_server_cv()
ちょっと足りないのは何ですか?
Reference
この問題について(OpenCVビデオ通信), 我々は、より多くの情報をここで見つけました
https://velog.io/@zhemdrawer/OpenCV-영상통신
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import socket
import struct
import threading
import time
from _thread import *
import numpy as np
import cv2
mouse_rectangle = False
def receive_all(sock, count):
buf = bytearray(b'')
while count:
newbuff = sock.recv(count)
if not newbuff: return None
buf += newbuff
count -= len(newbuff)
return buf
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
def int_to_bytes(value, length):
result = []
for i in range(0, length):
result.append(value >> (i * 8) & 0xff)
result.reverse()
return result
def onMouse(event, x, y, flags, parm):
global mouse_rectangle, col, row, g_copy_img, g_decode_img
if event == cv2.EVENT_LBUTTONDOWN:
mouse_rectangle = True
col, row = x, y
elif event == cv2.EVENT_MOUSEMOVE:
if mouse_rectangle:
cv2.rectangle(g_decode_img, (col, row), (x, y), (0, 255, 0), 2)
elif event == cv2.EVENT_LBUTTONUP:
mouse_rectangle = False
def run_server_cv():
global mouse_rectangle, g_copy_img, g_decode_img
HOST = ''
PORT = 20001
cv2.namedWindow('Client') # should create window object first
cv2.setMouseCallback('Client', onMouse, 0)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
server_socket.bind((HOST, PORT))
print('Socket bind complete')
server_socket.listen(10)
print('Socket now listening')
client_socket, addr = server_socket.accept()
# print("wait accept to : ", addr[0], ":", str(addr[1]))
print("Accept to : ", addr)
print('wait image')
while True:
try:
if mouse_rectangle is True:
bytes_buf_null = receive_all(client_socket, 4)
if bytes_buf_null is not None:
bytes_length_null = bytes_to_int(bytes_buf_null)
print("Clr Length = {} ".format(bytes_length_null))
byte_data_null = receive_all(client_socket, int(bytes_length_null))
else:
bytes_buf = receive_all(client_socket, 4)
if bytes_buf is not None:
bytes_length = bytes_to_int(bytes_buf)
print("Rx Length = {} ".format(bytes_length))
byte_data = receive_all(client_socket, int(bytes_length))
# convert jpg image to matix
g_decode_img = np.frombuffer(byte_data, dtype=np.uint8)
g_decode_img = cv2.imdecode(g_decode_img, cv2.COLOR_RGB2BGR)
g_copy_img = np.copy(g_decode_img)
cv2.imshow('Client', g_copy_img)
cv2.waitKey(1)
# convert Mat to byte for sending to client
ret, imgencoded = cv2.imencode('.jpg', g_copy_img)
byte_img = np.array(imgencoded)
int_len_byte_img = len(byte_img)
bytes_len_img = int_len_byte_img.to_bytes(4, byteorder='big')
client_socket.send(bytes_len_img)
client_socket.send(byte_img)
except IOError:
client_socket.close()
print("wait accept")
client_socket, addr = server_socket.accept()
print("accept to : ", addr[0], ":", str(addr[1]))
print('wait image')
server_socket.close()
if __name__ == "__main__":
run_server_cv()
Reference
この問題について(OpenCVビデオ通信), 我々は、より多くの情報をここで見つけました https://velog.io/@zhemdrawer/OpenCV-영상통신テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol