2. ISO 19794-5 Images (Face)¶
2.1. Reading¶
The open() method sets the following info properties
version- Version (
010,020or030) nb_facial_images- The number of representations, i.e. the number of frames
In addition, each frame has the following additional attributes:
headerThe representation header (specific to each frame), containing:
For version
010:landmark_pointsgendereye_colourhair_colourproperty_maskexpressionpose_yawpose_pitchpose_rollpose_uncertainty_yawpose_uncertainty_pitchpose_uncertainty_rollface_image_typeimage_data_typesource_typedevice_typequality
When reading an image the fields
gender,eye_colour,hair_colour,property_mask,expression,face_image_type,image_data_typeandsource_typeare converted to readable text.
2.2. Writing¶
The save() method can take the following keyword arguments:
save_all- If true, Pillow will save all frames of the image to a multirepresentation file.
append_images- A list of images to append as additional frames. Each of the images in the list can be a single or multiframe image.
version- The version of the format to use, one of
010,020or030. If not provided and if the image was loaded from an ISO 19794 image, the same version will be used.
2.3. Usage¶
First, let’s create a sample image:
>>> from PIL import Image, ImageDraw
>>> sample = Image.new("RGB",(200,300),255)
>>> draw = ImageDraw.Draw(sample)
>>> for i in range(20,100,10):
... for n in range(5):
... draw.ellipse( (i+n,i+n,200-i-n,300-i-n),outline=0)
To build a single frame image, we first need a representation header. This can be built from a list of key/value.
>>> import datetime
>>> header = dict(
... landmark_points=[],
... gender='M',
... eye_colour='BLUE',
... hair_colour='BLACK',
... property_mask=['GLASSES'],
... expression='NEUTRAL',
... pose_yaw=0,
... pose_pitch=0,
... pose_roll=0,
... pose_uncertainty_yaw=0,
... pose_uncertainty_pitch=0,
... pose_uncertainty_roll=0,
... face_image_type='FULL_FRONTAL',
... image_data_type='JPEG',
... source_type='STATIC_CAMERA',
... device_type=b'\x00\x00',
... quality=b'\x00\x00',
... )
Header must be defined on the image for the save operation to work correctly, but a minimal header is also possible (default values will be provided)
>>> sample.header = dict()
>>> buffer = io.BytesIO()
>>> sample.save(buffer,"FAC", version='010')
Using a fully defined header:
>>> sample.header = header
>>> buffer = io.BytesIO()
>>> sample.save(buffer,"FAC", version='010')
>>> print(buffer.getvalue()[0:3])
b'FAC'
>>> print(buffer.getvalue()[4:7])
b'010'
Multi-frames image is generated with the save_all option:
>>> buffer_multi = io.BytesIO()
>>> sample.save(buffer_multi,"FAC",save_all=True,append_images=[sample], version='010')
To read an image, just use the standard open function:
>>> nsample = Image.open(buffer_multi)
>>> nsample.info['nb_facial_images']
2
Access the second frame:
>>> nsample.seek(1)
>>> nsample.mode
'RGB'
>>> nsample.size
(200, 300)