簡體   English   中英

使用opencv和python從具有可變幀速率的IP攝像機的視頻記錄

[英]Video record from an IP camera with variable frame rate with opencv and python

首先,我想評論一下我要做什么。

我有一台IP攝像機通過帶有以太網電纜的路由器連接到我的網絡( FOSCAM 9800p ),並且我試圖從中嘗試使用RTSP協議錄制視頻。 將來,我的意圖是使用opencv在中間添加一個小的視頻處理程序,但此刻我想進行測試以簡單地記錄下來。

主要問題是相機每秒以可變的幀速率傳送圖像,即有時達到18幀,其他達到22幀,依此類推。 當以固定的每秒幀數錄制視頻時,最終發生的情況是視頻播放速度超過了應有的速度

有點怪異的是,當我使用opencv get(CAP_PROP_FPS)運行時,它返回的值很大,如180000.0

為了嘗試解決此問題,我們要做的是讀取框架並將它們放在隊列中。 從timer.Event()命令的另一個過程中,我們讀取它們,並嘗試以固定的時間間隔在視頻中進行寫入,以獲得固定的幀速率。

代碼如下:

video_capture = cv2.VideoCapture("rtsp://"+user+":"+password+"@"+ip+":"+str(port)+"/videoMain")

if (video_capture.isOpened() == False):
  print("Unable to read camera feed")
  sys.exit()

frame_width = int(video_capture.get(3))
frame_height = int(video_capture.get(4))

video_writer =cv2.VideoWriter(output_filename,cv2.VideoWriter_fourcc(*'MP4V'), fps_to_save, (frame_width,frame_height))
input_buffer = queue.Queue(20)

finished = False

read_frames = 0

def readFile():
    global finished
    global read_frames
    while not finished:
        ret, frame = video_capture.read()
        if not ret:
            finished = True
        while not finished:
            try:
                input_buffer.put_nowait(frame)
                read_frames+=1
                break
            except queue.Full:
                print("queue.Full")
                pass

def processingFile():
    global finished

    written_frames = 0
    repeated_frames = 0

    time_per_frame_elapsed = 0.0

    start_time=time.time()
    ticker = threading.Event()

    while True:
        ticker.wait(time_per_frame-time_per_frame_elapsed)
        time_per_frame_start=time.time()
        try:
            frame = input_buffer.get_nowait()
            video_writer.write(frame)
            writing_time = time.time()
            if written_frames is 0:
                start_time = writing_time
            written_frames += 1
        except queue.Empty:
            if written_frames is not 0:
                video_writer.write(frame)
                writing_time = time.time()
                written_frames += 1
                repeated_frames += 1
        except:
            pass
        total_elapsed_time = time.time() - start_time
        print("total_elapsed_time:{:f}".format(total_elapsed_time))
        if total_elapsed_time>time_to_save_seconds:
          finished = True
          ticker.clear()
          print ("Playback terminated.")
          break
        time_per_frame_elapsed=time.time()-time_per_frame_start
    print("Total readed frames:{:f}".format(read_frames))
    print("Total frames repated:{:f}".format(repeated_frames))
    print("Total frames writed:{:f}".format(written_frames))

tReadFile = threading.Thread(target=readFile)
tProcessingFile = threading.Thread(target=processingFile)

tReadFile.start()
tProcessingFile.start()

tProcessingFile.join()
tReadFile.join()

結果接近我們想要的結果,但有時我們在時代上存在重大差異。 我們正在用大約10秒鍾的短視頻進行測試,並獲得9.8秒鍾的錄制時間。

起初,這似乎不是一個嚴重的問題,但是錯誤是累積性的,也就是說,如果我們增加時間的增加,以便錄制較長時間的視頻,就會遇到更嚴重的問題。

我們想知道如何使用以可變速率傳送幀的攝像機來解決此類視頻記錄問題。 這樣做是個好主意嗎?

在什么時候會產生累積誤差?

從已經非常感謝你!

祝福大家!

我只能說一件事。 以我自己的經驗,OpenCV VideoCapture類在聯機模式下與FFMPEG一起使用(OpenCV使用它來解碼視頻)非常糟糕。 圖像偽影和ffmpeg內部錯誤很多。 但是VideoCapture可以完美地與USB攝像機配合使用。 我使用XSplit Broadcaster解決了從IP攝像機進行在線捕獲的問題。 該軟件包能夠通過物理IP攝像機模擬USB攝像機。 唯一的限制是將相機框架的尺寸調整為640 * 480。 XSplit Broadcaster的基本許可證是完全免費的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM