View Source Image.Video (image v0.22.0)

Implements functions to extract frames froma video file as images using eVision.

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 wrrapped 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.

Link to this section Summary

Types

The valid options for Image.Video.seek/2, Image.Video.image_from_video/2

The representation of a video stream

Functions

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.

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

Opens a video file or video stream for frame extraction.

Opens a video file 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.

Link to this section 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

Link to this section Functions

@spec close(Evision.VideoCapture.t()) ::
  {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}

Closes a video.

arguments

Arguments

returns

Returns

  • {:ok, closed_video} or

  • {:error, reason}

example

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

Arguments

returns

Returns

  • closed_video or

  • raises an exception.

example

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

Arguments

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

Returns

  • {:ok, image} or

  • {:error, reason}

notes

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

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> {:error, "Offset for :frame must be a positive integer. Found -1"} = Image.Video.image_from_video(video, frame: -1)
iex> {:error, "Offset for :frame is too large"} = Image.Video.image_from_video(video, frame: 500)
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

Arguments

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

Returns

  • image or

  • raises an exception

notes

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 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

@spec open(filename_or_stream :: Path.t() | stream_id()) ::
  {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}

Opens a video file or video stream for frame extraction.

arguments

Arguments

  • filename_or_stream is the filename of a video file 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.

returns

Returns

  • {:ok, video} or

  • {:error, reason}

example

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 for frame extraction or raises an exception.

arguments

Arguments

  • filename is the filename of a video file

returns

Returns

  • video or

  • raises an exception

example

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

Arguements

returns

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.

  • {:error, reason}

examples

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

Arguments

options

Options

  • unit is either :frame or :millisecond with a non-negative integer offset. For example frame: 3.

returns

Returns

  • {:ok, video} or

  • {:error, reason}

notes

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

Warning

Seeking is not frame accurate!

examples

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> {:error, "Offset for :frame must be a positive integer. Found -1"} =
...>   Image.Video.seek(video, frame: -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

Arguments

options

Options

  • unit is either :frame or :millisecond with a non-negative integer offset. For example frame: 3.

returns

Returns

  • {:ok, video} or

  • {:error, reason}

notes

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

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 Evision.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

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. :milliseconds can only be specified for video files, not for video streams. For example, milliseconds: 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

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

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())) ::
  {:ok, Evision.VideoCapture.t()} | {:error, Image.error_message()}

Opens a video file, calls the given function with the video reference and closes the video after the function returns.

arguments

Arguments

  • filename is the filename of a video file

returns

Returns

  • {:ok, video} or

  • {:error, reason}

example

Example

iex> Image.Video.with_video "./test/support/video/video_sample.mp4", fn video ->
...>  Image.Video.image_from_video(video, 1)
...> end