首先,我试图做一些类似屏幕共享的事情,我遇到了一个错误。我试图一行一行地发送图像,但我发现它只能在局域网中工作,因为连接速度要快得多。然后我只传输每个像素,然后自己构建阵列,这会非常慢。代码如下: 服务器端:
def getImg(socket,y,x):
pixels = []
print(x*y*3)
for a in range(x*y*3):
pixels.append(struct.unpack('i', socket.recv(4))[0])
if a%(x*y)==0:
pass
return np.array(pixels).reshape(y,x,3)
客户端:
def sendSS(img):
y, x, color = img.shape
print(y*x*3)
for a in range(y):
for b in range(x):
for m in img[a][b]:
socket.send(struct.pack('i', m))
错误是:
(<class 'cv2.error'>, error("OpenCV(4.5.1) c:\\users\\appveyor\\appdata\\local\\temp\\1\\pip-req-build-wvn_it83\\opencv\\modules\\imgproc\\src\\color.simd_helpers.hpp:94: error: (-2:Unspecified error) in function '__cdecl cv::impl::`anonymous-namespace'::CvtHelper<struct cv::impl::`anonymous namespace'::Set<3,4,-1>,struct cv::impl::A0xeee51b91::Set<3,4,-1>,struct cv::impl::A0xeee51b91::Set<0,2,5>,2>::CvtHelper(const class cv::_InputArray &,const class cv::_OutputArray &,int)'\n> Unsupported depth of input image:\n> 'VDepth::contains(depth)'\n> where\n> 'depth' is 4 (CV_32S)\n"), <traceback object at 0x0000023221307740>)
我构建numpy阵列的方式很好:
import pyautogui
import cv2
import numpy as np
import pickle
import struct
from pprint import pprint as pp
ss = np.array(pyautogui.screenshot())
y,x,color = ss.shape
pixels = []
for a in range(y):
for b in range(x):
for m in ss[a][b]:
pixels.append(struct.pack('i',m))
pixels2 = []
for val in pixels:
pixels2.append(struct.unpack('i',val)[0])
pixels2 = np.array(pixels2).reshape((1080,1920,3))
cv2.imwrite('name.png',pixels2)
如何更快地传输并解决此问题
编辑: 这是发生错误的代码部分,它说深度是4,但我确定图像的尺寸是10801920,3,因为我可以打印它
image = getImg(aSocket,y,x)
SS = cv2.cvtColor(image,cv2.COLOR_RGB2BGR) # error occurs in this line
aSocket.send('image is gotten'.encode('utf-8'))
print('image is gotten')
cv2.imwrite(f'{ip[0]}\{count}.png',SS)
您需要将新形状作为tuple传递给
reshape
,例如arr.reshape((y,x,3))
。如果OpenCV期望的数据类型(每个通道8位,无符号)与它从程序中获得的数据类型(32位有符号整数)不同,则还可能会出现另一个错误,请参见documentation了解cvtColor()
。您可以在创建数组np.array(..., dtype=np.uint8)
时指定数据类型关于性能,在Python
for
中,对大量数据的循环可能会很慢,如果可以避免循环而改用库例程,通常可以使代码大大加快。此外,您应该使用send()
和recv()
读取和写入较大的块。如果您不熟悉socket编程,至少应该查看python文档Socket Programming HOWTO。通过直接将数据解释为字节,可以消除图像数据上的循环。套接字代码遵循链接文档页面中的示例接收器需要知道预期输入的大小
通常,您应该始终使用序列化库,而不是通过网络直接发送原始字节,因为这些库通常处理各种重要细节,如字节顺序、消息大小、数据类型、转换等
相关问题 更多 >
编程相关推荐