Image manipulation: Import stills from video into python/matplotlib? - python

I am playing with stacking and processing astronomical photographs. I'm as interested in understanding algorithms as I am in the finished images, so I have not (yet) tried any of the numerous polished products floating around.
I have moderately-sized collections of still photographs (dozens at a time) which I can successfully import using
img = imread("filename.jpg")
This produces a numpy ndarray matrix, which I can manipulate using the tools available from numpy and scipy.ndimage, and display using imshow(). This is supported on the back end by the Python Imaging Library, PIL, which as far as I can tell supports only still images.
For longer exposures, it'd be nice to set my camera to take video, then extract frames from the video and run them through the same analysis pipeline as the still images. As far as I can tell, PIL supports only still images. My camera produces Quicktime movies with .MOV file extensions.
Is there a Python library that will let me access the data from frames of a video?
Alternatively, I'd appreciate guidance on using an external tool (there seems to exist a command-line ffmpeg, but I haven't tried it) to generate temporary files that I can feed into my still-image pipeline. Since I might want to examine all 18k frames in a ten-minute, 30fps movie, just extracting all the frames into one big folder is probably not an option.
I am running Python 2.7 on OSX Mavericks; I have easy access to MacPorts to install things.

The following line of ffmpeg will let you extract 10 seconds of video, starting at a prespecified time (here 20 seconds after the start of the movie) :
ffmpeg -i myvideo.MOV -ss 00:00:20.00 -t 10 img%3d.jpg
It is easy to figure out how you can use that in a Bash loop or run the command in a loop via Python.

Related

"imagio.imsave" vs "imageio.core.util.Array.tofile"

I am expanding my limited Python knowledge by converting some MATLAB image analysis code to Python. I am following Image manipulation and processing using Numpy and Scipy. The code in Section 2.6.1 saves an image using both imageio.imsave and face.tofile, where type(face)=<class 'imageio.core.util.Array>'.
I am trying to understand why there are two ways to export an image. I tried web-searching tofile, but got numpy.ndarray.tofile. It's very sparse, and doesn't seem to be specific to images. I also looked for imageio.core.util.Array.tofile, but wasn't able to find anything.
Why are there two ways to export files? And why does imageio.core.util.Array.tofile seem to be un-findable online?
The difference is in what the two functions write in the file.
imageio.imsave() saves a conventional image, like a picture or photo, in JPEG/PNG format that can be viewed with an image viewer like GIMP, feh, eog, Photoshop or MSxPaint.
tofile() saves in a Numpy-compatible format that only Numpy (and a small number of other Python tools) use.

What are the steps needed to convert a video to a Gif in Python?

I have a project that involves creating a program that converts a video into a gif. Sounds simple enough if I use OpenCV but I need to organize the bitstream of the gif file myself. I Googled around and I can't find any resources that outline the steps required to achieve this or how to organize the bitstream myself.
I'm assuming the steps I need to do is image compression for each frame but I'm not sure if I still need to use Motion Estimation if I want a smooth Gif in the end.
edit: Just to be clear I need this to be done without using a library that converts the video to a gif for me so moviepy won't work
from moviepy.editor import *
clip = (VideoFileClip("ABCD.mp4")
.subclip((1,22.65),(1,23.2))
.resize(0.3))
clip.write_gif("ABCD.gif")
You can download Youtube Video with this command if you have Youtube-dl installed:
youtube-dl 2Jw-AeaU5WI -o ABCD.mp4

Reading a RAW image (.CR2) using numpy.fromfile

I am trying to read a raw image in .CR2 format ("Canon Raw format"). I wanted to do it with opencv initially but could not get it to work so I tried doing it with a numpy function:
img = np.fromfile('IMG.CR2', "uint16")
The camera is a canon EOS t5 18MP DSLR.
If I run img.size it return 10105415 which seems too small for an 18 MP camera.
My first question, is using np.fromfile() a valid approach?
Secondly, would you recommend any other python libraries to do the same process in an easier way/more efficient? I have openCV installed so if it could be done there, that would be great (I still want to store it as a numpy array).
Canon RAW format is not just a blob of data, it has some metadata which you need to parse. Luckily, others have already implemented some python parsers.
RAW Image processing in Python
After using one of the suggested solutions you can load the data into numpy array.

Video editing with python or command line

I need to perform the following operations in my python+django project:
joining videos with same size and bitrate
joining videos and images (for the image manipulation I'll use PIL: writing text to an existing image)
fading in the transitions between videos
I already know of some video editing libraries for python: MLT framework (too complex for my needs), pygame and pymedia (don't include all the features I want), gstreamer bindings (terrible documentation).
I could also do all the work from command line, using ffmpeg, mencoder or transcode.
What's the best approach to do such a thing on a Linux machine.
EDIT: eventually I've chosen to work with melt (mlt's command line)
http://avisynth.org/mediawiki/Main_Page is a scripting language for video.
Because ffmpeg is available on GNU/Linux, i thing using it with modules such as pexpect or subprocess is the best solution....
You can use OpenCV for joining videos and images. See the documentation, in particular the image/video I/O functions.
However, I'm not sure if the library has functions that will do the fading for you.
What codec are you using?
There are two ways to compress video: lossy and lossless. It's easy to tell them apart. Depending on their length, lossy video files are in the megabyte range, lossless (including uncompressed) are in the gigabyte range.
Here's an oversimplification. Editing video files is a lot different from editing film, where you just glue the pieces of film together. It's not just about bitrate, frame rate and resolution. Most lossy video codecs (MPEG 1-4, Ogg Theora, H.26x, VC-1, etc.) start out with a full frame then record only the changes in movement. When you watch the video what you're actually seeing is a static scene with layer after layer of changes pasted on top of it. It looks like you're seeing full frame after full frame, but if you looked at the data in the file all you'd see would be a black background and scrambled blocks of video.
If it's uncompressed or uses a lossless codec (HuffYUV, Lagarith, FFV1, etc.) then you can edit your video file just like film. You still have to re-encode the video but it won't effect video quality and you can cut, copy and paste however you like as long as the resolution and frame rate are the same. If you're video is lossy you have to re-encode it with some loss of video quality, just like saving the same image in JPEG, over and over.
Another option might be to put several pieces of video into a container like MKV and use chapters to have it jump from piece to piece. I seem to remember being told this is possible but I've never tried it so maybe it isn't.

Python scene change detection

I am wondering if anyone has any experience with Python and video processing. Essentially, I would like to know if there are any libraries that would allow me to do scene detection in a video? If not, are there any that can allow me to split the video up into a series of frames and let me mess about with the pixels?
Thanks!
OpenCV has Python bindings; I don't think it has any scene boundary algorithms / functions built it, but you can definitely use it to write your own.
You can use FFmpeg to do the scene detection and obtain the change frames and their timestamps. The command can be combined with a python script and you can modify it according to your use case.
You can simply use the command:
ffmpeg inputvideo.mp4 -filter_complex "select='gt(scene,0.3)',metadata=print:file=time.txt" -vsync vfr img%03d.png
This will save just the relevant information in the time.txt file like below and also save the shot change images in order:
frame:0 pts:108859 pts_time:1.20954
lavfi.scene_score=0.436456
frame:1 pts:285285 pts_time:3.16983
lavfi.scene_score=0.444537
frame:2 pts:487987 pts_time:5.42208
lavfi.scene_score=0.494256
frame:3 pts:904654 pts_time:10.0517
lavfi.scene_score=0.462327
frame:4 pts:2533781 pts_time:28.1531
lavfi.scene_score=0.460413
frame:5 pts:2668916 pts_time:29.6546
lavfi.scene_score=0.432326
The frame is the serial number of the detected shot change from the starting. Also, choose your threshold value (here 0.3) appropriately for your use case to get correct outputs

Categories

Resources