ISO/IEC 19794-2:2005 Summary

This is a brief, incomplete description of fingerprint template format defined in ISO/IEC 19794-2:2005 spec, often abbreviated as ISO 19794-2:2005 or even ambiguously as ISO 19794-2. The description is detailed enough to enable reading all essential information from the template. Reading the template in full detail or writing conforming templates is not supported though, because many fields are underdocumented and many parts of the original spec aren't even mentioned here.

If you need more information than what can be found on this page, you will have to buy the original ISO/IEC 19794-2:2005 spec. Alternatively, consider sponsoring the author to get complete online description of this format and all its versions plus reference implementation in author's opensource SourceAFIS.

This document was written by Robert Važan as part of his work on SourceAFIS fingerprint matcher using someone else's brief summary of the original ISO/IEC 19794-2:2005 spec. This other brief summary was available online some time ago, but the link was unfortunately lost meantime. Author has no affiliation with ISO. This format summary is distributed free of charge under Creative Commons Attribution 4.0 International License in order to enable implementation of the format in opensource software. Nevertheless, author discourages use of ISO 19794-2 and other so-called "standard" templates in favor of plain fingerprint images.

Introduction

Human fingerprint recognition is usually performed in two separate steps: feature extraction and matching. Feature extraction takes fingerprint image (also called fingerprint sample), usually obtained from fingerprint reader (or fingerprint sensor) hardware, and produces so-called fingerprint template filled with fingerprint features useful for matching. Matching takes two fingerprint templates on input, compares fingerprint features contained in them, and produces similarity score on output, which is then compared to a threshold to produce match or non-match decision. There are many kinds of fingerprint features: minutiae (especially ridge endings and bifurcations), core and delta points, ridge shapes or patterns, orientation and ridge frequency fields, edges between minutiae, and many others.

Most fingerprint recognition systems have their own native fingerprint template format. Some people however insist on exchange of fingerprint templates between fingerprint recognition systems even though it is almost always a bad idea. ISO 19794-2:2005 is one of several fingerprint template formats that can be used for this purpose.

ISO 19794-2:2005 mainly encodes minutiae, including their position, angle, and type (ending, bifurcation, or other). It can optionally include vendor-specified extensions with additional information. It carries some fingerprint metadata, notably finger position (thumb, index, ...). It permits encoding several fingerprints in a single template.

Related formats

This format shares MAGIC and VERSION fields with ANSI 378-2004. The only way to differentiate the two formats is to look at the TOTALBYTES field.

ISO 19794-2 defines two additional template formats intended for use on smartcards. These two formats are not described here. This page describes only the main format defined in ISO 19794-2.

Layout

The template is a binary file consisting of simple fields arranged into field groups. Fields or field groups may repeat. There are no keys or tags and fields are identified only by their position in the template. Numbers are in big-endian byte order. When some field is described as "Mystery", it means I have no knowledge of what it contains.

Fields and field groups

File signature / magic number (MAGIC)

First four bytes of the template contain constant string "FMR\0" where '\0' stands for zero byte. This is a magic number (or file signature) that helps biometric software to automatically distinguish this format from other file formats. Somewhat confusingly, ANSI 378 uses the same magic number.

Format version (VERSION)

Version field contains 4-byte constant string " 20\0" (note the space before "20") where '\0' stands for zero byte. Version field makes it easy to distinguish this format from its later versions.

Unfortunately, ANSI 378-2004 uses the same version string " 20\0". The only way to differentiate this format from ANSI 378-2004 is to look at the TOTALBYTES field. This is of course a totally ridiculous situation and it makes me question motivations of people designing these formats.

Total template length in bytes (TOTALBYTES)

Total length in bytes is redundant, because the template simply ends after the last FINGERPRINT section. It might be nevertheless useful to easily find the end of the template in a stream of bytes.

Template length is encoded in 4 bytes as a big-endian unsigned 32-bit number. TOTALBYTES smaller than 24 bytes is invalid, because it cannot accommodate even the template header.

Since MAGIC and VERSION are not sufficient to tell the difference between this format and ANSI 378-2004, TOTALBYTES must be used to augment format detection. In ANSI 378-2004, template length is at least 26 bytes and it is encoded in 2 or 6 bytes. The 2-byte encoding is a single big-endian unsigned 16-bit number. The 6-byte encoding consists of two zero bytes followed by a big-endian unsigned 32-bit number. The following algorithm can determine which one of the two template formats is being decoded:

  1. Read two bytes and interpret them as a big-endian unsigned 16-bit number A.
  2. If A is 26 or higher, the template is in the ANSI 378 format. Decoding should continue according to the ANSI 378 format. Here we assume than no template in this format will be larger than 1,703,935 bytes, which is unlikely to occur in practice.
  3. Read two more bytes and interpret them as a big-endian unsigned 16-bit number B.
  4. If A is in range 1-25, which is invalid in ANSI 378, the template is in this format. Template length is 0x10000 * A + B.
  5. At this point, A is zero, because all other options have been already considered.
  6. If B is 24 or higher, a valid length in this format, the template is assumed to be in this format and B is its length. Here we assume than no template in the ANSI 378 format will be larger than 1,572,863 bytes, which is unlikely to occur in practice.
  7. Otherwise the template is in the ANSI 378 format. Decoding should continue according to the ANSI 378 format.

Image width (WIDTH)

Image width in pixels encoded as a big-endian unsigned 16-bit number.

Image height (HEIGHT)

Image height in pixels encoded as a big-endian unsigned 16-bit number.

Horizontal pixel density (RESOLUTIONX)

Image resolution (commonly called DPI), specifically its horizontal component, is stored in this field in units of pixels per centimeter. It is encoded as a big-endian unsigned 16-bit number. If sensor resolution is fractional, it is rounded to the nearest integer. The common resolution of 500dpi is equal to 197px/cm after rounding.

Vertical pixel density (RESOLUTIONY)

Like RESOLUTIONX above but for vertical resolution. It's usually equal to RESOLUTIONX.

Number of fingerprints (FPCOUNT)

An unsigned 8-bit number that indicates the number of FINGERPRINT blocks in the template.

Fingerprint (FINGERPRINT)

A single fingerprint view, essentially a single scan from fingerprint reader. Fingerprint section contains MINUTIA records and some metadata about the fingerprint, notably finger's POSITION on hands. Fingerprint section can optionally contain EXTENSIONS.

Single template can contain multiple FINGERPRINT sections. Their number is indicated by the FPCOUNT field.

Finger position on hands (POSITION)

An unsigned 8-bit number encoding hand position of the finger. It must be in range 0-10 with meaning of allowed codes explained by the table below.

CodeHandFinger
0UnknownUnknown
1RightThumb
2RightIndex
3RightMiddle
4RightRing
5RightLittle
6LeftThumb
7LeftIndex
8LeftMiddle
9LeftRing
10LeftLittle

Fingerprint quality (FPQUALITY)

This field indicates overall fingerprint quality. It is safe to ignore. Note that there is also a per-minutia quality in the MINQUALITY field.

Number of minutiae (MINCOUNT)

An unsigned 8-bit number that indicates the number of MINUTIA records that follow. MINCOUNT may be zero, which means the feature extractor failed to find any minutiae.

Minutia (MINUTIA)

Minutiae are interesting points on the fingerprint, usually ridge endings and bifurcations.

MINUTIA records span 6 bytes each and carry minutia position (MINX, MINY), angle (MINANGLE), type (MINTYPE), and optionally quality (MINQUALITY). Field MINCOUNT contains the number of MINUTIA records present. There could be no MINUTIA records if the feature extractor failed to find any minutiae.

Minutia type (MINTYPE)

Minutia type is packed in the top two bits of the first byte occupied by the MINX field. Three minutia types are supported:

BitsType
01Ridge ending
10Ridge bifurcation
00Other minutia type

Minutia X position (MINX)

Location of the minutia on the fingerprint in pixel units along X axis. Pixels are counted left-to-right, starting with zero. Minutia is in the center of the pixel specified by MINX and MINY.

MINX is a 14-bit unsigned number that is stored in the lower 14 bits of the big-endian 16-bit number that also contains MINTYPE.

Minutia Y position (MINY)

Like MINX above but for Y axis. Pixels on Y axis are counted top-down, starting with zero. MINY is stored in a 16-bit unsigned big-endian field, but only the lower 14 bits of this field are used for MINY. Upper 2 bits are zero.

Minutia angle (MINANGLE)

An 8-bit unsigned number holding quantized minutia angle. Minutiae have commonly defined angles where ridge endings point towards the ridge and bifurcations point towards the splitting valley. Zero angle points to the right and angles increase counterclockwise. MINANGLE range is 0-255. Angles in radians or degrees must be rescaled into this range and quantized.

Minutia quality (MINQUALITY)

An 8-bit field encoding minutia quality.

Total length of extension data (EXTBYTES)

A big-endian 16-bit unsigned number holding the total size of the EXTENSIONS area in bytes.

Extension data (EXTENSIONS)

Implementation-defined extension data. Its length is stored in EXTBYTES field.