View Source Image.Video (image v0.55.2)
Implements functions to extract frames froma video file as images using eVision. The implementation is based upon OpenCV Video Capture.
Images can be extracted by frame number of number of milliseconds with
Image.Video.image_from_video/2
.
In order to extract images the video file must first be
opened with Image.Video.open/1
. At the end of processing the video
file should be closed with Image.Video.close/1
.
This process can be wrapped by Image.Video.with_video/2
which will
open a video file, execute a function (passing it the video reference) and
closing the video file at the end of the function.
Note
This module is only available if the optional dependency
eVision is configured in
mix.exs
.
Summary
Guards
Guards that a frame offset is valid for a video
Guards that a stream id is valid for a video stream
Guards that a millisecond count is valid for a video
Types
The valid options for Image.Video.seek/2, Image.Video.image_from_video/2
The representation of a video stream
Functions
Returns a boolean indicating if the specified backend is available (configured and available for use).
Returns a list of available (configured and available for use) backend video processors.
Closes a video.
Closes a video or raises an exception.
Extracts a frame from a video and returns an image.
Extracts a frame from a video and returns an image or raises an exception.
Returns a boolean indicating if the specified backend is known (valid but not necessarily available for use in the current OpenCV configuration).
Returns a list of known (valid but not necessarily available for use in the current OpenCV configuration) backend video processors.
Opens a video file, camera, RTSP URL or video stream for frame extraction.
Opens a video file, camera, RTSP URL or video stream for frame extraction or raises an exception.
Scrubs a video forward by a number of frames.
Seeks the video head to a specified frame offset or millisecond offset.
Seeks the video head to a specified frame offset or millisecond offset.
Returns video file or live video as a Enumerable.t/0
stream.
Opens a video file, calls the given function with the video reference and closes the video after the function returns.
Guards
Guards that a frame offset is valid for a video
Guards that a stream id is valid for a video stream
Guards that a millisecond count is valid for a video
Types
@type seek_options() :: [{:frame, non_neg_integer()}] | [{:millisecond, non_neg_integer()}]
The valid options for Image.Video.seek/2, Image.Video.image_from_video/2
@type stream_id() :: non_neg_integer() | :default_camera
The representation of a video stream
Functions
Returns a boolean indicating if the specified backend is available (configured and available for use).
@spec available_backends() :: [Image.Options.Video.backend()]
Returns a list of available (configured and available for use) backend video processors.
See the OpenCV documentation for more information on video processor backends.
@spec close(Evision.VideoCapture.t()) :: {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}
Closes a video.
Arguments
video
is anyt:VideoCapture.t/0
.
Returns
{:ok, closed_video}
or{:error, reason}
.
Example
iex> {:ok, video} = Image.Video.open "./test/support/video/video_sample.mp4"
iex> Image.Video.close(video)
@spec close!(Evision.VideoCapture.t()) :: Evision.VideoCapture.t() | no_return()
Closes a video or raises an exception.
Arguments
video
is anyt:VideoCapture.t/0
.
Returns
closed_video
orraises an exception.
Example
iex> {:ok, video} = Image.Video.open "./test/support/video/video_sample.mp4"
iex> Image.Video.close!(video)
@spec image_from_video(Evision.VideoCapture.t(), seek_options()) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error_message()}
Extracts a frame from a video and returns an image.
After the image is extracted the play head
in the video file is advanced one frame. That is,
successive calls to Image.Video.image_from_video/2
will return successive frames - not the same frame.
Arguments
video
is anyt:VideoCapture.t/0
options
is a keyword list of options. The defalt
Options
unit
is either:frame
or:millisecond
with a non-negative integer offset. For exampleframe: 3
. The default is[]
which means that no seek is performed and the extracted image is taken from the current position in the file or video stream. Note that seeking is not guaranteed to be accurate. If frame accuracy is required the recommended process is:- Open the video file with
Image.Video.open/1
- Scrub forward to the required freame with
Image.Video.scrub/2
- Then capture the frame with
Image.Video.image_from_video/1
- Open the video file with
Returns
{:ok, image}
or{:error, reason}
.
Notes
Seeking cannot be performed on image streams such as webcams. Therefore no options may be provided when extracting images from an image stream.
Examples
iex> {:ok, video} = Image.Video.open("./test/support/video/video_sample.mp4")
iex> {:ok, _image} = Image.Video.image_from_video(video)
iex> {:ok, _image} = Image.Video.image_from_video(video, frame: 0)
iex> {:ok, _image} = Image.Video.image_from_video(video, millisecond: 1_000)
iex> Image.Video.image_from_video(video, frame: -1)
{:error, "Offset for :frame must be a non-negative integer. Found -1"}
iex> Image.Video.image_from_video(video, frame: 500)
{:error, "Offset for :frame is too large"}
@spec image_from_video!(Evision.VideoCapture.t(), seek_options()) :: Vix.Vips.Image.t() | no_return()
Extracts a frame from a video and returns an image or raises an exception.
After the image is extracted the play head
in the video file is advanced one frame. That is,
successive calls to Image.Video.image_from_video/2
will return successive frames - not the same frame.
Arguments
video
is anyt:VideoCapture.t/0
.options
is a keyword list of options.
Options
unit
is either:frame
or:millisecond
with a non-negative integer offset. For exampleframe: 3
. The default is[]
which means that no seek is performed and the extracted image is taken from the current position in the file or video stream. Note that seeking is not guaranteed to be accurate. If frame accuracy is required the recommended process is:- Open the video file with
Image.Video.open/1
- Scrub forward to the required freame with
Image.Video.scrub/2
- Then capture the frame with
Image.Video.image_from_video/1
- Open the video file with
Returns
image
orraises an exception.
Notes
Seeking cannot be performed on image streams such as webcams. Therefore no options may be provided when extracting images from an image stream.
@spec known_backend?(Image.Options.Video.backend()) :: boolean()
Returns a boolean indicating if the specified backend is known (valid but not necessarily available for use in the current OpenCV configuration).
Examples
iex> Image.Video.known_backend?(:avfoundation)
true
iex> Image.Video.known_backend?(:invalid)
false
iex> Image.Video.known_backend?(1200)
true
iex> Image.Video.known_backend?(-1)
false
@spec known_backends() :: [Image.Options.Video.backend()]
Returns a list of known (valid but not necessarily available for use in the current OpenCV configuration) backend video processors.
See the OpenCV documentation for more information on video processor backends.
Example
iex> Image.Video.known_backends() |> Enum.sort()
[:android, :any, :aravis, :avfoundation, :cmu1394, :dc1394, :dshow, :ffmpeg,
:fireware, :firewire, :giganetix, :gphoto2, :gstreamer, :ieee1394, :images,
:intel_mfx, :intelperc, :msmf, :obsensor, :opencv_mjpeg, :openni, :openni2,
:openni2_astra, :openni2_asus, :openni_asus, :pvapi, :qt, :realsense, :ueye,
:unicap, :v4l, :v4l2, :vfw, :winrt, :xiapi, :xine]
@spec open( filename_or_stream :: Path.t() | stream_id(), Image.Options.Video.open_options() ) :: {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}
Opens a video file, camera, RTSP URL or video stream for frame extraction.
Arguments
filename_or_stream
is the filename of a video file, the URL of an RTSP stream or the OpenCV representation of a video stream as an integer. It may also be:default_camera
to open the default camera if there is one.options
is a keyword list of options. The default is[]
.
Options
:backend
specifies the backend video processing system to be used. The default is:any
which means that the first available backend in the current OpenCV configuration will be used. The available backends can be returned byImage.Video.available_backends/0
.
Returns
{:ok, video}
or{:error, reason}
.
Notes
The video
t:VideoCapture.t/0
struct that is returned includes metadata fields for frame rate (:fps), frame width (:frame_width), frame height (:frame_height) and frame count (:frame_count). Note that frame count is an approximation due to issues in the underlying OpenCV.Opening an RTSP stream requires that
evision
be built withffpmeg
support. Since the prebuiltevision
packages are not built withffmpeg
support,evision
must be installed and compiled with the environment variableEVISION_PREFER_PRECOMPILED=false
after ensuring thatffmpeg
is installed. On a MacOS system,brew install ffmpeg && brew link ffpeg
or similar will perform that installation. See also the detailed evision installation instructions.
Example
iex> Image.Video.open "./test/support/video/video_sample.mp4"
iex> {:ok, camera_video} = Image.Video.open(:default_camera)
iex> Image.Video.close(camera_video)
@spec open!(filename_or_stream :: Path.t() | stream_id()) :: Evision.VideoCapture.t() | no_return()
Opens a video file, camera, RTSP URL or video stream for frame extraction or raises an exception.
Arguments
filename_or_stream
is the filename of a video file, the URL of an RTSP stream or the OpenCV representation of a video stream as an integer. It may also be:default_camera
to open the default camera if there is one.options
is a keyword list of options. The default is[]
.
Options
:backend
specifies the backend video processing system to be used. The default is:any
which means that the first available backend in the current OpenCV configuration will be used. The available backends can be returned byImage.Video.available_backends/0
.
Returns
video
orraises an exception.
Notes
The video
t:VideoCapture.t/0
struct that is returned includes metadata fields for frame rate (:fps), frame width (:frame_width), frame height (:frame_height) and frame count (:frame_count). Note that frame count is an approximation due to issues in the underlying OpenCV.Opening an RTSP stream requires that
evision
be built withffpmeg
support. Since the prebuiltevision
packages are not built withffmpeg
support,evision
must be installed and compiled with the environment variableEVISION_PREFER_PRECOMPILED=false
after ensuring thatffmpeg
is installed. On a MacOS system,brew install ffmpeg && brew link ffpeg
or similar will perform that installation. See also the detailed evision installation instructions.
Example
iex> Image.Video.open! "./test/support/video/video_sample.mp4"
@spec scrub(Evision.VideoCapture.t(), frames :: pos_integer()) :: {:ok, pos_integer()} | {:error, Image.error_message()}
Scrubs a video forward by a number of frames.
In OpenCV (the underlying video library used by
Image.Video
), seeking to a specified frame is not
frame accurate. This function moves the video
play head forward frame by frame and is therefore
a frame accurate way of moving the the video head
forward.
Arguements
video
is anyt:VideoCapture.t/0
.frames
is a positive integer number of frames to scrub forward.
Returns
{:ok, frames_scrubbed}
.frames_scrubbed
may be less than the number of requested frames. This may happen of the end of the video stream is reached, or{:error, reason}
.
Examples
iex> {:ok, video} = Image.Video.open "./test/support/video/video_sample.mp4"
iex> {:ok, 10} = Image.Video.scrub(video, 10)
iex> Image.Video.scrub(video, 100_000_000)
{:ok, 161}
@spec seek(Evision.VideoCapture.t(), seek_options()) :: {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}
Seeks the video head to a specified frame offset or millisecond offset.
Note that seeking a video format is supported, seeking a live video stream (such as from a webcam) is not supported and will return an error.
Arguments
video
is anyt:VideoCapture.t/0
.options
is a keyword list of options.
Options
unit
is either:frame
or:millisecond
with a non-negative integer offset. For exampleframe: 3
.
Returns
{:ok, video}
or{:error, reason}
Notes
Seeking cannot be performed on image streams such as webcams. Therefore no options may be provided when extracting images from an image stream.
Warning
Seeking is not frame accurate!
Examples
iex> {:ok, video} = Image.Video.open("./test/support/video/video_sample.mp4")
iex> {:ok, _image} = Image.Video.seek(video, frame: 0)
iex> {:ok, _image} = Image.Video.seek(video, millisecond: 1_000)
iex> Image.Video.seek(video, frame: -1)
{:error, "Offset for :frame must be a non-negative integer. Found -1"}
@spec seek!(Evision.VideoCapture.t(), seek_options()) :: Evision.VideoCapture.t() | no_return()
Seeks the video head to a specified frame offset or millisecond offset.
Note that seeking a video format is supported, seeking a live video stream (such as from a webcam) is not supported and will return an error.
Arguments
video
is anyt:VideoCapture.t/0
.options
is a keyword list of options.
Options
unit
is either:frame
or:millisecond
with a non-negative integer offset. For exampleframe: 3
.
Returns
{:ok, video}
or{:error, reason}
.
Notes
Seeking cannot be performed on image streams such as webcams. Therefore no options may be provided when extracting images from an image stream.
@spec stream!( filename_or_stream :: Path.t() | stream_id() | Evision.VideoCapture.t(), options :: Keyword.t() ) :: Enumerable.t()
Returns video file or live video as a Enumerable.t/0
stream.
This allows a video file or live video to be streamed for processing like any other enumerable.
Arguments
filename_or_stream
is either a pathname on the current system, a non-negative integer representing a video stream or:default_camera
representing the stream for the default system camera. It can also be at:VideoCapture.t/0
representing a video file or stream that is already opened (this is the preferred approach).options
is a keyword list of options.
Options
Only one of the following options can be provided. No options means the entire video will be streamed frame by frame.
:frame
is aRange.t/0
representing the range of frames to be extracted.:frames
can only be specified for video files, not for video streams. For example,frames: 10..100/2
will produce a stream of images that are every second image between the frame offsets10
and100
.:millisecond
is aRange.t/0
representing the range of milliseconds to be extracted.:millisecond
can only be specified for video files, not for video streams. For example,millisecond: 1000..100000/2
will produce a stream of images that are every second image between the millisecond offsets of1_000
and100_000
.
Returns
- A
Enumerable.t/0
that can be used with functions in theStream
andEnum
modules to lazily enumerate images extracted from a video stream.
Example
# Extract every second frame starting at the
# first frame and ending at the last frame.
iex> "./test/support/video/video_sample.mp4"
...> |> Image.Video.stream!(frame: 0..-1//2)
...> |> Enum.to_list()
...> |> Enum.count()
86
@spec with_video(filename :: Path.t(), (Evision.VideoCapture.t() -> any())) :: any()
Opens a video file, calls the given function with the video reference and closes the video after the function returns.
Arguments
filename
is the filename of a video file.
Returns
The result of the user function or
{:error, reason}
if the video file could not be opened.
Example
iex> Image.Video.with_video "./test/support/video/video_sample.mp4", fn video ->
...> Image.Video.image_from_video(video, 1)
...> end