gpt4 book ai didi

opencv - 从 Raspivid 到 OpenCV 的 Netcat H.264 视频

转载 作者:太空宇宙 更新时间:2023-11-03 22:09:22 26 4
gpt4 key购买 nike

目标是通过网络将来自 Raspberry Pi (Raspivid/H.264) 的视频流式传输到笔记本电脑上运行的 OpenCV 应用程序中。

打开的CV抓取如下(C++):

cv::VideoCapture cap;
cap.open("cam_1"); // cam_1 is a FIFO

cv::Mat frame;

while(1){
cap >> frame;
cv::imshow("", frame);
cv::waitKey(10);
}

FIFO 流创建如下:

mkfifo cam_1

一旦 OpenCV 程序运行,netcat 监听器就会启动:

ncat --recv-only --keep-open --verbose --listen 5001 > cam_1

一旦 netcat 监听器在笔记本电脑上运行,流就会从 Raspberry Pi 开始

raspivid --verbose --nopreview -b 2000000 --timeout 0 -o - | ncat 192.168.LAPTOP.IP 5001

或者,出于调试目的,可以将笔记本电脑上的本地文件传输到 netcat:

cat video.h264 | nc 192.168.LAPTOP.IP 5001 

两者都给出以下错误:

Unable to stop the stream: Inappropriate ioctl for device (ERROR)icvOpenAVI_XINE(): Unable to initialize video driver.

有趣的是,如果我在膝上型电脑上启动 Netcat 监听器,然后使用 CTRL+C 将其终止,然后在开始视频流之前再次启动它,使用任何一种方法...然后视频播放正确

我不明白为什么启动 netcat 监听器然后将其杀死,然后再次启动会产生影响或影响是什么。我考虑过可能需要在播放视频之前将 EOF 或 BOF 回显到 FIFO 中,但我不确定该语法是什么。

我已经尝试过所有版本的 Netcat。

最佳答案

我刚刚使用以下 https://stackoverflow.com/a/48675107/2355051 解决了这个问题

我最终改编了这个 picamera python recipe

在树莓派上:(createStream.py)

import io
import socket
import struct
import time
import picamera

# Connect a client socket to my_server:8000 (change my_server to the
# hostname of your server)
client_socket = socket.socket()
client_socket.connect(('10.0.0.3', 777))

# Make a file-like object out of the connection
connection = client_socket.makefile('wb')
try:
with picamera.PiCamera() as camera:
camera.resolution = (1024, 768)
# Start a preview and let the camera warm up for 2 seconds
camera.start_preview()
time.sleep(2)

# Note the start time and construct a stream to hold image data
# temporarily (we could write it directly to connection but in this
# case we want to find out the size of each capture first to keep
# our protocol simple)
start = time.time()
stream = io.BytesIO()
for foo in camera.capture_continuous(stream, 'jpeg', use_video_port=True):
# Write the length of the capture to the stream and flush to
# ensure it actually gets sent
connection.write(struct.pack('<L', stream.tell()))
connection.flush()

# Rewind the stream and send the image data over the wire
stream.seek(0)
connection.write(stream.read())

# Reset the stream for the next capture
stream.seek(0)
stream.truncate()
# Write a length of zero to the stream to signal we're done
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()

在处理流的机器上:(processStream.py)

import io
import socket
import struct
import cv2
import numpy as np

# Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means
# all interfaces)
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 777))
server_socket.listen(0)

# Accept a single connection and make a file-like object out of it
connection = server_socket.accept()[0].makefile('rb')
try:
while True:
# Read the length of the image as a 32-bit unsigned int. If the
# length is zero, quit the loop
image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
if not image_len:
break
# Construct a stream to hold the image data and read the image
# data from the connection
image_stream = io.BytesIO()
image_stream.write(connection.read(image_len))
# Rewind the stream, open it as an image with opencv and do some
# processing on it
image_stream.seek(0)
image = Image.open(image_stream)

data = np.fromstring(image_stream.getvalue(), dtype=np.uint8)
imagedisp = cv2.imdecode(data, 1)

cv2.imshow("Frame",imagedisp)
cv2.waitKey(1) #imshow will not output an image if you do not use waitKey
cv2.destroyAllWindows() #cleanup windows
finally:
connection.close()
server_socket.close()

此解决方案与我在原始问题中引用的视频有相似的结果。较大分辨率的帧会增加提要的延迟,但这对于我的应用程序而言是可以容忍的。

首先需要运行processStream.py,然后在树莓派上执行createStream.py。如果这不起作用,请使用 sudo

执行 python 脚本

关于opencv - 从 Raspivid 到 OpenCV 的 Netcat H.264 视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45924220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com