Create an avi video with opencv and python on a mac - python

this is my situation:
Im trying to use opencv to generate an avi movie from some png images
Using OpenCV 2.3.4, Python 2.7 on Mac OSX
The program ends with no error, generates the file. But is not playable.
Here is the code:
import cv
def make_video(nFrames):
isColor = 1
fps = 1 #25 or 30, frames per second
size = cv.GetSize(cv.LoadImage("canvas.png"))
writer=cv.CreateVideoWriter("~/Documents/Workspace/Brief/video.avi",cv.CV_FOURCC('D','I','V','X'), fps,size,isColor)
#-----------------------------#Writing the video file:#-----------------------------
for i in range(nFrames):
img = cv.LoadImage("canvas%d.png"%i) #specify filename and the extension
cv.WriteFrame(writer,img) # add the frame to the video

You are trying to use the DIVX codec on a platform that has neither a native encoder nor decoder for it. This won't work. Try using something simpler, like MJPG (Motion JPEG), instead.

I found a list of codecs that are native on Mac OSX:
http://opencv.willowgarage.com/wiki/QuickTimeCodecs
Now, it works very fine.

Related

Python OpenCV video format play in browser

I'm trying to create a video from a sequence of images and display it in a browser but from some weird reason no matter what codec or file format I use I get the following error:
No video with supported format and mime type found
Here is my code:
ready_images = []
import cv2
for img in videos['Images']:
image = cv2.imread(img.fileName)
ready_images.append(image)
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
video_name = videos['Images'][0].gifLocationPath + "//" + videos['Name']
frame = cv2.imread(videos['Images'][0].fileName)
height, width, layers = frame.shape
video_name = video_name[:-4]+".mp4"
video = cv2.VideoWriter(video_name, fourcc, 20.0, (width, height))
for image in ready_images:
video.write(image)
cv2.destroyAllWindows()
video.release()
The funny thing is that in Firefox or Chrome the videos are not working but in Edge... they actually work.
I don't want to use FFMPEG and would prefer to make it work with OpenCV.
If any of you guys know what format of video (I know the web formats are webm, ogg, mp4) or codec I should use for this, please, just let me know.
Thanks.
MP4V or MPEG-4 part 2 is not supported by most browsers, you may want to try H.264 (MPEG-4 part 10) instead.
To do that, change:
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
to
fourcc = cv2.VideoWriter_fourcc(*'H264')
If you are using Python 3, use the following hexadecimal code instead (there seems to be a bug when using the four bytes notation):
fourcc = 0x00000021
Run the script and you will likely get the following error message:
Failed to load OpenH264 library: openh264-1.6.0-win32msvc.dll
Please check environment and/or download library: https://github.com/cisco/openh264/releases
You need to do as the message says and download the required library from github and place it somewhere accessible by your PATH.
Using H.264 compression you will also get a smaller file which is better for Web.
I know the question is old but for everyone that is looking for a compatible codec + container for web browser :
VP8 or VP80 is a compatible encoder
cv2.VideoWriter_fourcc('V','P','8','0')
I used it with .webM as a container.
Native WebM support by Mozilla Firefox,[7][8] Opera,[9][10] and Google Chrome[11] was announced at the 2010 Google I/O conference
https://en.wikipedia.org/wiki/WebM
it worked like a charm and with pretty good performance even though
for some reason I got this error when creating videoWriter objects :
OpenCV: FFMPEG: tag 0x30385056/'VP80' is not supported with codec id 139 and format 'webm / WebM'
Get .webm suffix audio file.
fourcc = cv2.VideoWriter_fourcc(*'vp80')
video_writer = cv2.VideoWriter('file.webm', fourcc, 20, (640, 480))
In html:
<body>
<video width="320" height="240" controls>
<source src="file.webm" type="video/webm">
</video>
</body>
It works on centos7 and Windows10.
I print the all available mp4 codecs by fourcc=-1.
After that I check codecs which are useful for me. I see there avc1.
So I write the code like:
fourcc = cv2.VideoWriter_fourcc(*'avc1')
When print the codes, you also see they are lowercase.

Opencv VideoCapture always returns false on Heroku

I'm using the following code to open a video stream:
import cv2
video = cv2.VideoCapture()
video.open("some_m3u8_link")
success, image = video.read()
However, even if the code works as intended locally, on Heroku success is always false.
I'm using cedar-14 stack with the following buildpacks:
heroku/python
https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
(I tried several buildpack options for ffmpeg)
Running ffmpeg --version on heroku instance will return ffmpeg version 4.0-static https://johnvansickle.com/ffmpeg/
Is there any setting/configuration I missed in order to make it work on deployment? Thank you!
Later edit: I tried several links for "some_m3u8_link" including from twitch and other streaming services (including traffic streaming li
An example for reproducing:
python -c "import cv2; video=cv2.VideoCapture(); video.open('https://hddn01.skylinewebcams.com/live.m3u8?a=5tm6kfqrhqbpblan9j5d4bmua4'); success, image = video.read(); print(success)"
Returns True on local machine and False on Heroku.
(the link is taken from here)
You can use pafy module with cv2
-try opencv3 if its not working with cv2
import cv2, pafy
url = "Some url to stream"
video = pafy.new(url)
best = video.getbest(preftype="webm")
video=cv2.VideoCapture(best.url)
pafyPYPI
You can try this:
import cv2
video = cv2.VideoCapture("some_m3u8_link")
success, image = video.read()
Specifying the mode to open it might work.
video.open("some_m3u8_link", "r")
If that doesn't work then specifying the file extension might help.
You might also need to make a variable equal to the function
Ex:
""" replace .mp4 with the applicable file type,
I don't know if you need to specify file mode"""
import cv2
video = cv2.VideoCapture()
video = video.open("some_m3u8_link.mp4")
success, image = video.read()
If this doesn't work then I am out of ideas.

python reading a video

I am using Python 2.7.11 and OpenCV 2.4.9. I cannot read a video by using cv2.imread() or cv2.VideoCapture().
import cv2
cap = cv2.VideoCapture('cam.avi')
print ("open = ",cap.isOpened())
OR
import cv2
cap = cv2.imread('cam.avi')
print ("open = ",cap.isOpened())
It will return false.
I don't know why. I am sure that the cam.avi is here.
imread() does not support reading from video files directly.
See also the documentation of OpenCV.
If you want to read a video with imread you will first have to convert it to single images, either via a serperate program (ffmpeg comes to mind) or using OpenCV and store the images in memory.
Try providing full path to video, like:
import cv2
cap = cv2.VideoCapture(r'C:\Users\e01069\Downloads\drop.avi')
print ("open = ",cap.isOpened())
If you run following in your same file, you would know that python is looking for your file on some different location.
import os
print os.path.abspath(__file__) #this is your current working directory
Note: .imread wouldn't work this way.

Unable to write video using python and opencv2 on mac os x

I am using mac os x 1.7.5 with python 2.7.5_1 and opencv 2.4.4_0 installed via macports. I seem to have all the latest dependent ports.
In my code, the cv2.Videowriter() is successfully created and opened which produces a 6kb .avi file but videoFile.write(img0) doesn't write anything into that file. I really am not able to figure out why the video stream isn't written to the file. Any insights?
My code is as follows:
import cv2
import cv
cv2.namedWindow("Original")
cap0 = cv2.VideoCapture(0)
codec = cv.CV_FOURCC('D','I','V','X')
print codec
videoFile = cv2.VideoWriter();
videoFile.open('video.avi', codec, 25, (640, 480),1)
key = -1
while(key < 0):
success0, img0 = cap0.read()
cv2.imshow("Original", img0)
videoFile.write(img0)
key = cv2.waitKey(1)
cv2.destroyAllWindows()
I've tried these codecs and none of them worked: I420, AVC1, YUV1, PIM1, MJPG, MP42, MP4V, DIV3, DIVX, XVID, IUYV,FFV1, FLV1, U263, H264, ZLIB
I've also gone through all the quick time codecs mentioned here
Using ZLIB codec I get the error:
[zlib # 0x7fb0d130a000] Specified pixel format yuv420p is invalid or not supported
Using H264 codec I get an error:
[libx264 # 0x7fe423869600] broken ffmpeg default settings detected
[libx264 # 0x7fe423869600] use an encoding preset (e.g. -vpre medium)
[libx264 # 0x7fe423869600] preset usage: -vpre <speed> -vpre <profile>
[libx264 # 0x7fe423869600] speed presets are listed in x264 --help
[libx264 # 0x7fe423869600] profile is optional; x264 defaults to high
I didn't understand what the above errors meant. I tried reinstalling ffmpeg to the latest version (1.2.2_0+gpl2) but my script still doesn't work. All the other codecs did not give any error.
I've even tried the file extensions of .mpg and .mkv with the above codecs. Sometimes I would get an error saying that the codec was not suitable for the file extension but when I didn't get error I would simply get the unreadable video file of a minuscule size.
Any help is much appreciated.
ps: I've already gone through the following SO questions which didn't solve my issue:
using opencv2 write streaming video in python
Writing video with OpenCV + Python + Mac
Create an avi video with opencv and python on a mac
Python OpenCV, can't write a video (.avi) to file
Creating AVI files in OpenCV
read/write avi video on MAC using openCV
Python OpenCV 2.4 writes half-complete PNG video frames
The problem seems to have been with the image size in the function videoFile.open('video.avi', codec, 25, (640, 480),1)
So I updated my script to include
size = (int(cap0.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),
int(cap0.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
And then accordingly changed videoFile.open to
videoFile.open('video.avi', codec, 25, size,1)
Then my script started working.
I've tried the codecs with fourcc: IYUV, I420, PIM1, MJPG, FFV1 and DIVX with file extension .avi
Each of the above codec worked with frame rates 16, 20, 25 and 30 except for PIM1 which seems to work only on 20fps and above.
Also,
Codec with fourcc THEO worked with file extension .ogv
XVID worked properly with file extension .mkv and though the .mkv container should work with any encoding I got a variety of weird results with other codecs.
FLV1 with file extension .flv didn't work. It gave the error:
[flv # 0x7f8414006000] Tag FLV1/0x31564c46 incompatible with output codec id '22' ([2][0][0][0])
FLV4 with file extension .flv didn't give an error but opencv's videowrite outputted an error "Could not update video file"
Of the codecs that worked with .avi file container, DIVX produced the smallest video file (~4Mb for 4 sec video) and IYUV produced the largest file (~160Mb for 4 sec video)
Note:
fps = videoCapture.get(cv2.cv.CV_CAP_PROP_FPS) always returns 0.0 when capturing from webcam. It is a bug in OpenCV2.4.3 and OpenCV2.4.4
I also found out that ffmpeg cannot grab images from Mac's iSight and FacetimeHD webcams the way it can from Windows and Ubuntu because designers at Apple have prohibited easy access to the mac's camera... what a shame!
References:
http://en.wikipedia.org/wiki/Comparison_of_container_formats
Initially I was getting a 0kb video file. I changed the Codec from MJPG to iYUV. It worked for me. Python 2.7 and openCV 2.4.5.
cap = cv2.VideoCapture(0)
fourCC = cv2.cv.CV_FOURCC('i','Y','U', 'V'); # Important to notice cv2.cv.CV_FOURCC
size = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
out = cv2.VideoWriter("Test.avi", fourCC, 15.0, size, True)
To get h264 working, install ffmpeg from the following link. Its quite a cumbersome installation but it ll get the encoder up and running.
https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

OpenCV + python -- grab frames from a video file

I can't seem to capture frames from a file using OpenCV -- I've compiled from source on Ubuntu with all the necessary prereqs according to: http://opencv.willowgarage.com/wiki/InstallGuide%20%3A%20Debian
#!/usr/bin/env python
import cv
import sys
files = sys.argv[1:]
for f in files:
capture = cv.CaptureFromFile(f)
print capture
print cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH)
print cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT)
for i in xrange(10000):
frame = cv.QueryFrame(capture)
if frame:
print frame
Output:
ubuntu#local:~/opencv$ ./test.py bbb.avi
<Capture 0xa37b130>
0.0
0.0
The frames are always None...
I've transcoded a video file to i420 format using:
mencoder $1 -nosound -ovc raw -vf format=i420 -o $2
Any ideas?
You don't have the gstreamer-ffmpeg or gsteamer-python or gsteamer-python-devel packages installed. I installed all three of them. and the exact same problem was resolved.
I'm using OpenCV 2.2.0, compiled on Ubuntu from source. I can confirm that the source code you provided works as expected. So the problem is somewhere else.
I couldn't reproduce your problem using mencoder (installing it is a bit of a problem on my machine) so I used ffmpeg to wrap a raw video in the AVI container:
ffmpeg -s cif -i ~/local/sample-video/foreman.yuv -vcodec copy foreman.avi
(foreman.yuv is a standard CIF image sequence you can find on the net if you look around).
Running the AVI from ffmpeg through your source gives this:
misha#misha-desktop:~/Desktop/stackoverflow$ python ocv_video.py foreman.avi
<Capture 0xa71120>
352.0
288.0
<iplimage(nChannels=3 width=352 height=288 widthStep=1056 )>
<iplimage(nChannels=3 width=352 height=288 widthStep=1056 )>
...
So things work as expected. What you should check:
Do you get any errors on standard output/standard error? OpenCV uses ffmpeg libraries to read video files, so be on the lookout for informative messages. Here's what happens if you try to play a RAW video file without a container (sounds similar to your problem):
error:
misha#misha-desktop:~/Desktop/stackoverflow$ python ocv_video.py foreman.yuv
[IMGUTILS # 0x7fff37c8d040] Picture size 0x0 is invalid
[IMGUTILS # 0x7fff37c8cf20] Picture size 0x0 is invalid
[rawvideo # 0x19e65c0] Could not find codec parameters (Video: rawvideo, yuv420p)
[rawvideo # 0x19e65c0] Estimating duration from bitrate, this may be inaccurate
GStreamer Plugin: Embedded video playback halted; module decodebin20 reported: Your GStreamer installation is missing a plug-in.
<Capture 0x19e3130>
0.0
0.0
Make sure your AVI file actually contains the required information to play back the video. At a minimum, this should be the frame dimensions. RAW video typically doesn't contain any information besides the actual pixel data, so knowing the frame dimensions and FPS is required. You can wrong-guess the FPS and still get a viewable video, but if you get the dimensions wrong, the video will be unviewable.
Make sure the AVI file you're trying to open is actually playable. Try ffplay file.avi -- if that fails, then the problem is likely to be with the file. Try using ffmpeg to transcode instead of mencoder.
Make sure you can play other videos, using the same method as above. If you can't, then it's likely that your ffmpeg install is broken.

Categories