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_image
  • import_mesh
  • import_landmarks
  • import_builtin_asset

Multi asset importers

  • import_images
  • import_meshes
  • import_auto

Single 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