我正在尝试从Kinect传感器中存储来自多个源(颜色,深度和红外线)的视频文件。
这是我使用cv2.imshow命令可视化的图像
使用以下代码:
cv2.imshow("ir", ir / 65535.)
cv2.imshow("depth", depth / 4500.)
cv2.imshow("color", color)
ir和深度都是(高度,宽度)
, float32
的数组。颜色是一个大小(高度,宽度,3)
的数组,其中3是RGB频道, uint8
从0-255输入。由于IR和DEPTH的值很大,因此我们需要使用上面的代码将其标准化。该代码给出了上述数字。
现在,我想将一系列图像数组作为视频文件存储。我使用以下代码:
ir_video = cv2.VideoWriter('ir.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), False)
depth_video = cv2.VideoWriter('depth.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), False)
color_video = cv2.VideoWriter('color.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), True)
for ir, depth, color in zip(ir_frames, depth_frames, color_frames):
ir_video.write(ir / 65535.)
depth_video.write(depth / 4500.)
color_video.write(color)
ir_video.release()
depth_video.release()
color_video.release()
颜色视频效果很好,看起来与 cv2.imshow
命令非常相似。但是,IR和深度视频被损坏。所有0KB。
我试图将Fourcc代码更改为 cv2.videowriter_fourcc(*'mp4v')
。这次,IR保存了我可以播放的视频。但这与 cv2.imshow
结果有很大不同。它显示在这里。
我想知道如何与 cv2.imshow
命令正确保存结果。应该使用哪些Fourcc代码?多谢!
I am trying to store video file from multiple sources (color, depth, and infrared) from Kinect sensors.
This is the image that I visualized using cv2.imshow command
using the following code:
cv2.imshow("ir", ir / 65535.)
cv2.imshow("depth", depth / 4500.)
cv2.imshow("color", color)
IR and depth both are array with size of (height, width)
, float32
. Color is an array with size of (height, width, 3)
, where 3 is the RGB channel and uint8
type from 0-255. Since IR and depth's values are large, we need to normalize them using the code above. This code gave the above figures.
Now I want to store a series of image array as a video file. I use the following code:
ir_video = cv2.VideoWriter('ir.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), False)
depth_video = cv2.VideoWriter('depth.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), False)
color_video = cv2.VideoWriter('color.mp4', cv2.VideoWriter_fourcc(*'MP42'), fps, (height, width), True)
for ir, depth, color in zip(ir_frames, depth_frames, color_frames):
ir_video.write(ir / 65535.)
depth_video.write(depth / 4500.)
color_video.write(color)
ir_video.release()
depth_video.release()
color_video.release()
Color video works very well, looks very similar to the cv2.imshow
command. However, IR and depth video are corrupted. All 0kb.
I tried to change the fourcc code to cv2.VideoWriter_fourcc(*'mp4v')
. This time the IR one saved a video that I can play. But it is very different from the cv2.imshow
result. It is shown here.
I'm wondering how I can correctly save the result as with cv2.imshow
command. What fourcc code should be used? Thanks a lot!
发布评论
评论(3)
从OpenCV 4.7.0开始,可以写16位深度视频,请参阅添加了对此的支持。
对于
videoWriter
您必须:cap_ffmpeg
,因为目前似乎仅支持FFMPEG,ffv1
videcapture videocapture (阅读)
请注意,这将打印出“ Videoio/ffmpeg:BGR转换关闭...”之类的警告。
但是,似乎有一些限制,请参见。
该拉的请求还添加了一个单位测试 videoWriter &
videocapture
往返。Starting with OpenCV 4.7.0 it is possible to write 16-bit depth videos, see the pull request which added support for it.
For
VideoWriter
you have to:CAP_FFMPEG
because this only seems to be supported for FFmpeg at the momentFFV1
codec{VIDEOWRITER_PROP_DEPTH, CV_16U, VIDEOWRITER_PROP_IS_COLOR, false}
as paramsFor
VideoCapture
(reading) you have to:CAP_FFMPEG
{CAP_PROP_CONVERT_RGB, false}
as paramsNote that this will print a warning like "VIDEOIO/FFMPEG: BGR conversion turned OFF ..." to the console.
There appear to be some limitations with this though, see the description of the pull request.
That pull request also added a unit test which contains a
VideoWriter
&VideoCapture
round trip.问题注释中提供的解决方案将图像数据从
float32
转换为uint8
,这足以保存视频。但是,由于uint8
仅能表示256个值,因此丢失了很多信息。这也是为什么源数据(IR和深度)为float32
而不是uint8
的原因 - 当颜色images> - 当保存为<时会丢失很多信息。代码> uint8 。因此,我提出了一个解决方案,将视频保存在uint16
格式中,并使用videoWriter
提交了该问题的作者。首先,有必要将值从
float32
转换为uint16
(范围0-65,535)。根据作者的代码,IR映像似乎已经属于该范围,因此只需要投射到uint16
。但是,深度图像必须从其原始范围0-4,500到uint16
范围进行标准化。该代码应放在作者提供的写入
方法之前。@marcono1234 提供了一个想法如何使用
opencv
VideoWriter (since version 4.7.0) but didn't provide the Python code.我发现正确编程的编程并不容易,因此我提供了一个完全有效的示例,可以将其从网络摄像头读取图像,将其转换为单色图像16个深度并保存下来。运行以记录视频并使用键盘字母Q
停止录制。最重要的部分显然是VideoWriter定义。为了使示例完成,您还想以某种方式阅读视频。 Here's again a fully working example of
OpenCV
videocapture 带有单色16位深度视频。请注意,由于
ffv1
编码16位深度单声道视频的编码尚不那么普遍,因此每一个视频播放器都无法播放视频。vlc Media Player
让此讨论支持它,因为版本3.0.18 ,一些改进也可能在释放时出现在版本4.0 中。Solution provided in the question comments converts the image data from
float32
touint8
which is sufficient to save the video properly. However, a lot of information is lost due touint8
only being able to represent 256 values. That is also the reason why the source data (IR and depth) arefloat32
and notuint8
as with the color images - a lot of information would be lost when saved asuint8
. Therefore, I propose a solution that saves the video inuint16
format with theVideoWriter
used by the author of the question.At first, it is necessary to convert the values from
float32
touint16
(range 0-65,535). According to author's code, IR image seems to already fall in that range, so only casting touint16
is necessary. However, depth image has to be normalized from its original range 0-4,500 to theuint16
range. This code should be placed in the for loop provided by author before thewrite
method.@Marcono1234 provided an idea how to save video with
OpenCV
VideoWriter (since version 4.7.0) but didn't provide the Python code. I find it not trivial to program it correctly, so I provide a fully working example of reading an image from your webcam, converting it to monochrome image 16 bits of depth and saving it as such. Run to record the video and use keyboard letterq
to stop recording. The most important part is obviously the VideoWriter definition.To make the example complete, you'd also like to read the video somehow. Here's again a fully working example of
OpenCV
VideoCapture with monochrome 16-bit depth video.Be aware that produced video might not be playable with every video player since
FFV1
encoding of 16-bit depth mono video is not so common yet.VLC media player
had this discussed and supports it since version 3.0.18 and some improvements might also come in version 4.0 when it is released.我使用其他深度摄像头(ORBBEC,ASUS XTION)和AFAIK VIDEOWRITER类的OpenCV类似的项目进行了类似项目的工作,这就是为什么您应该转换为8位的评论中建议的。您可以看一下
I worked on a similar project using other depth cameras (Orbbec, Asus Xtion) and afaik videowriter class of OpenCV does not support 16-bit depth images, that's why as suggested in the comments you should convert to 8 bit. You can take a look here for what I was using to save such a video (It's about using OpenNI2 but the main concept is there).