View Source Image.Video (image v0.54.4)

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

Link to this macro

is_frame(frame, frame_count)

View Source (macro)

Guards that a frame offset is valid for a video

Link to this macro

is_stream(stream_id)

View Source (macro)

Guards that a stream id is valid for a video stream

Link to this macro

is_valid_millis(millis, frames, fps)

View Source (macro)

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

Link to this function

available_backend?(backend)

View Source
@spec available_backend?(any()) :: boolean()

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 any t: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)

Closes a video or raises an exception.

Arguments

  • video is any t:VideoCapture.t/0.

Returns

  • closed_video or

  • raises an exception.

Example

iex> {:ok, video} = Image.Video.open "./test/support/video/video_sample.mp4"
iex> Image.Video.close!(video)
Link to this function

image_from_video(video, options \\ [])

View Source
@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 any t: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 example frame: 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:

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"}
Link to this function

image_from_video!(video, options \\ [])

View Source
@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 any t:VideoCapture.t/0.

  • options is a keyword list of options.

Options

  • unit is either :frame or :millisecond with a non-negative integer offset. For example frame: 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:

Returns

  • image or

  • raises 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]
Link to this function

open(filename, options \\ [])

View Source
@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 by Image.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 with ffpmeg support. Since the prebuilt evision packages are not built with ffmpeg support, evision must be installed and compiled with the environment variable EVISION_PREFER_PRECOMPILED=false after ensuring that ffmpeg 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)
Link to this function

open!(filename_or_stream)

View Source
@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 by Image.Video.available_backends/0.

Returns

  • video or

  • raises 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 with ffpmeg support. Since the prebuilt evision packages are not built with ffmpeg support, evision must be installed and compiled with the environment variable EVISION_PREFER_PRECOMPILED=false after ensuring that ffmpeg 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 any t: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}

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 any t:VideoCapture.t/0.

  • options is a keyword list of options.

Options

  • unit is either :frame or :millisecond with a non-negative integer offset. For example frame: 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"}
Link to this function

seek!(video, options \\ [])

View Source

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 any t:VideoCapture.t/0.

  • options is a keyword list of options.

Options

  • unit is either :frame or :millisecond with a non-negative integer offset. For example frame: 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.

Link to this function

stream!(video, options \\ [])

View Source
@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 a t: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 a Range.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 offsets 10 and 100.

  • :millisecond is a Range.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 of 1_000 and 100_000.

Returns

  • A Enumerable.t/0 that can be used with functions in the Stream and Enum 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
Link to this function

with_video(filename, fun)

View Source
@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