Documentation for herc-imgtool

Image processing utilities for the University of South Carolina Heterogeneous and Reconfigurable Computing (HeRC) research group. In particular, this tool is used for converting images to and from formats suitable for use with various embedded systems and FPGA platforms.

Description

Keep in mind that this script is not a tool for producing high-quality production images. It may introduce artifacting in some cases. Reading an image as a JPEG and saving it as a JPEG will not necessarily produce a bit-for-bit copy of that image. If you want high quality image manipulation of standardized formats, you should instead use convert from ImageMagic.

Dependencies

To run this application, a Python 3 interpreter must be in $PATH and available via the name python3. Additionally, the following Python 3 packages must be installed:

  • PIL
  • numpy
  • skimage (only for canny edge detection)

HeRC Header Format (H2F)

For the purpose of code-sharing, a number of in-house HeRC formats use the same header format, which is documented here. An H2F consists of 16 bytes of data, organized into the following fields. Unless otherwise noted, all integer fields are assumed to be unsigned, with large byte order.

  • Magic string [4 bytes] - the ASCII characters ‘HeRC’, hexadecimal 0x48655243. This is used for validation.
  • Width in pixels [2 bytes] - unsigned int specifying image width.
  • Height in pixels [2 bytes] - unsigned int specifying image height.
  • File Format [1 byte] - see below for values.
  • Reserved [7 bytes] - reserved for future use, should be zeroed.

The file format field is used to specify which of the HeRC image formats is in use. The following values are possible:

Code Format
0 de2rawh
1 hif8
2 hif1

Supported Image Formats

The following standard image formats are supported:

  • jpeg
  • png
  • ppm
  • bmp (24-bit color bitmap)

The remainder of this section documents non-standard image formats which are also supported.

NOTE: To view a current listing of available image formats, as well as implementation status, please use the --list flag. The output from this option is generated directly from the herc-imtool image conversion matrix, and should always reflect what your copy of the tool is actually capable of.

Altera DE2 RAW Image With Header (de2rawh)

This image format stores a contiguous sequence of 1-byte color channel values, organized into tuples comprising the RGB color channel of each pixel consecutively, such that each group of 24 bits specifies the color value for one single pixel. Note that this is only the case for the default format, and some variants (such as feature flag 1). Some feature flags (i.e. 2) use a diffrent format. See below for details.

The de2rawh begins with a 16-byte H2F format header, and uses file format code 0.

This image format is used on the Altera DE2-115 development board to load images for further processing. Note that this is not an Altera format, it is simply convenient for use with Altera’s tooling. To that end, this image format may in fact be useful for other purposes, but it’s primary purpose is to support the DE2 development board, in particular in the context of the University of South Carolina CSCE313 course.

In particular, it is intended for this format to be convenient to utilize with C program, as it can be indexed directly as an array, being careful to start indexing at byte 16 (i.e. the first 16 bytes are ignored, so that the header is not treated as data).

By convention, images in the de2rawh format use one of the following two file extensions: .de2rawh, or .d2h.

NOTE: You can also have herc-imgtool pack your de2rawh file into a zip file suitable for use with Altera zipfs. This is accomplished by providing the --pack2zipfs flag.

NOTE: The name of this image format is maintained for compatibility with herc-imgtool 0.0.1. This format would be more accurately dubbed HIF24.

HeRC Image Format (HIF)

HIF is actually a collection of different image formats. All HIF image types store pixel data contiguously in row-major format, with big byte-order. HIF formats are suffixed with a number (i.e. hif8), which is the number of bits per pixel. In this way, hif1 refers to a 1-bit-per-pixel bitmap, hif8 to a 1-byte-per-pixel greyscale image, and hif24 to a 3-byte-per-pixel RGB image (identical to de2rawh).

All HIF types begin wtih a 16-byte H2F format header.

The following HIF formats are supported:

  • hif1
  • hif8
  • hif24 (de2rawh)

Altera DE2 RAW Image Without Header (de2raw)

This is exactly identical to de2rawh, but sans the 16 byte header. The resolution is assumed to be 320x240 exactly. Note that if the image is not already 320x240, it will be automatically resized as if you had passed the options --resize 320x240 --bg_fill 0,0,0. For a non-default background color, you must specify --resize and --bg_fill manually.

By convention, images in the de2raw format use one of the following two file extensions: .de2raw, .dat, or .d2r. Note that the .dat file extension is actually associated (see infer_format()) with the de2raw format, meaning using .dat as a file extension for input or output implies that that file should be treated as a de2raw file. To override this behaviour, use --input_format.

NOTE: You can also have herc-imgtool pack your de2raw file into a zip file suitable for use with Altera zipfs. This is accomplished by providing the --pack2zipfs flag.

herc-imgtool In-Memory Format (hercimf)

This format is simply the in-memory image format for this program. It’s on-disk representation is simply a pickled copy of the data structure which holds the image in memory. This is generally not useful except for debugging this program. Note that this format is not guaranteed to be stable - it should not be used for archival.

The data structure itself is a dict with the following keys:

  • width - integer number of horizontal pixels
  • height - integer number of vertical pixels
  • version - the version string for the herc-imgtool which generated this image.
  • pixels - numpy 2-dimensional array of pixel color values in RGB color. I believe this is technically a 3-dimensional array in-memory, since color channels can be accessed via an additional level of subscription.
  • greyscale - boolean, if true, then the red channel is intended to be treated as greyscale color values, and the G and B color channels are to be ignored. The pixels array retains the same format.
  • pixmap - boolean, if true, greyscale is ignored, and the image is assumed to be a 1-bit-per-pixel image. The red channel is used to store the 1s or 0s (as 8 bit ints) while the G and B channels are ignored.

Note that the hercimf on-disk format is bz2 compressed before writing, to save space.

herc-imgtool Architecture Overview

herc-imgtool utilizes a 4-stage image processing pipeline, which is orchestrated by the main() function. The stages of the pipeline are:

1. image load - the input image is loaded into the in-memory format for further processing. In the case of hercimf image, this simply involves unpickling the object. For other formats, dedicated conversion functions are utilized.

2. image manipulation - any image manipulations specified by the user are executed sequentially in a pre-defined order. For example --resize and --stretch. In the future, more manipulations (i.e. channel masking) may be added. The order in which manipulations run is not user-configurable.

3. image store - the finalized image is written to disk in the desired format. For hercimf images, this simply involves pickling the object and writing it out. For other images, dedicated conversion functions are utilized.

4. post processing - in some cases, it may be desirable to post-process the generated output file using a script of some kind. For example, the --pack2zipfs flag causes a zip command to be run on the generated output file to pack a zip file suitable for use with Altera zipfs. At present, this is the only post-processing step available, but others may be added in the future. Post-processing steps are executed sequentially, in a non-user-configurable order.

Of particular note, stages 1 and 3 utilize the somewhat novel conversion matrix this construct is a hashtable of hashtables. The outer key is a format (i.e. png). The inner key is either load or store. The value associated with the inner key is always a function object (function pointer in C parlance). Every such function must conform to the same calling conventions, and must be pure with respect to the overall application state (which resides in main(). The conversion matrix saves considerable time and complexity as compared to a case statement or a long if/elif/else block. It is also useful, because individual formats may support read-only, write-only, or read-write access, all of which can be encoded trivially in the conversion matrix.

Stage 2 is relatively uninteresting, and roughly consists of executing a number of pure functions against the working state of the image in memory.

Stage 4 is equally uninteresting, and generally consists of conditionally executing shell commands, with appropriate glue.

Syntax

Run this script with the ``--help`` parameter for usage information.

Author

Charles Daniels

License

Copyright 2018 Charles Daniels

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Changelog

  • 0.0.1

    • 2018-02-12 - Charles Daniels

      • Initial version with the following features:

        • Letterbox and stretch resizing, with arbitrary BG fill color.
        • Read and write support for jpeg, png, bmp, ppm, de2raw, de2rawh, and hercimf format image files.
        • Automatic packing of Altera zipfs-compatible zip files (via --pack2zipfs).
  • 0.0.2

    • 2018-02-19 - Charles Daniels

      • Added –canny
      • Added –canny_sigma
      • Added –greyscale option
      • Added –threshold option
    • 2018-02-20 - Charles Daniels

      • Specify H2F and HIF formats.
      • Added –display.
      • Implemented HIF8 support.
      • Added methods to handle generating and parsing H2F headers.
    • 2018-02-22 - Charles Daniels

      • Added HIF1 support.
  • 0.0.3