# Image Utilities Tutorial

Image datasets are becoming increasingly popular in deep learning.

mlpack's image saving/loading functionality is based on [stb](https://github.com/nothings/stb).

## Model API

Image utilities supports loading and saving of images.

It supports filetypes `jpg`, `png`, `tga`, `bmp`, `psd`, `gif`, `hdr`, `pic`,
`pnm` for loading and `jpg`, `png`, `tga`, `bmp`, `hdr` for saving.

The datatype associated is unsigned char to support RGB values in the range
1-255. To feed data into the network typecast of `arma::Mat` may be required.
Images are stored in matrix as `(width * height * channels, numberOfImages)`.
Therefore `imageMatrix.col(0)` would be the first image if images are loaded in
`imageMatrix`.

## `ImageOptions`

The `ImageOptions` class contains the metadata of the images.

```c++
/**
 * Instantiate the ImageInfo object with the image width, height, channels.
 *
 * @param width Image width.
 * @param height Image height.
 * @param channels number of channels in the image.
 */
ImageOptions(const size_t width,
             const size_t height,
             const size_t channels);
```

Other public members include the quality compression of the image if saved as
`jpg` (0-100).

## Loading

Standalone loading of images can be done with the function below.

```c++
/**
 * Load the image file into the given matrix.
 *
 * @param filename Name of the image file.
 * @param matrix Matrix to load the image into.
 * @param opts An object of ImageOptions class.
 * @return Boolean value indicating success or failure of load.
 */
template<typename eT>
bool Load(const std::string& filename,
          arma::Mat<eT>& matrix,
          ImageOptions& opts);
```

Loading a test image is shown below. It also fills up the `ImageOptions` class

object.

```c++
mlpack::ImageOptions opts = mlpack::NoFatal + mlpack::Transpose;
Load("test_image.png", matrix, opts);
```

`ImageOptions` requires height, width, and the number of channels of the image.


```c++
size_t height = 64, width = 64, channels = 1;
mlpack::ImageOptions opts(width, height, channels);
```

More than one image can be loaded into the same matrix.

Loading multiple images can be done using the function below.

```c++
/**
 * Load the image file into the given matrix.
 *
 * @param files A vector consisting of filenames.
 * @param matrix Matrix to save the image from.
 * @param opts An object of ImageOptions class.
 * @return Boolean value indicating success or failure of load.
 */
template<typename eT>
bool Load(const std::vector<std::string>& files,
          arma::Mat<eT>& matrix,
          ImageOptions& opts)
```

```c++
mlpack::ImageOptions opts;
std::vector<std::string>> files{"test_image1.bmp","test_image2.bmp"};
Load(files, matrix, opts);
```

## Saving

Saving images expects a matrix of type unsigned char in the form `(width *
height * channels, NumberOfImages)`.  Just like loading, it can be used to save
one image or multiple images. Besides image data it also expects the shape of
the image as input `(width, height, channels)`.

Saving one image can be done with the function below:

```c++
/**
 * Save the image file from the given matrix.
 *
 * @param filename Name of the image file.
 * @param matrix Matrix to save the image from.
 * @param opts An object of ImageOptions class.
 * @return Boolean value indicating success or failure of load.
 */
template<typename eT>
bool Save(const std::string& filename,
          arma::Mat<eT>& matrix,
          ImageOptions& opts);
```

```c++
mlpack::ImageOptions opts = mlpack::NoFatal + mlpack::Transpose;
opts.Width() = opts.Height() = 25;
opts.Channels() = 3;
opts.Quality() = 90;
Save("test_image.bmp", matrix, opts);
```

If the matrix contains more than one image, only the first one is saved.

Saving multiple images can be done with the function below.

```c++
/**
 * Save the image file from the given matrix.
 *
 * @param files A vector consisting of filenames.
 * @param matrix Matrix to save the image from.
 * @param opts An object of ImageOptions class.
 * @return Boolean value indicating success or failure of load.
 */
template<typename eT>
bool Save(const std::vector<std::string>& files,
          arma::Mat<eT>& matrix,
          ImageOptions& opts);
```

```c++
mlpack::ImageOptions opts = mlpack::NoFatal + mlpack::Transpose;
opts.Width() = opts.Height() = 25;
opts.Channels() = 3;
opts.Quality() = 90;
std::vector<std::string>> files{"test_image1.bmp", "test_image2.bmp"};
Save(files, matrix, opts);
```

Multiple images are saved according to the vector of filenames specified.
