AIception, paint me like one of your French girls

Here is a nice thought:

What if one of the great painters (Picasso, van Gogh, Monet) was still alive?

Wouldn’t you be really excited to ask him/her to paint you?

 

Thanks to modern technology you can!

Morgan Starry

 

AIception has a public endpoint https://aiception.com/api/v2.1/artistic_image that will help “paint” any image in the “style” of any great painter.

 

Let’s get started!

We wish to implement it in Python but you can use your favorite programming language.

1. Create the following directory structure:

/blog_aiception_artistic
    aiception.py
    picasso_painted_me.py

2. Get aiception.py  <from the github here>.

3. Download and install Anaconda ( a great package, dependency and environment manager)

https://www.continuum.io/downloads

4. Create a virtual environment with Python 3.*

conda create -n blog_aiception_artistic python=3.5

5. Activate your new environment

source activate blog_aiception_artistic

6. Install extra packages like the requests HTTP library

pip install requests

7. Do your first API call

from aiception import *
from pprint import pprint

token = "YOUR_TOKEN_HERE"
image_url = "https://upload.wikimedia.org/wikipedia/commons/0/06/Morgan_Freeman,_2006_(cropped).jpg"

# call AIception API
r = face_age(token, image_url)
pprint(r)

You get the following JSON response from the server:

{'answer': {'age': 60.5},
 'created_at': 'Fri, 17 Feb 2017 19:16:20 GMT',
 'image_url': 'https://upload.wikimedia.org/wikipedia/commons/0/06/Morgan_Freeman,_2006_(cropped).jpg',
 'state': 'done',
 'this_url': 'https://aiception.com/api/v2.1/face_age/2547',
 'type': 'face_age'}

Great! So the age of the man in the picture is 60.5 years old…wait…that’s not what we want… we want to get a painting!

Let’s use the correct endpoint now, artistic_image, and we need an extra parameter for the style of the image.

8. Call the artistic_image endpoint

from aiception import *


token = "YOUR_TOKEN_HERE"
image_url = "https://upload.wikimedia.org/wikipedia/commons/0/06/Morgan_Freeman,_2006_(cropped).jpg"
style_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1280px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg"

# call AIception API (takes around 55 seconds)
r = artistic_image(token, image_url, style_url)
print(r)

It will take a while (around 55 seconds) so please be patient.

You can’t rush art!

We receive the following JSON response that is a bit more complex than the first one:

{  
   'answer':{  
      'urls':[  
         {  
            'iteration':'100',
            'image_url':'https://s3.eu-central-1.amazonaws.com/aiception.com/2017/02/task-113-N3agK7gftHq3GxfByN7tLyT16yy0Tqds71YcxQtlUs5a3AhirqjydCbMd2kF.png'
         },
         {  
            'iteration':'300',
            'image_url':'https://s3.eu-central-1.amazonaws.com/aiception.com/2017/02/task-113-9U9wNXug1TeUqolEgxEau7fyFlwBLH16HBtRadkZ4uGtTSXk0ik27S9meT9L.png'
         },
         {  
            'iteration':'200',
            'image_url':'https://s3.eu-central-1.amazonaws.com/aiception.com/2017/02/task-113-NKLC9n2yI1RcCoMukBkwpCTCf7CFY1SaBxBP9TBFIZfCNaEuCYWuCnMEKekb.png'
         }
      ]
   },
   'image_url':'https://upload.wikimedia.org/wikipedia/commons/0/06/Morgan_Freeman,_2006_(cropped).jpg',
   'created_at':'Fri, 17 Feb 2017 18:56:39 GMT',
   'type':'artistic_image',
   'style_url':'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1280px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg',
   'state':'done',
   'this_url':'https://aiception.com/api/v2.1/artistic_image/113'
}

The JSON contains 3 urls.

Each is the same stylized image at different stages (iterations) in the digital painting process. You cannot control this parameter (yet).

Nice!

9. We want to be able to automatically download the received images.

We picked the one at iteration 300 because it looks better.

import shutil

# select the image at iteration '300'
image_url = [elem['image_url'] for elem in r['answer']['urls'] if elem['iteration'] == '300'][0]

# download the image
file_name = "my_image.png"
response = requests.get(image_url, stream=True)
with open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response.raw, out_file)

Great!

 

Now it’s your turn!

Use this technology in your next great

  • mobile app
  • facebook app
  •  unity game

People will want their own photos/cats/dogs stylized.

Try the other endpoints:

r = face_age(token, image_url)
r = detect_object(token, image_url)
r = adult_content(token, image_url)
r = faces(token, image_url)

Mix and match the eye to catch…

 

Publish your own crazy idea that uses AIception API and if we love it we will share it on this blog as well!

 

 

AIception faces + asteroids

Intro

We, human beings, take a lot of pictures of our surroundings. A lot them contain human faces (strange, right?).

An interesting task (and a prerequisite for others) is to be able to find the human faces in images. This is called face detection.

AIception has a public endpoint https://aiception.com/api/v2.1/face to help us find faces in images and we will use it.

Parts:

  1. Call the AIception face endpoint
  2. Draw bounding boxes for the detected faces
  3. Crop a face
  4. Image of friends + asteroids game = faceteroids

All github code is here:

https://github.com/Razvy000/blog_aiception_faces

1. Call the AIception face endpoint

Create the following folder structure.

/aiception
   /js
       aiception.js
   index1.html

Download aiception.js from [here].

Add the following to index1.html:

<!DOCTYPE html>
<html>

<head>
    <title>HTML5 + AIception faces API = faceteroids</title>
</head>

<body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="js/aiception.js"></script>

    <script type="text/javascript">
    
    // call AIception API here

    </script>
</body>

</html>

We are now ready to call the AIception API and see what it returns! All we need is the token and an image_url.

<script type="text/javascript">
    // call AIception API here
    var token = "YOUR_TOKEN_HERE"

    var image_url = "https://upload.wikimedia.org/wikipedia/en/8/86/Einstein_tongue.jpg"
    faces(token, image_url, function(error, success) {
        if (error) {
            console.log(error);
        } else {
            console.log(JSON.stringify(success, null, 2));
        }
    });
</script>

Now, open index1.html and check your chrome console (CTRL+SHIFT+i).

Ta da:

{
  "answer": {
    "faces": [
      [         // heey we detected a face!
        12,
        64,
        167,
        219
      ]
    ]
  },
  "created_at": "Tue, 14 Feb 2017 09:12:10 GMT",
  "image_url": "https://upload.wikimedia.org/wikipedia/en/8/86/Einstein_tongue.jpg",
  "state": "done",
  "this_url": "https://aiception.com/api/v2.1/face/328",
  "type": "face"
}

If everythings looks similar to above congratulations! You made your first API call to AIception.

The answer is what we are looking for. The JSON response has a “faces” key with a list of faces. Each face is a list of coordinates.

If we use another image_url with 2 faces:

var image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg/800px-Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg"

We will get:

{
  "answer": {
    "faces": [
      [          // this is the first face detected
        531,
        201,
        716,
        387
      ],
      [          // this is the second face detected
        142,
        93,
        365,
        316
      ]
    ]
  },
  "created_at": "Tue, 14 Feb 2017 09:17:53 GMT",
  "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Albert_Einstein_a…ie_Chaplin_-_1931.jpg/800px-Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg",
  "state": "done",
  "this_url": "https://aiception.com/api/v2.1/face/329",
  "type": "face"
}

Just the coordinates makes little sense so let’s actually see what they mean.

2. Draw bounding boxes for the detected faces

What do those coordinates mean? Each list of 4 coordinates is actually a bounding box x1, y1, x2, y2 of the detected face.

Let’s add a canvas element “myCanvas” and begin our processing when the document is ready:

<!DOCTYPE html>
<html>
<head>
    <title>HTML5 + AIception faces API = faceteroids</title>
</head>
<body>

<canvas id="myCanvas" width="100" height="100" ></canvas>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="js/aiception.js"></script>

<script type="text/javascript">

    $(document).ready(function() {
        // run when ready
    }); // end ready    
</script>

</body>
</html>

Create a function that can draw green rectangles.

        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        var drawRect = function(x, y, width, height){
            context.beginPath();
            context.rect(x, y, width, height);
            context.lineWidth = 8;
            context.strokeStyle = 'green';
            context.stroke();
        }

Create a function that will call the API and draw each rectangle from the result.

        var drawFaces = function(img){
            faces(token, image_url, function(error, success) {
                if (error) {
                    console.log(error);
                } else {
                    console.log(JSON.stringify(success, null, 2));

                    for(faceid in success.answer.faces){
                            face = success.answer.faces[faceid] 
                            drawRect(face[0], face[1], face[2]-face[0], face[3]-face[1])
                    }             
                }
            });
        }

Finally load the image and call drawFaces.

        var loadImage = function(){
            var img = new Image;
            img.onload = function() {
                canvas.height = img.height;
                canvas.width = img.width;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(this, 0, 0);
            };
            img.src = image_url;

            drawFaces(img);   
        }
        
        loadImage();

 

Putting everything together this is how index2.html looks.

<!DOCTYPE html>
<html>
<head>
    <title>HTML5 + AIception faces API = faceteroids</title>
</head>
<body>

<canvas id="myCanvas" width="100" height="100" ></canvas>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="js/aiception.js"></script>

<script type="text/javascript">

    $(document).ready(function() {

        var token = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MywidGltZSI6MTQ4MDk2Nzk5MS42NjIzMTR9.jFJhqMT4969s-_V8TArPFHi5b0da6u4p_RcQA9W0OGI"
        
        var image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg/800px-Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg"

        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        var drawRect = function(x, y, width, height){
            context.beginPath();
            context.rect(x, y, width, height);
            context.lineWidth = 8;
            context.strokeStyle = 'green';
            context.stroke();
        }

        var drawFaces = function(img){
            faces(token, image_url, function(error, success) {
                if (error) {
                    console.log(error);
                } else {
                    console.log(JSON.stringify(success, null, 2));

                    for(faceid in success.answer.faces){
                            face = success.answer.faces[faceid] 
                            drawRect(face[0], face[1], face[2]-face[0], face[3]-face[1])
                    }             
                }
            });
        }

        var loadImage = function(){
            var img = new Image;
            img.onload = function() {
                canvas.height = img.height;
                canvas.width = img.width;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(this, 0, 0);
            };
            img.src = image_url;

            drawFaces(img);   
        }
        
        loadImage();       

    }); // end ready    
</script>

</body>
</html>

Cool! Try a few different images of you or your friends.

Now, let’s say you want to do something more advanced like cropping Brad’s Pitt/Angelina Jolie face and putting it into your own image. Can you do it automatically?

3. Crop a face

Create index3.html. And use the code from index2.html.

We want to create a new canvas and draw only the extracted face.

Create another canvas.

<canvas id="myCanvas" width="100" height="100" ></canvas>
<canvas id="myCanvas2" width="100" height="100" ></canvas>

Reference it.

        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        var canvas2 = document.getElementById('myCanvas2');
        var context2 = canvas2.getContext('2d');

Let’s extra the first face we find.

                        if(faceid == 0){
                            src_width =  face[2]-face[0]
                            src_height =face[3]-face[1]
                            canvas2.height = img.height;
                            canvas2.width = img.width;
                            context2.drawImage(img, face[0], face[1], src_width, src_height, 0, 0, src_width, src_height);
                        }

context.drawImage seems daunting at first but here is a great reference https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage

Putting everything together.

<!DOCTYPE html>
<html>

<head>
    <title>HTML5 + AIception faces API = faceteroids</title>
</head>

<body>

    <canvas height="100" id="myCanvas" width="100"></canvas>
    <canvas height="100" id="myCanvas2" width="100"></canvas>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="js/aiception.js"></script>
    
    <script type="text/javascript">
    $(document).ready(function() {

        var token = "YOUR_TOKEN_HERE"

        var image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg/800px-Albert_Einstein_and_Charlie_Chaplin_-_1931.jpg"

        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        var canvas2 = document.getElementById('myCanvas2');
        var context2 = canvas2.getContext('2d');

        var drawRect = function(x, y, width, height) {
            context.beginPath();
            context.rect(x, y, width, height);
            context.lineWidth = 8;
            context.strokeStyle = 'green';
            context.stroke();
        }

        var drawFaces = function(img) {
            faces(token, image_url, function(error, success) {
                if (error) {
                    console.log(error);
                } else {
                    console.log(JSON.stringify(success, null, 2));

                    for (faceid in success.answer.faces) {
                        face = success.answer.faces[faceid]
                        drawRect(face[0], face[1], face[2] - face[0], face[3] - face[1])
                        if (faceid == 0) {
                            src_width = face[2] - face[0]
                            src_height = face[3] - face[1]
                            canvas2.height = img.height;
                            canvas2.width = img.width;
                            context2.drawImage(img, face[0], face[1], src_width, src_height, 0, 0, src_width, src_height);
                        }
                    }
                }
            });
        }

        var loadImage = function() {
            var img = new Image;
            img.onload = function() {
                canvas.height = img.height;
                canvas.width = img.width;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(this, 0, 0);
            };
            img.src = image_url;

            drawFaces(img);
        }

        loadImage();

    }); // end ready
    </script>
</body>

</html>

Nice! Now you know how to extract the head. Want can you do with it?

Well we had a crazy idea that combines all the tricks we learned so far and we will share it with you.

 

4. Image of friends + asteroids game = faceteroids maybe?

Play it <here> (arrow keys, spacebar)

How we did it?

We took a very cleanly written html5 javascript canvas asteroids game and we added the AIception face detection to extract the faces and make them into asteroids!

Here is the AIception fork and the commit to make it all possible.

  • we hijacked the main loop
  • we added code for the extraction and drawing of the face

 

What’s next?

Here are some ideas to get you started with your own with AIception API:

  • extend 2. draw bounding boxes to allow the user to select a custom image_url
  • make an android / ios app that swaps faces
  • jigsaw puzzle using faces

Publish your own crazy idea that uses AIception API, if we love it we will share it on this blog as well!

 

Welcome to AIception!

AIception, the artificial intelligence platform as a service.

 

Why did we do AIception?

We are passionate about artificial intelligence and we want to share the magic with you. Artificial intelligence brought a lot of insight and fun into our work and life and we are excited to now be able to give back.

How AIception came to be?

We are are a group of friends. We are engineers and researchers that build and train our own deep neural networks.

What is AIception?

AIception is AI as a service.
We export the functionality of different task specific modules (object detection, face recognition…) through a clean and simple RESTful API.

Can I join AIception?

We will open AIception as a marketplace where you can publish and monetize your own Artificial Intelligence modules.