I want to extract selected images from downloaded video files. I’d like to know whether Membrane is a reasonable tool for this job, whether anyone else has done similar tasks with it, etc. I’m also unsure about how its “pipeline” approach would fit a “random access” use case.
For purposes of discussion, assume that I’ll be using VLC media player to download videos from web sites such as YouTube, storing them as MP4 files. Because I’ll be processing the images, I’d like to get them into Nx tensor format.
Can someone give me some advice, clues, and/or suggestions?
It seems like FFmpeg only extracts images in PNG format. This might work well with ExPNG, but I think I’ll want to get them into Nx format at some point. Suggestions?
You can therefore use either the more idiomatic API in Image.Video or simply leverage the code that is there to use Evision directly.
Depending on the codec support of the OpenCV installation on your system I suspect you may not need to use the FFMEG CLI approach any more.
Example using Image
# Extract using a frame offset
iex> {:ok, video} = Image.Video.open("./test/support/video/video_sample.mp4")
iex> {:ok, _image} = Image.Video.image_from_video(video, frame: 0)
# Extract using a millisecond offset
iex> {:ok, _image} = Image.Video.image_from_video(video, millisecond: 0)
# Capturing images from a camera (note that seeking is not supported
# on image streams. On MacOS you will receive a prompt to permit the
# app to access the camera. You may need to restart the BEAM and/or
# your system if capturing fails immediately after granting permission.
iex> {:ok, video} = Image.Video.open(:default_camera)
iex> {:ok, _image} = Image.Video.image_from_video(video)
Example using Evision directly
# Extract by frame offset
video = Evision.VideoCapture.videoCapture(video_filename)
true = Evision.VideoCapture.set(video, Evision.cv_CAP_PROP_POS_FRAMES(), frame_offset),
cv_image = Evision.VideoCapture.read(video)
Using images in Nx
Both Image and Evision support zero-copy “export” of images to Nx. Just call Image.to_nx/1 or Evision.Mat.to_nx/1 as appropriate.