MIO Format Questions

Hi,

if i understood it corretcly then “MIO” seems to be the only format in which i can save float images. Is there anything aprat from CommVisBlox that is capable of reading/showing these files or is there a way to access the pixel data inside a MIO file?

For instance, there is Intel’s IPL images that support float pixel values, these are also used in OpenCV and other SDKs probably. Though, other SDKs cannot read MIO from the get-go, you should be able to get the image data over there using GetLinearAccess() and create a new image in the other SDK from memory.

but arent’s those just in-memory formats?? I need a file format to pass floating point images to other ppl…

Hi @taserface,

you are right, the MIO format is currently the only file format for images in :cvb: that supports images with floating-point-valued pixels, and it is a highly proprietary format - to the point that nothing except :cvb: is able to load and/or save it. Other formats that would in principle be able to digest such images are JPEG2000 and TIFF, but for both those formats we have not implemented encoders/decoders that are capable of digesting floating-point-valued bitmaps.

MIO is shorthand for M inos I mage O object and gives a hint that the format is actually older than :cvb: itself. The origins of Minos, today a tool inside :cvb: predate :cvb: by about 10 years and when Minos was made a :cvb: tool, parts of Minos ended up in the ImageManager. One of these parts is the support for the proprietary image file format that Minos has been and is still using internally (for example a Minos Training Set or a Manto Sample Image List consists - among other things - of collections of MIO images). To prevent confusion, the extension by which WriteImageFile identifies the MIO format has been kept.

The MIO format is basically a binary dump of an entire :cvb: image object, including the image’s VPAT and coordinate system plus some internal structure information. This makes it very hard to correctly locate the pixel data inside the MIO file and there are cases where it’s practically impossible (at least not supportable) without knowing :cvb:'s internal object structure.

But for simpler cases it is actually feasible. Consider for example Clara.mio that is located in %CVB%\Tutorial, which is a MIO file with 5 planes with 8 bits per pixel each. The binary content of this file may be read as follows:

Offset (dec) Value (hex) Content Remark
0 0x00002710 object ID (*1) identifies a MIO image object; this type of object uses planar arrangement of pixel data and supports pixel types other than uint8_t; for a monochrome or RGB image with uint8_t pixels the object ID usually is 0x00002712 (see 2nd example below)
4 0x00000001 object count # of objects to follow (the count always refers to the object type that follows the count, not the the type that precedes it)
8 0x00000fa0 object ID ‘List’ (in Minos, image objects regardless of data were always a conglomerate of lists)
12 0x00000005 object count again referring to the object type in the next line…
16 0x00002711 object id ‘Image Plane’
20 0x00000001 object count of the following object
24 0x00000fa1 object id ‘Buffer’
28 0x00000000 object count no object ID follows, therefore 0
32 0x000107d0 buffer size 67536 bytes
36 pixel data 67536 bytes of pixel data for plane 0
67572 0x000008a0 buffer size buffer size for VPAT buffer (*2), 2208 bytes
67576 vpat data 2208 bytes of VPAT data for plane 0
69784 0x00000008 data type the pixel data type of plane 0 (8 = uint8_t)
69788 0x00002711 object id ‘Image Plane’
69792 0x00000001 object count of the following object
69796 0x00000fa1 object id ‘Buffer’
69800 0x00000000 object id no object ID follows, therefore 0
69804 0x000107d0 buffer size 67536 bytes
69808 pixel data 67536 bytes of pixel data for plane 1
137344 0x000008a0 buffer size buffer size for VPAT buffer, 2208 bytes
137348 vpat data 2208 bytes of VPAT data for plane 1
139556 0x00000008 data type the pixel data type of plane 1 (8 = uint8_t)
… (continue like this for plane 2…4) …
348876 0x000010c width width of the loaded image (268 pixels)
348880 0x00000fc height height of the loaded image (252 pixels)
348884 6 doubles TCoordinateMap the coordinate system of image stored as x offset, y offset and the elements a11, a12, a21 and a22 of the transformation matrix; in the simplest of cases these values are just 0.0, 0.0, 1.0, 0.0, 0.0, 1.0

… and done :wink:

(*1) Should you ever encounter a 0 in the object ID except in cases like the example below, then you have come across a case that cannot be loaded without :cvb:'s internal object structure. It might in fact not even be a proper MIO image but something different…

(*2) Note that although the VPAT of an image is always stored inside a MIO image, in practice this VPAT is always a linear VPAT and may therefore easily be ignored (the VPAT may, however, hint at a last-line-first arrangement in memory and in case of the interleaved DIB-like RGB images the VPAT will also take care of correctly addressing the red, green and blue channel). Also note that the VPAT is always given in 32 bit address size (i.e. 4 bytes for x entry and 4 bytes for y entry).

This example was one that is more similar to a case where you store floating-point-valued data in an image. In that case you should expect the datatype values for your planes to be 0x220, the rest is more or less the same.

The other case that is practically relevant - an image with 1 or 3 planes of uint8_t pixels - would look like this (loaded %CVB%\Tutorial\ClaraRGB.bmp and saved it to ClaraRGB.mio):

Offset (dec) Value (hex) Content Remark
0 0x00002711 object ID (*1) identifies a DIB image object; this type of object uses interleaved arrangement of pixel data and only supports the pixel type uint8_t
4 0x00000002 object count # of objects to follow (the count always refers to the object type that follows the count, not the the type that precedes it)
8 0x00000fa0 object ID ‘List’ (in Minos, image objects regardless of data were always a conglomerate of lists)
12 0x00000003 object count again referring to the object type in the next line…
16 0x00002711 object id ‘Image Plane’
20 0x00000001 object count of the following object
24 0x00000fa1 object id ‘Buffer’
28 0x00000000 object count no object ID follows, therefore 0
32 0x00036842 buffer size 223298 bytes
36 pixel data 223298 bytes of pixel data for plane 0
223334 0x000008d8 buffer size buffer size for VPAT buffer, 2264 bytes
223338 vpat data 2264 bytes of VPAT data for plane 0
225602 0x00000008 data type the pixel data type of plane 0 (8 = uint8_t)
225606 0x00002711 object id ‘Image Plane’
225610 0x00000001 object count of the following object
225614 0x00000000 object id in this case 0, which means a previously loaded object will be referenced again
225618 0x00000003 backreference index of the loaded object that will be referenced - the third object that was loaded was the pixel buffer at offset 24; in other words: this image plane object will use the same pixel buffer as the previous one
225622 0x000008d8 buffer size buffer size for VPAT buffer, 2264 bytes
225626 vpat data 2264 bytes of VPAT data for plane 1
227890 0x00000008 data type the pixel data of plane 1 (8 = uint8_t)
227894 0x00002711 object id ‘Image Plane’
227898 0x00000001 object count of the following object
227902 0x00000000 object id in this case 0, which means a previously loaded object will be referenced again
227906 0x00000003 backreference index of the loaded object that will be referenced - the third object that was loaded was the pixel buffer at offset 24; in other words: this image plane object will use the same pixel buffer as the previous one
227910 0x000008d8 buffer size buffer size for VPAT buffer, 2264 bytes
227914 vpat data 2264 bytes of VPAT data for plane 2
230178 0x00000008 data type the pixel data of plane 1 (8 = uint8_t)
230182 0x00002713 object id ‘DIB Info’
230186 0x00000000 object count no object follows, therefore zero
230190 0x00000028 buffer size 40 bytes
230194 40 bytes bitmap information; basically a BITMAPINFO structure containing the width (270), height (275), color format (24 bit) and channel count (1)
230234 0x00000000 unused value that is no longer relevant
230238 0x000010e width width of the loaded image (270 pixels)
230242 0x0000113 height height of the loaded image (275 pixels)
230246 6 doubles TCoordinateMap the coordinate system of image stored as x offset, y offset and the elements a11, a12, a21 and a22 of the transformation matrix; in the simplest of cases these values are just 0.0, 0.0, 1.0, 0.0, 0.0, 1.0

Phew… :sweat:

1 Like

By the way, the MIO format is closely related to what ImageToMemory produces: ImageToMemory will create exactly the same structure in memory, i.e. if you take a block of memory filled by ImageToMemory and stream it into a file with the extension *.mio then this file will be a valid and loadable MIO file. You can also parse the block of memory filled by ImageToMemory just like you would parse a MIO file…

:roll_eyes:
to be honest I did not expect something so mind boggling here… I was kindof hoping for something where I can easily retrieve width and height and pixel data :confounded:

Well, in that case you might want to have a look at the function ImageToMemoryRaw. This has been introduced in :cvb: 12.01.xxx (aka :cvb: 2016 SP 1) and simply dumps all pixel data into a block of memory (which you could then write into e.g. a binary file). You will, however, need to take care yourself of passing the information about image size and number of channels and format of the channels to whoever wants to consume the data later on…

:+1:
That looks a lot more reasonable, thanks for pointing out ImageToMemoryRaw to me!