OpenCV Video Write-out Size is Reduced - python

I am trying to combine frames into a video using openCV, using the following codes. However, the total size of frames in png format is over 500 megabytes, yet the output video is only 360 kilobytes.
How can I write out the video without any compression?
#setting fourcc
fourcc = cv2.VideoWriter_fourcc(*'XVID')
#creating the writer object
writer=cv2.VideoWriter('Screen1.avi', fourcc, 30, (unitWidth, unitHeight), True)
#writing out the frames into video
for i in range(Frames):
img=cv2.imread('./Screen1/frame'+str(i)+'.png')
writer.write(img)
writer.release()

If you are worrying about video quality, try a lossless codec like the Huffman Lossless Codec.
fourcc = cv2.VideoWriter_fourcc(*'HFYU')
Or search for any other lossless codec.
If you want absolutely no compression at all, you can try fourcc = 0, which will output every frame raw and result in very large file size.

Related

Opencv saving empty video Python

I am facing a problem in recording a video from camera. I am using python and opencv to do so. I have my images in QImage format, I convert them to numpy array in order to display to stream it when video capturing of the cam (using VideoCapture of opencv), everything works fine.
When I try to record a video and save it in the folder (using VideoWriter_fourcc of opencv), I get no errors but I get an empty video. I did a lot of searching to find the problem but I couldn't.
Here's the code that I use to record a video:
import cv2
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
#img is a numpy array
videoWriter = cv2.VideoWriter('video.avi', fourcc, 20, (img.shape[0],img.shape[1]))
while True:
videoWriter.write(img)
videoWriter.release()
I tried to change the Framerate, the frameSize, the extension of the video and the code of codec but nothing worked.
I am so desperate. I appreciate all and every help and suggestion I can get.
Thank you
The issue is that you mixed up width and height as you passed them to VideoWriter.
VideoWriter wants (width, height) for the frameSize argument.
Note that width = img.shape[1] and height = img.shape[0]
Giving VideoWriter a, say, 1920x1080 frame to write, while having promised 1080x1920 frames in the constructor, will fail, but silently.

How can I get the .avi file to work correctly after adding audio to it?

Using cv2, I make a bunch of jpgs out of an mp4 file:
vidcap = cv2.VideoCapture(inp_file)
success,image = vidcap.read()
cv2.imwrite("raw_frames/frame%d.jpg"%count,image)
success,image = vidcap.read()
count+=1
I then do a bunch of operations on all those jpgs and store them in another folder. Then I go through all of those and create an avi out of them:
img = Image.open(file)
width,height = img.size
frameSize = (width,height)
outfile = inp_file.split(".")[0] + '_asc'
out = cv2.VideoWriter(outfile+'.avi',cv2.VideoWriter_fourcc(*'DIVX'),ffps,frameSize)
path = "rendered_frames"
for img_i in range(len(all_images)):
img = cv2.imread(path+"/rf_"+str(img_i)+".jpg")
out.write(img)
print("\tVideo complete!")
out.release()
Then I take that video and try to add the audio from the original mp4 file back to it, using moviepy:
def combine_audio(vidname,audname,outname,fps):
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
my_clip = VideoFileClip(vidname)
audio_background = AudioFileClip(audname)
final_clip = my_clip.set_audio(audio_background)
final_clip.write_videofile(outname,fps=fps,codec='rawvideo')
combine_audio(outfile+'.avi',inp_file,outfile+"ii.avi",ffps)
However, there seems to be a problem with the codec. Under the current conditions, their skin turns purple, purple things turn red, white things stay pretty white etc..
Note that this happens when I add the audio back to them. Before adding audio to the video from cv2, it is perfect.
Here is a reference for what is happening now
Original:
After rendering:
I've tried some other values in cv2 and moviepy but no success.
I tried creating an mp4 instead with MP4V instead of DIVX with cv2.VideoWriter() and some mp4 codec in the audio function, but there is way too much compression for how detailed the video needs to be for what I am doing.
From moviepy's documentation it says that you could leave the codec field blank for an .avi but that causes an error.
Some additional information:
After making the video with cv with fourcc 'DIVX' (pre audio) VLC media player says the codec of the video is MPEG-4 (FMP4).
When passing 'FMP4' as the codec for moviepy, it doesn't recognize it.

writing a video without any loss in data or bitrate - opencv (python)

I am trying to write a video file without any loss in OpenCV, but so far any codec that I have selected from fourcc codec lists somehow results in loss of data.
regarding the recording parameters I am using:
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
used these codecs so far but they either to compression or upsize video bit rate
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
fourcc = cv2.VideoWriter_fourcc(*'RGBA')
fourcc = cv2.VideoWriter_fourcc(*'x265')
fourcc = cv2.VideoWriter_fourcc('H','2','6','4')
my video writer function is:
writer= cv2.VideoWriter(out_dest, fourcc, fps, (width,height))
Just to be clear, I do not want any sort of compression for the output video.
I also use
vid_format = int(cap.get(cv2.CAP_PROP_FOURCC))
to get the output video bit rate and compare it to the original video.
I also found someone on GitHub using skvideo but wasn't able to perform the same code
https://gist.github.com/docPhil99/a612c355cd31e69a0d3a6d2f87bfde8b
as it kept showing an extension error and couldn't find proper documentation on how to use it!
Thank you in advance
An Update on the topic:
the final output writer codec will be used as the video writer for BGR to RGB conversion in OpenCV, if you have any other ideas or suggestions that can do the job, I'm all ears!
If all you need to do is to get RGB data out of raw AVI file and feed the RGB frame data with MediaPipe, there is no need for intermediate file to store RGB data because FFmpeg can convert the pixel format on the fly by specifying output -pix_fmt rgb24 option.
To do this, you can try my ffmpegio package to load the data. My package is designed for your use case to remove the need to set up FFmpeg call. To install:
pip install ffmpegio
You also need FFmpeg in the system.
Then video.read() loads the video data:
import ffmpegio
fs, I = ffmpegio.video.read('datafile.avi',pix_fmt='rgb24')
# fs = framerate
# I = 250x480x640x3 numpy array containing RGB video data
If you don't want to read all 250 frames at once, you can use the stream interface to work on X number of frames at a time:
with ffmpegio.open('datafile.avi','rv', blocksize=25, pix_fmt='rgb24') as f:
for I in f: # loops 10 times, 25 frames at a time
# I = 25x480x640x3 numpy array

List all supported codecs/fourcc tags on Raspberry Pi 4 using python, opencv

This is my code for recording videos on Raspberry Pi 4 running Raspbian Buster:
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
writer = cv2.VideoWriter(tempVideo.path, fourcc, framerate, resolution, True)
writer.write(frame)
However, no matter what codec I try, I keep getting errors like:
OpenCV: FFMPEG: tag 0x47504a4d/'MJPG' is not supported with codec id 7 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
Setting fourcc = 1 also did not help. Here is what I see:
OpenCV: FFMPEG: tag 0xffffffff/'????' is not found (format 'mp4 / MP4 (MPEG-4 Part 14)'
Is there a way to list all the supported codecs and their tags?
Here is the link with all fourcc codecs.
http://www.fourcc.org/codecs.php
Some codecs don't exist there, but in your case, it is not an error it is just a fallback, so your code is running anyway and in the output you will get your mp4 file.
If you don't like how it looks just use this
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
or
fourcc = 0x00000021
It's not an exact answer to the question, but what eventually helped me is cv2.getBuildInformation() is an answer. It shows what video formats are supported by particular build of opencv.

Can't write and save a video file using OpenCV and Python

I'm trying to process frames from a video stream, and it as a new video.
This is what I'm doing :
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('Videos/output.mp4',fourcc, fps, (1080,1080))
I keep getting :
OpenCV: FFMPEG: tag 0x44495658/'XVID' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'
I think I'm using the wrong fourcc value... Which one should I use ? I've been trying a lot of them.
I'm using Ubuntu 16.04, Python 2.7.11 and OpenCV 3.1.0
Define the codec and create VideoWriter object like this
fourcc = cv2.VideoWriter_fourcc(*'MPEG')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
For Windows users
I am using OpenCV 2 with Python 3.6, on Windows 10.
The 'XVID' codec, along with producing a .avi file, seems to be the most generic solution (if not the only one that works).
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('test.avi', fourcc, 60, (320, 240))
In addition, only BGR can be directly written with such a VideoWriter declaration. Don't try to write gray frames: the output would be empty.
The problem that you are having is that you are trying to export the frames in XVID format but the name of your output file is ending with .mp4. You should change the export format to MP4V or the name of your output file to .avi.
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('Videos/output.mp4',fourcc, fps, (1080,1080))
alternative
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('Videos/output.avi',fourcc, fps, (1080,1080))
here you can find more information about the video codecs
The size of the frame(width,height) you are giving, should match the size of the frame you want to save.
so
fw = int(cap.get(3))
fh = int(cap.get(4))
print("w,h",fw,fh)
out = cv2.VideoWriter('fb1.avi',cv2.VideoWriter_fourcc('X','V','I','D'), fps, (fw,fh))
If you want to save video by opencv in mp4 format, let
Follow this link:
you should replace:
fourcc = cv2.VideoWriter_fourcc(*'XVID')
by:
fourcc = cv2.VideoWriter_fourcc(*'FMP4')
I tried and succeeded.
I had the same problem. With me, it turned out that I had switched the height and width of the video, so the frame dimensions did not match the video specifications and as a result nothing was written. Make sure they match exactly.
Also, OpenCV seems to give that same warning if the file extension does not match the codec used. Specifically, it wants .avi for the XVID codec.
I wanted to save as a .mp4, and using *"mp4v" turned out to be the right code, on Linux at least.
Check the example below
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))
Install K-Lite Mega Codec Pack: https://filehippo.com/download_klite_mega_codec/
This error occurs because some codecs are not available by default in Windows media player. So by installing this software, the video works fine with same code.
If you are using linux try this
fourcc = 0x00000021
out = cv2.VideoWriter('Videos/output.mp4',fourcc, fps, (1080,1080))
In my case, i use:
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
video = cv2.VideoWriter(video_name, fourcc, FPS, (width,height))
and this work :>
On a mac
writer = cv2.VideoWriter('mysupervideo.mp4', cv2.VideoWriter.fourcc(*'mp4v'), 20, (width, height))
Works better

Categories