【问题标题】:OpenCV video write to file works but video is blankOpenCV视频写入文件有效,但视频为空白
【发布时间】:2019-01-01 17:34:27
【问题描述】:

我正在使用 opencv 进行一些神经风格传输技巧,但我无法将视频保存到文件中。该文件已创建,但只有 6 kb 大。

from imutils.video import VideoStream
from imutils import paths
import itertools
import argparse
import imutils
import time
import cv2
import numpy as np

ap = argparse.ArgumentParser()
ap.add_argument("-m", "--models", required=True,
    help="path to directory containing neural style transfer models")
args = vars(ap.parse_args())


modelPaths = paths.list_files(args["models"], validExts=(".t7",))
modelPaths = sorted(list(modelPaths))


models = list(zip(range(0, len(modelPaths)), (modelPaths)))

modelIter = itertools.cycle(models)
(modelID, modelPath) = next(modelIter)


print("[INFO] loading style transfer model...")
net = cv2.dnn.readNetFromTorch(modelPath)


print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)
print("[INFO] {}. {}".format(modelID + 1, modelPath))



out = cv2.VideoWriter('output2.avi', cv2.VideoWriter_fourcc(*'XVID'), 5, (451, 600))
while True:

    frame = vs.read()




    frame = imutils.resize(frame, width=600)
    orig = frame.copy()
    (h, w) = frame.shape[:2]


    blob = cv2.dnn.blobFromImage(frame, 1.0, (w, h),
        (103.939, 116.779, 123.680), swapRB=False, crop=False)
    net.setInput(blob)
    output = net.forward()


    output = output.reshape((3, output.shape[2], output.shape[3]))
    output[0] += 103.939
    output[1] += 116.779
    output[2] += 123.680
    output /= 255.0
    output = output.transpose(1, 2, 0)

    out.write(np.uint8(output))

    cv2.imshow("Input", frame)
    cv2.imshow("Output", output)
    key = cv2.waitKey(1) & 0xFF

    if key == ord("n"):

        (modelID, modelPath) = next(modelIter)
        print("[INFO] {}. {}".format(modelID + 1, modelPath))
        net = cv2.dnn.readNetFromTorch(modelPath)
        print(frame.shape)

    elif key == ord("q"):
        break


cv2.destroyAllWindows()
vs.stop()

主要的事情发生在:

out = cv2.VideoWriter('output2.avi', cv2.VideoWriter_fourcc(*'XVID'), 5, (450, 600))
output = net.forward() # which computes the neural styled output image

为了将输出/帧保存到文件,我做了:

out.write(np.uint8(output))

关于为什么我的代码不起作用的任何想法?我尝试了许多编解码器和文件类型组合,但我认为问题不存在。大家觉得可能是次元吗? (我现在有 450、600,因为我打印了 output.shape,它返回了 450,600,3,所以我认为 450 x 600 听起来不错)。

【问题讨论】:

  • 如果你在视频中写np.uint8(output),那么你应该imshow同样的事情。我看到output /= 255.0,所以我猜输出是一个浮点数组,其值在 [0.0, 1.0] 范围内。将其转换为 uint8 会将其减少到仅 0 和 1。但是,imshow(根据文档)会将浮点图像转换并缩放回 0-255 范围。
  • @DanMašek 是正确的。你可以阅读更多关于他描述的内容here
  • 确保您的应用程序可以访问 opencv_ffmpeg dll(或共享库?)

标签: python opencv conv-neural-network codec


【解决方案1】:

@Dan Mašek 的评论可能是正确的。你可以阅读更多关于它的信息here。为了完整起见,您可以通过以下方式修复它:

  1. out.write(np.uint8(output)) 更改为out.write(np.uint8(output * 255))

  1. 评论output /= 255.0并将cv2.imshow("Output", output)更改为cv2.imshow("Output", output / 255.)

您应该根据您是否希望 output 位于 (1) [0., 1.] 或 (2) [0, 255] 范围内来选择解决方案。

【讨论】:

  • 由于output 仅用于编写视频或显示图像,我想说缩放在显示的代码中绝对没用。因此,我建议使用方法#3——放弃output /= 255.0 并将其替换为output = np.uint8(output)。然后你可以将 same 图像传递给writeimshow (我假设显示它以及写作的原因是能够准确地看到你写的是什么)。无论如何,即使 OP 懒得回应,也要为你写一个答案 +1...
  • 很抱歉,我没有看到此回复。我明天早上第一件事就试试看。
猜你喜欢
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2015-06-01
  • 2021-04-12
相关资源
最近更新 更多