In [1]:
import (
    "flag"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
    "strings"
    "time"
    "unicode"
    "fmt"
    "encoding/json"

    "github.com/machinebox/sdk-go/facebox"
)

Connect to MachineBox

To perform facial recognition, we are going to use MachineBox's FaceBox. If you haven't heard of MachineBox, check them out! They provide state of the art machine learning technology inside a Docker container which you can run, deploy and scale.

Here we will assume that we have MachineBox's facebox running locally.


In [2]:
faceboxClient := facebox.New("http://localhost:8080")

Train FaceBox to recognize a face

We are now going to walk over images of faces in a directory and provide these faces to facebox. FaceBox will learn how to recognize these faces in images. The faces that we are going to use here are of someone that is probably familiar to most:

trump1.jpg trump2.jpg trump3.jpg

In [3]:
inDir := "/home/dwhitena/go/src/github.com/dwhitena/pach-machine-box/data/train/faces1"

In [4]:
// Walk over images in the training directory.
if err := filepath.Walk(inDir, func(path string, info os.FileInfo, err error) error {

    // Skip any directories.
    if info.IsDir() {
        return nil
    }

    // Open the training image file.
    f, err := os.Open(filepath.Join(inDir, info.Name()))
    if err != nil {
        return err
    }
    defer f.Close()

    // Teach FaceBox the input image.
    if err := faceboxClient.Teach(f, info.Name(), "trump"); err != nil {
        return err
    }

    return nil
}); err != nil {
    log.Println(err)
}


// warning: redefined identifier: err
// warning: call to deferred function f.Close() returned [<nil>] values, expecting zero: %!v(MISSING)
// warning: redefined identifier: err
// warning: call to deferred function f.Close() returned [<nil>] values, expecting zero: %!v(MISSING)
// warning: redefined identifier: err
// warning: call to deferred function f.Close() returned [<nil>] values, expecting zero: %!v(MISSING)

Using the trained FaceBox to recognize a face

Now that we have trained FaceBox to recognize our face of interest, we can try to identify this face in an image. For example, let's try to recognize this face in the following image:

First, let's create a struct that will allow us to unmarshal the JSON response from FaceBox. This JSON response should include an indication that faces where detected along with labels of recognized faces and their locations.


In [5]:
// IdentifiedFaces includes information about the faces
// identified in an image.
type IdentifiedFaces struct {
    Success    bool           `json:"success"`
    FacesCount int            `json:"facesCount"`
    Faces      []facebox.Face `json:"faces"`
}

Then we can use the Check() method on the FaceBox client to check the image for recognized faces:


In [6]:
// Open the input image.
f, err := os.Open("/home/dwhitena/go/src/github.com/dwhitena/pach-machine-box/data/unidentified/image1.jpg")
if err != nil {
    log.Println(err)
}
defer f.Close()

// Teach FaceBox the input image.
faces, err := faceboxClient.Check(f)
if err != nil {
    log.Println(err)
}


// warning: redefined identifier: err

Finally, we can output the detected face information:


In [7]:
// Prepare the output.
output := IdentifiedFaces{
    Success:    true,
    FacesCount: len(faces),
    Faces:      faces,
}

// Marshal the output.
outputData, err := json.MarshalIndent(output, "", "  ")
if err != nil {
    return log.Println(err)
}

fmt.Println(string(outputData))


Out[7]:
{
  "Success": true,
  "FacesCount": 13,
  "Faces": [
    {
      "Rect": {
        "Top": 199,
        "Left": 677,
        "Width": 107,
        "Height": 108
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 96,
        "Left": 1808,
        "Width": 89,
        "Height": 90
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 163,
        "Left": 509,
        "Width": 108,
        "Height": 108
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 186,
        "Left": 2186,
        "Width": 89,
        "Height": 89
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 166,
        "Left": 1638,
        "Width": 90,
        "Height": 89
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 116,
        "Left": 1453,
        "Width": 107,
        "Height": 107
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 405,
        "Left": 1131,
        "Width": 89,
        "Height": 89
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 206,
        "Left": 1300,
        "Width": 90,
        "Height": 89
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 176,
        "Left": 1957,
        "Width": 90,
        "Height": 89
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 495,
        "Left": 1462,
        "Width": 62,
        "Height": 62
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 1158,
        "Left": 2181,
        "Width": 62,
        "Height": 63
      },
      "ID": "",
      "Name": "",
      "Matched": false
    },
    {
      "Rect": {
        "Top": 175,
        "Left": 963,
        "Width": 108,
        "Height": 108
      },
      "ID": "trump3.jpg",
      "Name": "trump",
      "Matched": true
    },
    {
      "Rect": {
        "Top": 544,
        "Left": 1647,
        "Width": 75,
        "Height": 75
      },
      "ID": "",
      "Name": "",
      "Matched": false
    }
  ]
}
// warning: redefined identifier: err

In [ ]: