{ "metadata": { "name": "", "signature": "sha256:bc7020c47aa9ce4f8bde7861883d0b3f8b2a20568102b3b09f0d2ebe3ef7f1db" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Motivating example: Interactive parallel face detection with OpenCV" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get a sense of what IPython.parallel might be used for,\n", "we start with an example.\n", "We will revisit pieces of this example as we learn about the different components of IPython." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "import sys, os, re, time\n", "\n", "import numpy as np\n", "\n", "from IPython import parallel" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, initialize OpenCV for simple facial detection" ] }, { "cell_type": "code", "collapsed": false, "input": [ "HAAR_CASCADE_PATH = \"haarcascade_frontalface_default.xml\"\n", "# if you have opencv installed via homebrew, this would be in\n", "# /usr/local/share/OpenCV/haarcascades/\n", "# If via Conda, it will be in:\n", "# os.path.join(sys.prefix, 'share', 'OpenCV', 'haarcascades')\n", "\n", "import cv\n", "storage = cv.CreateMemStorage()\n", "cascade = cv.Load(HAAR_CASCADE_PATH)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then define a few functions for extracting faces from images" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def extract_faces(image, faces):\n", " \"\"\"Returns any faces in an image in a list of numpy arrays\"\"\"\n", " import numpy as np\n", " A = np.frombuffer(image.tostring(), dtype=np.uint8).reshape((image.height, image.width, image.nChannels))\n", " A = A[:,:,::-1]\n", " face_arrays = []\n", " for face in faces:\n", " Aface = A[face[1]:face[1]+face[3],face[0]:face[0]+face[2]]\n", " face_arrays.append(Aface)\n", " return face_arrays\n", "\n", "\n", "def detect_faces(filename):\n", " \"\"\"Loads an image into OpenCV, and detects faces\n", "\n", " returns None if no image is found,\n", " (filename, [list of numpy arrays]) if there are faces\n", " \"\"\"\n", " \n", " image = cv.LoadImage(filename)\n", " faces = []\n", " detected = cv.HaarDetectObjects(image, cascade, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING, (100,100))\n", " if detected:\n", " for (x,y,w,h),n in detected:\n", " faces.append((x,y,w,h))\n", " if faces:\n", " return filename, extract_faces(image, faces)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we don't trust the network, we can just build a list of images from anywhere on our filesystem.\n", "Any list of images will do.\n", "For instance, you can use the path to the 'Thumbnails' directory in your iPhoto library,\n", "which vary from ~320x240 - 1024x768." ] }, { "cell_type": "code", "collapsed": false, "input": [ "pictures_dir = os.path.join('images', 'portrait')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will search `pictures_dir` for any JPEGs or PNGs.\n", "\n", "See the [download images](download impages.ipynb) notebook for a quick way to populate a folder with images from Wikimedia Commons with a certain tag." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import glob\n", "pictures = []\n", "for directory, subdirs, files in os.walk(pictures_dir):\n", " for fname in files:\n", " if fname.lower().endswith(('.jpg', '.png')):\n", " pictures.append(os.path.join(directory, fname))\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's test our output" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for p in pictures:\n", " found = detect_faces(p)\n", " if found:\n", " break\n", "\n", "filename, faces = found\n", "for face in faces:\n", " plt.figure()\n", " plt.imshow(face)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hey, that looks like a face!" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Now in parallel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we connect our parallel Client" ] }, { "cell_type": "code", "collapsed": false, "input": [ "rc = parallel.Client()\n", "all_engines = rc[:]\n", "view = rc.load_balanced_view()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we initialize OpenCV on all of the engines (identical to what we did above)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "here = os.getcwd()\n", "%px %cd $here" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%px\n", "HAAR_CASCADE_PATH = \"haarcascade_frontalface_default.xml\"\n", "\n", "import cv\n", "storage = cv.CreateMemStorage()\n", "cascade = cv.Load(HAAR_CASCADE_PATH)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and make sure `extract_faces` is defined everywhere" ] }, { "cell_type": "code", "collapsed": false, "input": [ "all_engines.push(dict(\n", " extract_faces=extract_faces,\n", "))" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can iterate through all of our pictures, and detect and display any faces we find" ] }, { "cell_type": "code", "collapsed": false, "input": [ "tic = time.time()\n", "\n", "amr = view.map_async(detect_faces, pictures[:1000], ordered=False)\n", "nfound = 0\n", "for r in amr:\n", " if not r:\n", " continue\n", " filename, faces = r\n", " nfound += len(faces)\n", " print \"%i faces found in %s\" % (len(faces), filename)\n", " for face in faces:\n", " plt.imshow(face)\n", " plt.show()\n", "\n", "toc = time.time()\n", "\n", "print \"found %i faces in %i images in %f s\" % (nfound, len(amr), toc-tic)\n" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }