opencv读取错误:[h264@0x8f915e0]解码MB 53 20时出错,字节流-7

xxls0lw8  于 2022-11-15  发布在  其他
关注(0)|答案(5)|浏览(343)

我的配置:

ubuntu 16.04
  opencv 3.3.1
  gcc version 5.4.0 20160609
  ffmpeg version 3.4.2-1~16.04.york0

我用以下代码构建了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 ..

并使用这些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.."

每次阅读大约50帧后,都会给予如下错误:

[h264 @ 0x8f915e0] error while decoding MB 53 20, bytestream -7

然后就再也抓不到什么了,奇怪的是:

1,comment doSomething() or
2,keep doSomething() and recording the stream from same IPCamera,then run
  code against recorded video

这两种情况下,代码工作正常,谁能告诉如何解决这个问题?2提前感谢!

ukxgm1gy

ukxgm1gy1#

让我们首先看一个简单的阅读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()

frame值是每一帧的图像,但是如果你在while代码块中为每一帧添加识别操作,比如添加Tensorflow来识别其中的小动物,就会报告这样的错误,while循环也会因为这个异常而中断。

[h264 @ 0x55abeda05080] left block unavailable for requested intra mode
[h264 @ 0x55abeda05080] error while decoding MB 0 14, bytestream 104435

事实证明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()

Receive用作接收数据的线程,Display显示为简单进程。

eyh26e7m

eyh26e7m2#

我使用的是海康威视ip poe相机,在ubuntu16.04的系统上使用opencv3.4和python3。相机是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
w1e3prcc

w1e3prcc3#

这仅适用于视频流:

如果返回值为False,您只需再次初始化cv2.VideoCapture。:)
对我有用。

vs = cv2.VideoCapture("rtsp://bla:bla@192.168.x.x")
while True:
    ret,frame = vs.read()
    if not(ret):
        st = time.time()
        vs = cv2.VideoCapture("rtsp://bla:bla@192.168.x.x")
        print("tot time lost due to reinitialization : ",time.time()-st)
        continue

    cv2.imshow("Current frame", frame)
    cv2.waitKey(0)
ssm49v7z

ssm49v7z4#

我一直面临着这个问题,现在我刚刚解决了它。
(Note:我正在使用python3)
我怀疑这与时间有关,因为在连续的capture.read()之间进行昂贵的操作时会出现这种错误。
此外,问题出现时,我流从我的网络摄像头(其中使用H264编码)和没有问题时,使用我的笔记本电脑摄像头。
因此,对我来说有效的解决方案是使用多线程,使用python的“线程”模块,一个线程流和其他进程,同时正确管理线程锁,这样就不会发生读/写冲突。

ozxc1zmp

ozxc1zmp5#

我有同样的问题后,4天的研究,最后我解决了这个问题很容易的代码:就试一次

for(;;) {
        if(!vcap.read(image)) {
            std::cout << "No frame" << std::endl;
            cv::waitKey();
        }
        cv::imshow("Output Window", image);
        if(cv::waitKey(1) >= 0) break;
    }

相关问题