问题描述
我正在测试 Python 中的屏幕投射。客户端和服务器的代码都比较简单。
总而言之,我之前做的是:
- 在服务器上:
- 使用
mss
抓取屏幕 - 使用
pickle
进行序列化 - 发送数据
- 对每一帧重复
- 使用
- 在客户端:
- 使用
pickle
接收数据并反序列化 - 通过CV2运行接收到的numpy数组显示
- 使用
我在本地进行了测试,结果证明效果很好。然而,一旦我开始在我的网络(台式机和笔记本电脑之间)内进行测试,问题就迅速激增。质量很棒,但非常滞后,FPS 低得难以置信。
我意识到帧可能太大了,所以我决定将重点转向压缩,我已经搜索并尝试了几个小时但无济于事。经过一段时间的搜索,我在 SO 上遇到了一些使用 zlib
的用户,所以我决定做同样的事情,尽管在序列化和发送(在服务器上)以及反序列化和反序列化之前压缩(zlib.compress(frame)
)解压缩 (zlib.decompress(frame)
)(在客户端上)我无法将数据转回 numpy 数组,因此 CV2 会崩溃,并说出 TypeError: Expected Ptr<cv::UMat> for argument 'src'
之类的内容。
除了知道如何有效地压缩帧之外,我还非常想知道是什么导致了我的代码变慢,因为我不完全确定问题出在帧大小上。我很感激在这个主题上的任何帮助以及任何提示、技巧或批评,因为我在这个主题上绝对没有经验。
服务器代码:
import sys,socket as s
import pickle
import struct
import cv2
import numpy as np
from mss import mss
from PIL import Image
import time
HOST = ''
if len(sys.argv) > 1:
PORT = int(sys.argv[1])
else:
PORT = 9999
sock = s.socket(s.AF_INET,s.soCK_STREAM)
sock.setsockopt(s.soL_SOCKET,s.so_REUSEADDR,1)
sock.bind((HOST,PORT))
sock.listen(1)
(conn_sock,addr) = sock.accept()
bounding_Box = {'top': 0,'left': 0,'width': 1920,'height':1080}
sct = mss()
sct.compression_level = 9
while True:
try:
frame = np.array(sct.grab(bounding_Box))
msg_bytes = pickle.dumps(frame,-1)
size_bytes = struct.pack('i',len(msg_bytes))
# Sending size bytes before actual data
conn_sock.sendall(size_bytes)
conn_sock.sendall(msg_bytes)
except Exception as e:
print(e)
conn_sock.close()
break
cv2.destroyAllWindows()
客户端代码:
import sys,socket as s
import pickle
import struct
import cv2
import numpy as np
from sock_utils import receive_all
if len(sys.argv) > 1:
HOST = sys.argv[1]
PORT = int(sys.argv[2])
else:
HOST = '127.0.0.1'
PORT = 9999
conn_sock = s.socket(s.AF_INET,s.soCK_STREAM)
conn_sock.connect((HOST,PORT))
while True:
# Getting size of bytes to receive
size_bytes = conn_sock.recv(4)
size = struct.unpack('i',size_bytes)[0]
# Getting frame bytes
msg_bytes = receive_all(conn_sock,size)
# Deserializing frame
frame = pickle.loads(msg_bytes)
# Showing output
cv2.namedWindow("Screencasting",cv2.WINDOW_norMAL)
cv2.imshow("Screencasting",frame)
# Checking for 'q' key if pressed
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
conn_sock.close()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)