2. ISO 19794-5 Images (Face)¶
2.1. Reading¶
The open()
method sets the following info
properties
version
- Version (
010
,020
or030
) nb_facial_images
- The number of representations, i.e. the number of frames
In addition, each frame has the following additional attributes:
header
The representation header (specific to each frame), containing:
For version
010
:landmark_points
gender
eye_colour
hair_colour
property_mask
expression
pose_yaw
pose_pitch
pose_roll
pose_uncertainty_yaw
pose_uncertainty_pitch
pose_uncertainty_roll
face_image_type
image_data_type
source_type
device_type
quality
When reading an image the fields
gender
,eye_colour
,hair_colour
,property_mask
,expression
,face_image_type
,image_data_type
andsource_type
are 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
,020
or030
. 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)