In [ ]:
import menpo.io as pio
Before we get started, Menpo has a small cache of test assets shipped with it for example and testing purposes. You can get the filepath of this folder on your system easily
In [ ]:
data_dir = pio.data_dir_path()
print 'shipped data is at {}'.format(data_dir)
import os
os.listdir(data_dir)
A convienience function is provided in the io package to make life easier
In [ ]:
builtin_assets = pio.ls_builtin_assets()
print builtin_assets
data_path_to(filename) can be used to get a path to examples from the folder. For instance, let's say you want to get a path to the bunny.obj file...
In [ ]:
bunny_path = pio.data_path_to('bunny.obj')
print 'a bunny lives at {}'.format(bunny_path)
The 6 menpo.io importing functions can be broken into two groups
Single asset importers
import_imageimport_meshimport_landmarksimport_builtin_assetMulti asset importers
import_imagesimport_meshesimport_autoSingle Asset Importers
Let's start by seeing how the basic single importers work.
In [ ]:
bunny = pio.import_mesh(bunny_path)
print bunny
In [ ]:
%matplotlib wx
bunny.view()
This still feels a little bit like too much hard work though. For built in files just use import_builtin_asset(asset_name), no need to deal with the paths manually
In [ ]:
same_bunny_less_hassle = pio.import_builtin_asset('bunny.obj')
print same_bunny_less_hassle
All imported objects get stamped with the filepath. Note that this API may change in time if we introduce a metadata dict on shapes - don't write code to rely on it's existance!
In [ ]:
print 'this bunny came from {}'.format(bunny.filepath)
Let's try a few more examples. How about provided images?
In [ ]:
%matplotlib inline
# builtin asset handles both images and meshes
takeo = pio.import_builtin_asset('takeo.ppm')
takeo.view()
In [ ]:
%matplotlib inline
bb = pio.import_builtin_asset('breakingbad.jpg')
bb.view()
Note that landmark files are automatically detected by the IO module and applied to assets. For instance, the breakingbad.jpg had alongside it a breakingbad.pts file...
In [ ]:
%matplotlib inline
print 'breaking bad assets are: {}'.format([a for a in builtin_assets if a.startswith('breakingbad')])
print bb.landmarks
bb.landmarks.view()
Of course, if we were feeling more verbose we could have used the import_image(filepath) function having found the breaking bad image for ourselves
In [ ]:
%matplotlib inline
new_mexico = pio.data_path_to('breakingbad.jpg')
print 'Walter White lives at {}'.format(new_mexico)
walter_2 = pio.import_image(new_mexico)
walter_2.view() # exactly the same!
The three importers we have looked at so far are for retrieving single items, and expect exact filepaths. If you provide an invalid path, or a path to something that can't be imported, you will get a ValueError explaining what went wrong
In [ ]:
try:
pio.import_image('/lol/I/bet/this/isnt/an/image/on/your/system.jpg')
except ValueError as e:
print e
Multi Asset importers
The final three import_* functions are the bulk importers. All three are generators, which means they yield the files they find one at a time, and support for looping. All three also expect a glob pattern to match against.
In [ ]:
all_data_files = pio.data_dir_path() + '/*'
print 'glob to find all inbuilt files: {}'.format(all_data_files)
for image in pio.import_images(all_data_files):
print image
Note that as we used import_images() all images in the data folder were returned to us one by one. If we want to get them all we can wrap the generator in a list constructor
In [ ]:
images = list(pio.import_images(all_data_files))
print images
Or we can use the generator to be selective on import. Often when importing large datasets of images we want to crop all the images in some way. It would be problematic to import all the images into memory at maximum size and then crop them en masse. With the generator we can crop as we go, and keep memory usage low
In [ ]:
cropped_images = []
for image in pio.import_images(all_data_files):
image.crop((0, 0), (100, 100))
cropped_images.append(image)
for image in cropped_images:
print image
Of course, import_meshes() follows exactly the same rules
In [ ]:
for mesh in pio.import_meshes(all_data_files):
print mesh
# note there is only one mesh in the data file at present!
Sometimes, you may wish to import a mixed bag of data. This may include meshes, their textures, and other images. You want the meshes to have their textures attached, but you don't want the textures importing as seperate images in their own right. import_auto() sorts all this out for you
In [ ]:
for asset in pio.import_auto(all_data_files):
print asset