Ale*_*uya 7 opencv ffmpeg decode ip-camera
我的配置:
ubuntu 16.04
opencv 3.3.1
gcc version 5.4.0 20160609
ffmpeg version 3.4.2-1~16.04.york0
Run Code Online (Sandbox Code Playgroud)
我用以下方法构建了 opencv:
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D PYTHON_EXECUTABLE=$(which python) -D OPENCV_EXTRA_MODULES_PATH=/home/xxx/opencv_contrib/modules -D WITH_QT=ON -D WITH_OPENGL=ON -D WITH_IPP=ON -D WITH_OPENNI2=ON -D WITH_V4L=ON -D WITH_FFMPEG=ON -D WITH_GSTREAMER=OFF -D WITH_OPENMP=ON -D WITH_VTK=ON -D BUILD_opencv_java=OFF -D BUILD_opencv_python3=OFF -D WITH_CUDA=ON -D ENABLE_FAST_MATH=1 -D WITH_NVCUVID=ON -D CUDA_FAST_MATH=ON -D BUILD_opencv_cnn_3dobj=OFF -D FORCE_VTK=ON -D WITH_CUBLAS=ON -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES" -D WITH_GDAL=ON -D WITH_XINE=ON -D BUILD_EXAMPLES=OFF -D BUILD_DOCS=ON -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D BUILD_opencv_dnn=OFF -D BUILD_PROTOBUF=OFF -D opencv_dnn_BUILD_TORCH_IMPORTER=OFF -D opencv_dnn_PERF_CAFFE=OFF -D opencv_dnn_PERF_CLCAFFE=OFF -DBUILD_opencv_dnn_modern=OFF -D CUDA_ARCH_BIN=6.1 ..
Run Code Online (Sandbox Code Playgroud)
并使用这些 python 代码读取和显示:
import cv2
from com.xxx.cv.core.Image import Image
capture=cv2.VideoCapture("rtsp://192.168.10.184:554/mpeg4?username=xxx&password=yyy")
while True:
grabbed,content=capture.read()
if grabbed:
Image(content).show()
doSomething()
else:
print "nothing grabbed.."
Run Code Online (Sandbox Code Playgroud)
每次读取大约 50 帧后,都会出现如下错误:
[h264 @ 0x8f915e0] error while decoding MB 53 20, bytestream -7
Run Code Online (Sandbox Code Playgroud)
那么什么都不能再抓了,奇怪的是:
1,comment doSomething() or
2,keep doSomething() and recording the stream from same IPCamera,then run
code against recorded video
Run Code Online (Sandbox Code Playgroud)
这两种情况,代码工作正常,谁能告诉如何解决这个问题?提前致谢!
小智 17
我们先来看一个简单的读取RTSP的示例程序
import cv2
cap=cv2.VideoCapture("rtsp://admin:admin_123@172.0.0.0")
ret,frame = cap.read()
while ret:
ret,frame = cap.read()
cv2.imshow("frame",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
cap.release()
Run Code Online (Sandbox Code Playgroud)
帧值是每一帧的图像。但如果在while代码块中添加对每一帧的识别操作,比如添加Tensorflow来识别其中的小动物,就会报这样的错误,并且while循环会因为这个异常而中断。
[h264 @ 0x55abeda05080] left block unavailable for requested intra mode
[h264 @ 0x55abeda05080] error while decoding MB 0 14, bytestream 104435
Run Code Online (Sandbox Code Playgroud)
原来FFMPEG Lib不支持rtsp协议中的H264视频,所以解决办法是写两个不同的线程分别处理每一帧的图像,然后另一个线程处理每一帧的图像。
思路是这样的:使用队列,采用先进先出策略,在一个线程中开始接收数据,在另一个线程中处理一帧一帧的数据
解决方案代码如下:
import cv2
import queue
import time
import threading
q=queue.Queue()
def Receive():
print("start Reveive")
cap = cv2.VideoCapture("rtsp://admin:admin_123@172.0.0.0")
ret, frame = cap.read()
q.put(frame)
while ret:
ret, frame = cap.read()
q.put(frame)
def Display():
print("Start Displaying")
while True:
if q.empty() !=True:
frame=q.get()
cv2.imshow("frame1", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if __name__=='__main__':
p1=threading.Thread(target=Receive)
p2 = threading.Thread(target=Display)
p1.start()
p2.start()
Run Code Online (Sandbox Code Playgroud)
Receive作为接收数据的线程,Display作为简单的进程进行显示。
小智 7
我在具有 ubuntu 16.04 的系统上使用带有 opencv 3.4 和 python3 的 hikvision ip poe 摄像机。相机以 h264 格式进行流式传输。
使用 RTSP,我使用 opencv 的视频捕获从摄像机进行流式传输,有时我遇到相同的问题“[h264 @ 0x8f915e0] 解码 MB 43 20,字节流 -4 时出错”
当您在进一步处理中使用捕获的帧并且在 rtsp 仍在流式传输时在管道中创建延迟时,就会出现此问题。
解决方案是将捕获放在不同的线程上,并将您使用的帧放在另一个线程上。
您将在同一进程中使用 python 多线程进行类似的操作:
#thread1
global frame
frame = None
cap = cv2.VideoCapture("rtsp://bla:bla@192.168.x.x")
while True:
ret,frame = cap.read()
#thread2
cv2.imshow("Current frame", frame)
cv2.waitKey(0)
# you can pass now the frame to your application for further processing
Run Code Online (Sandbox Code Playgroud)
我遇到了这个问题,现在刚刚解决了。
(注:我使用的是python3)
我怀疑这与时间有关,因为在连续的capture.read(). 你的问题让我确定了这一点。
另外,当我从网络摄像头(使用 H264 编码)进行流传输时会出现问题,而使用笔记本电脑摄像头则没有问题。
因此,对我有用的解决方案是使用多线程和 python“线程”模块。一个线程进行流处理,其他进程进行处理,同时正确管理线程锁,因此不会发生读/写冲突。