来自连接到远程机器的相机的 Opencv 流
Opencv stream from a camera connected to a remote machine
我正在 python 中开发一个 wx 应用程序,用于流式传输和显示来自两个不同网络摄像头的视频。这工作正常,但现在我需要在不同的场景中执行此操作,在该场景中,两台摄像机连接在通过网络连接的 运行ning 和 Windows 上的单独机器中。我的应用程序将 运行 在机器 1 上运行。来自摄像头 1 的视频可以使用 opencv 获取并显示在面板上。而且我还想从连接到机器 2 的摄像头 2 获取视频,并将其显示在应用程序中。
有什么办法吗?
VLC 可以通过 RTSP 流式传输捕获设备的图像,请参阅 "Streaming using the GUI" chapter of VLC's "Streaming HowTo"。
然后 OpenCV 的 VideoCapture
可以从 RTSP 流中抓取帧,例如:
std::string address = "rtsp://<username:password>@<ip_address>:<port>";
cv::VideoCapture cap;
if(!cap.open(address))
{
std::cout << "Error opening video stream: " << address << std::endl;
return -1;
}
如果受密码保护,address
类似于 rtsp://127.0.0.1:554
或 rtsp://username:password@127.0.0.1:554
。
我已经使用 websockets 在两台机器之间传输数据。您在机器 1 中抓取图像并将其流式传输到正在侦听特定端口上的连接的机器 2。
机器 1(客户端):
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while(cap.isOpened()):
ret,frame=cap.read()
memfile = StringIO.StringIO()
np.save(memfile, frame)
memfile.seek(0)
data = json.dumps(memfile.read().decode('latin-1'))
clientsocket.sendall(struct.pack("L", len(data))+data)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
机器 2(服务器线程):
self.isRunning = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((self.hostname, self.port))
print 'Socket bind complete'
data = ""
payload_size = struct.calcsize("L")
s.listen(10)
print 'Socket now listening'
while self.isRunning:
conn, addr = s.accept()
while True:
data = conn.recv(4096)
if data:
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:
data += conn.recv(10000)
frame_data = data[:msg_size]
memfile = StringIO.StringIO()
memfile.write(json.loads(frame_data).encode('latin-1'))
memfile.seek(0)
frame = numpy.load(memfile)
ret, jpeg = cv2.imencode('.jpg', frame)
self.jpeg = jpeg
self.connected = True
else:
conn.close()
self.connected = False
break
self.connected = False
注意 json 序列化器,它大大提高了序列化过程的性能,特别是与 pickle 相比,如这个很棒的 article 中所解释的。
可以找到源代码here。
我正在 python 中开发一个 wx 应用程序,用于流式传输和显示来自两个不同网络摄像头的视频。这工作正常,但现在我需要在不同的场景中执行此操作,在该场景中,两台摄像机连接在通过网络连接的 运行ning 和 Windows 上的单独机器中。我的应用程序将 运行 在机器 1 上运行。来自摄像头 1 的视频可以使用 opencv 获取并显示在面板上。而且我还想从连接到机器 2 的摄像头 2 获取视频,并将其显示在应用程序中。
有什么办法吗?
VLC 可以通过 RTSP 流式传输捕获设备的图像,请参阅 "Streaming using the GUI" chapter of VLC's "Streaming HowTo"。
然后 OpenCV 的 VideoCapture
可以从 RTSP 流中抓取帧,例如:
std::string address = "rtsp://<username:password>@<ip_address>:<port>";
cv::VideoCapture cap;
if(!cap.open(address))
{
std::cout << "Error opening video stream: " << address << std::endl;
return -1;
}
如果受密码保护,address
类似于 rtsp://127.0.0.1:554
或 rtsp://username:password@127.0.0.1:554
。
我已经使用 websockets 在两台机器之间传输数据。您在机器 1 中抓取图像并将其流式传输到正在侦听特定端口上的连接的机器 2。
机器 1(客户端):
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while(cap.isOpened()):
ret,frame=cap.read()
memfile = StringIO.StringIO()
np.save(memfile, frame)
memfile.seek(0)
data = json.dumps(memfile.read().decode('latin-1'))
clientsocket.sendall(struct.pack("L", len(data))+data)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
机器 2(服务器线程):
self.isRunning = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((self.hostname, self.port))
print 'Socket bind complete'
data = ""
payload_size = struct.calcsize("L")
s.listen(10)
print 'Socket now listening'
while self.isRunning:
conn, addr = s.accept()
while True:
data = conn.recv(4096)
if data:
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:
data += conn.recv(10000)
frame_data = data[:msg_size]
memfile = StringIO.StringIO()
memfile.write(json.loads(frame_data).encode('latin-1'))
memfile.seek(0)
frame = numpy.load(memfile)
ret, jpeg = cv2.imencode('.jpg', frame)
self.jpeg = jpeg
self.connected = True
else:
conn.close()
self.connected = False
break
self.connected = False
注意 json 序列化器,它大大提高了序列化过程的性能,特别是与 pickle 相比,如这个很棒的 article 中所解释的。
可以找到源代码here。