Creating a face detection API with Python and OpenCV (in just 5 minutes)


So you’ve just built your first awesome computer vision app.

Maybe it can detect faces in images. Or maybe your app can recognize prescription pills in photos. Or maybe your computer vision app can identify the covers of top selling books, all while displaying the latest reader reviews and the cheapest websites online to purchase them.

So the big question is…how do you wrap your computer vision app in an easy to use web API?

With more and more services heading to the cloud, your users, customers, and fellow developers are likely expecting an easy to consume web API (and probably in JSON format).

Creating a computer vision web API is actually not as hard as you think — I’ll go as far as to say it’s unbelievably easy to wrap your application in a consumable API using a Python web framework such as Django or Flask.

Personally, I’m a big fan of Django. I’ve done a ton of work with Django in the past and loved every minute of it. And while it’s a bit of overkill for a small example project like this (especially when compared to a micro-framework such as Flask),  I still think it’s an excellent choice. And of course, feel free to port this implementation into whichever framework best fits your own personal needs and preferences.

Anyway, in the rest of this tutorial I’ll be demonstrating how to create your own face detection API in only 5 minutes!

And as a bonus at the end of this article, I’ll give you a sneak peak of what’s on deck for next week — the unveiling of the (free) PyImageSearch web API.

Set your timers — Ready. Set. Go!

Looking for the source code to this post?
Jump right to the downloads section.

OpenCV and Python versions:
In order to run this example, you’ll need Python 2.7 and OpenCV 2.4.X.

Creating a face detection API with Python and OpenCV (in just 5 minutes)

After getting a ton of awesome reader feedback on the step-by-step tutorial on installing OpenCV on your Raspberry Pi 2/B+, I decided to take the same approach to this tutorial — I’ve created 8 simple, bite size steps to get your own face detection API up and running.

The goal here is that if you were to run the commands presented at each of the steps below, along with copy-and-paste the code snippets into the appropriate Django project files, that your face detection API would be up and running on your local system within 5 minutes.

However, I am going to start by assuming that you have OpenCV setup and installed. If not, then you’re going to need to install it prior to proceeding (and that’s going to break the 5 minute goal of this post).

Disclaimer: Before finishing my PhD, I used to do a lot of web application development. But over the past 3 years my focus has been entirely on the computer vision, scientific, and research side of things. If my Django code is not perfect, I’ll be the first to apologize. However, also realize that the intention of this tutorial is not to build a “bulletproof” API using all the latest Django bells and whistles. Instead, it’s meant to be a simple and concise demonstration on how you can take a computer vision application (specifically, a face detector) and turn into a web API with little effort.

Step 1: Setup your environment

The first step is to get our development environment setup and running. We’ll need only three required packages:

We need NumPy since OpenCV represents images as multi-dimensional NumPy arrays. And technically NumPy should already be installed if you have OpenCV installed as well.

The django  packages obviously contains the Django web framework.

And we’ll also include use the requests package to make interfacing with our web API much easier.

Step 2: Create our Django project

Now that the pre-requisites are installed, let’s setup our Django project:

These commands create a new Django project, adequately named  cv_api.

The cv_api  directory now contains all the necessary code and configurations to run our Django project — this code has been auto-generated and includes basic database configurations, project based options, and application settings. It also includes the ability to run a built in web server for testing (which we’ll get to later in this tutorial).

Here’s the directory structure of our new project:

Before we proceed, let’s briefly chat about the structure of a Django project.

A Django project consists of multiple apps. And one of the core paradigms of the Django framework is that each app should be reusable in any project (theoretically, anyway) — therefore, we do not (normally) place any app-specific code inside the cv_api  directory. Instead, we explicitly create separate “apps” inside the cv_api  project.

With this in mind, let’s create a new app named face_detector , which will house our code for building a face detection API:

Notice how we now have a face_detector  directory inside our cv_api  directory. Again, Django has auto-generated some boilerplate code and configurations for our face_detector  app, which we can see the contents of below:

Now that our Django project is all setup, we can get to coding.

Step 3: My personal computer vision API template

This step is where the actual “wrapping” of our computer vision project comes into place and where we are going to insert our face detection code.

The Django framework is a type of a Model-View-Template (MVT) framework, similar to a Model-View-Controller, where a “View” can be thought of as a type of web page. Inside the View you place all the necessary code to interact with Models, such as pulling data from a database, and processing it. The View is also responsible for populating the Template before it is sent to the user.

In our case, all we need is the View portion of the framework. We are not going to be interacting with the database, so the Model is not relevant to us. And we are going to ship the results of our API back to the end-user as a JSON object, so we won’t need the Template to render any HTML for us.

Again, our API is simply going to accept an image from a URL/stream, process it, and return a JSON response.

Step 3a: My personal boilerplate template when building a Python + OpenCV API

Before we dive into the code to perform the actual face detection, I want to share with you my personal boilerplate template when building a Python + OpenCV. You can use this code as a starting point when building your own computer vision API.

This boilerplate API code defines two functions: detect , which is our actual view, and _grab_image , which is a nice little convenience function to read an image from disk, URL, or stream into OpenCV format. From a code organization and reusability perspective, you probably want to put the *_grab_image* function in a “utilities” module that is globally accessible throughout the Django project. But as a manner of completeness, I have included the _grab_image  function inside the  file — I’ll leave it as a personal decision as to where you want to store this function.

Most of our time should be spent examining the detect  method. In reality, you could call this method whatever you want, but you probably want to make the name relevant to the goal the function is accomplishing. In the context of face detection, naming the main API endpoint as detect  in the face_detection  Django app seems fitting.

The detect  method accepts a single parameter, a request , which is a Django object containing properties germane to the web request.

Inside the actual view, I like to define a data  dictionary. This dictionary represents all data that will be JSON-ified and shipped back to the user. At a bare minimum this dictionary should include a success/failure flag.

From there, we need to process the actual request  and determine how the image was sent to our API.

If our image was uploaded via multi-part form data, we can simply process the data stream directly and read it into OpenCV format (Lines 17-19).

Otherwise, we’ll assume that instead of the raw image being uploaded, a URL pointing to an image was passed into our API. In that case, we’ll read the image from the URL and into OpenCV format (Lines 22-32).

Lines 34-37 is where you would actually “wrap” your computer vision app. Here you would insert any code related to processing, manipulating, classifying, etc. of your image. You’ll also want to update your data  dictionary with any relevant information related to the results of processing your image.

Finally, after all the image processing is done, we send a JSON response of the data  back to the user on Line 43.

Step 4: Inserting the face detector into my template API

Now that we have examined the boilerplate code for a Python + OpenCV web API, let’s take it and insert the face detector. Open up the cv_api/face_detector/  file and insert the following code:

As you can see, we haven’t inserted much code beyond the standard boilerplate OpenCV API template.

The first thing you’ll notice is that I’m defining the FACE_DETECTOR_PATH  (Lines 11 and 12), which is simply the path to where the pre-trained OpenCV face detector lives — in this case, I’ve included the pre-trained face detector inside the face_detector/cascades  application.

The real face detection magic takes place on Lines 41-44.

Now that we have our image in OpenCV format (whether it was uploaded via multi-part form encoded data or via URL), we start by converting our input image to grayscale. We discard any color information since color add little to face detection accuracy.

From there we load our face detector  on Line 42, supplying the path to our pre-trained face detector. Now that our face detector is loaded, we can apply the detectMultiScale  method and detect the actual faces.

I’m not going to perform an exhaustive review of the parameters to detectMultiScale  since I cover them in-depth inside my book, Practical Python and OpenCV + Case Studiesbut the important takeaway here is that these parameters influence the speed, efficiency, and the false-positive detection rate of faces in images.

The detectMultiScale  function returns a list of bounding boxes, or simply the (x, y)-coordinates, and width and height, of the faces in the image. Given this list of bounding boxes, we package them into our data  dictionary and ship them back to the user on Lines 47-53.

Not too bad, right?

As you can see, the majority of the code is still related the computer vision API boilerplate — the actual detection of the faces took only a few lines of code.

Step 5: Update the URLs to include an endpoint to our API

But before we can access our face detection API, we first need to update the project URLs to include our face detection endpoint.

Simply open up the cv_api/cv_api/  file, and update it to include a URL endpoint to our face detection view:

Step 6: Run the Django test server

Alright, now we’re ready to test out our face detection API!

Simply use your terminal to navigate back to the cv_api project root and fire up the test server:

Our web server is now available at http://localhost:8000

And if you open up your web browser and point it to http://localhost:8000/face_detection/detect/  you should see the JSON response from our face detection API:

Figure 1: Navigating our browser to the face detection API endpoint.

Figure 1: Navigating our browser to the face detection API endpoint.

Obviously, since we have not uploaded an image to our API, we are getting a JSON response of  {success: false} , implying that a face could not be detected in the (non-existent) image.

Step 7: Test out the face detection API via cURL

Before we do anything too crazy, let’s test out our face detection using cURL. We’ll start by passing the URL of this image ( of Barack Obama into our face detection API:


Figure 2: Passing the URL of this Barack Obama image into our face detector API.

Let’s construct the command to interact with our face detection API via cURL:

And sure enough, based on the output we were able to detect Obama’s face (although we can’t yet visualize the bounding box, we’ll do that in the following section).

Let’s try another image, this time uploading via file instead of URL:

Figure 3: A picture of myself outside Horseshoe Bend, AZ. Will the face detector API be able to detect my face in the image?

Figure 3: A picture of myself outside Horseshoe Bend, AZ. Will the face detector API be able to detect my face in the image?

Again, we’ll need to construct our cURL command, assuming that the name of the above file is adrian.jpg :

And based on the JSON response we were indeed about to detect the face in the image.

Step 8: Write some Python code to interact with the face detection API

Using cURL to test out our face detection API was simple enough — but let’s write some actual Python code that can upload and interact with images sent to our API. This way we can actually ingest the JSON response and draw the bounding boxes surrounding the faces in the images.

Open up a new file, name it , and include the following code:

We’ll start by importing the requests  package to handle sending and receiving data from our API. We’ll also import cv2  for our OpenCV bindings.

From there, Lines 6-20 handle uploading an image via URL to our face detection API.

All we need to do is define a payload  dictionary that contains a url  key, with the corresponding value being our image URL of Barack Obama above. We then ship this payload dictionary to the face detection endpoint (Lines 6-11), where our API responds with the number of faces detected in the image, along with the bounding boxes of the faces. Finally, we take the bounding boxes and draw them on the actual image (Lines 15-20).

We’ll also upload an image from disk to our face detection API on Lines 24-35. Just like uploading an image via URL, uploading from an image from disk is just as simple — we just need to specify the files  parameter rather than the data  parameter when making a call to .

To see our script in action, just execute the following command:

First, we’ll see the image of the bounding box drawn around Obama’s face:

Figure 4: Taking the JSON response from our face detection API and drawing the bounding box around Obama's face.

Figure 4: Taking the JSON response from our face detection API and drawing the bounding box around Obama’s face.

Followed by the successful detection and bounding box around my face:

Figure 5: Uploading an image from disk to our face detection API -- once again, we are able to detect the face and draw the bounding box surrounding it.

Figure 5: Uploading an image from disk to our face detection API — once again, we are able to detect the face and draw the bounding box surrounding it.

Clearly our face detection API is working! And we were able to utilize it via both image file upload and image URL.

Faces aren’t being detected in my images. What gives?

If you downloaded the code to this post and gave it a try with your own images, you might have run into circumstances where faces were not detected in your images — even though the faces were clearly visible.

So what gives?

While Haar cascades are quite fast and can obtain decent accuracy, they have two prominent shortcomings.

The first is parameter tuning — you’ll need to tweak the parameters of detectMultiScale  to get the detection just right for many images. It can be a real pain, especially if you are looking to process many images in bulk and can’t visually inspect the output of each face detection.

The second shortcoming of Haar cascades is that they can be highly prone to false positives, meaning that faces are detected when there really aren’t any faces there! Again, this problem can be fixed by tuning the parameters of detectMultiScale  on a case-by-case basis.

In reality, Haar cascades and the Viola-Jones detector, while effective, have ran their course in computer vision history. For highly accurate object detectors we now rely on HOG + Linear SVMs and deep learning based methods, especially Convolutional Neural Networks.

That all said, it’s hard to beat the pure speed of Haar cascades, even if their accuracy and false-positive rate is a bit sub-par, at least compared to today’s state-of-the-art techniques.

Bonus: A live example of the face detection API

Want to give the face detection API a try? No problem.

I already have a face detection API instance spun up and running. You can find the face detection API endpoint here:

And here’s another cURL example of detecting faces in an image to get you started. Only this time we are using the live API endpoint:

So given the URL, I bet you can guess what next week’s announcement is…but I’ll leave the rest until next Monday.


In this blog post we learned how to wrap our computer vision applications into an easy to use and consume, JSON web API. We utilized the Django web framework to build our API, but we could use any other Python web framework such as Flask — it really depends on your personal preference and how simple or advanced you want your API to be.

I also shared my personal boilerplate API code that you can use to wrap your own computer vision applications and make them web-ready.

Finally, I gave a sneak preview of next week’s big announcement — the (free) PyImageSearch API.

So, what’s next?


If you enjoyed this blog post and want to learn more about computer vision and OpenCV, I would definitely recommend taking a look at my book, Practical Python and OpenCV + Case Studies.

Inside my book you’ll continue to learn all about face detection (including an explanation of the detectMultiScale  parameters I mentioned earlier in this post) in both images and video, tracking objects in videorecognizing handwritten digits, and even how to identify book covers in a snap of your smartphone.

If these topics sound interesting to you, definitely take a look and consider grabbing a free sample chapter.


If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL! Sound good? If so, enter your email address and I’ll send you the code immediately!

, , , , , , , ,

89 Responses to Creating a face detection API with Python and OpenCV (in just 5 minutes)

  1. Eugene May 11, 2015 at 12:13 pm #


    Nice article 🙂 I did pretty similar stuff with nodejs and here’s a friend warning: OpenCV cascade classifier is not thread-safe. I’m not quite sure how Django serves multiple request, but simultaneous calls to detectMultiScale function on same classifier can crash the app. Cheers!

    • Adrian Rosebrock May 11, 2015 at 12:53 pm #

      Hey Eugene, thanks for the tip! I configured the Django webserver to allocate one thread per request, thus each request has its own independent thread. Theoretically, that should prevent the problem.

      • Vivek April 18, 2018 at 12:26 am #

        Could you please guide us on how to configure Django webserver to allocate one thread per request?

        Would be helpful.

        Thanks and Regards,

        • Adrian Rosebrock April 18, 2018 at 3:01 pm #

          Hey Vivek — that sounds like a great question for the Django community. I am not a Django expert and would not want to give you poor advice.

  2. Sechaba September 17, 2015 at 5:23 am #

    Hello Adrian

    This is a really cool article.
    This article talks about face detection. Are there any similar articles for facial comparison for django. My goal is to uniquely identify a user with their profile picture.


    • Adrian Rosebrock September 17, 2015 at 7:33 am #

      Hey Sechaba, great question. I haven’t covered face recognition on the PyImageSearch blog yet, but I do cover it in the PyImageSearch Gurus course.

  3. ahkhan October 23, 2015 at 1:27 pm #

    Thanks for this code, was extremely useful. I wanted to be able to extend the APIs to be able to actually serve back images to the browser to make it easier to test/check the image operations i’m running on the server. So for example I could carry out a cv2.rectangle operation on the image to highlight the face detected and return that image to the caller.

    see snippet below to return any opencv “image” to the browser :

    • Adrian Rosebrock October 24, 2015 at 7:06 am #

      Awesome, thanks for sharing! 🙂

    • Ghassan Albadowi April 6, 2016 at 8:03 pm #

      if I’m using cURL how to get the image ?

  4. Muhammad October 31, 2015 at 10:25 am #

    THANKS a lot

  5. Jim November 19, 2015 at 12:32 am #

    Where can I find your copy of pre-trained face detector inside the face_detector/cascade?

    • Adrian Rosebrock November 19, 2015 at 6:18 am #

      The Haar face detector cascade is included in the source code download of the post. Additionally, you can grab it from the OpenCV repository

  6. Timco January 9, 2016 at 10:54 am #

    Hi, I got stuck on point 3a, please where I have to save boilerplate code?? 🙂

    • Adrian Rosebrock January 9, 2016 at 5:33 pm #

      That goes inside the I would suggest using the code download form at the bottom of the post to download my original code so you can look at the directory structure of the project.

  7. cs January 16, 2016 at 12:43 pm #

    I using Python 3 for the testing and is no longer support . have to replace with cv2.CASCADE_SCALE_IMAGE

    • Adrian Rosebrock January 17, 2016 at 5:27 pm #

      Thanks for sharing!

  8. SaMnCo February 19, 2016 at 12:02 pm #

    I’m trying to containerize this and make it work on various hardware, then add face recognition on top of the detection.

    However, for some reason I don’t understand, I always get stuck with :

    curl -X POST ‘http://localhost:8000/face_detection/detect/’ -d ‘url=’ ; echo “”
    {“num_faces”: 0, “success”: true, “faces”: []}

    Whatever the image, it always answers 0, and I don’t get why. Would you mind just having a look at the www folder in the repo and see if you detect something? I have spent ages on it, and I don’t get it. Frustration.

    Using a similar core out of the API does actually see the face(s) in images.

    Thanks in advance,

    • Adrian Rosebrock February 19, 2016 at 1:48 pm #

      I just tested the curl command on my system and it indeed works properly. You might be using a different version of OpenCV. Unfortunately, the parameters to detectMultiScale can be a bit finicky and you often need to play with them. I discuss each of the parameters to detectMultiScale (and how to tune them) inside Practical Python and OpenCV.

  9. Yesi March 7, 2016 at 5:32 pm #

    Hi Adrian,

    Is really awesome article. I did the complete post and works :), thanks. Later, i used the Yes and Mouth.xml however I can’t detect the mouth in my pics.

    🙁 Any clue? thanks a lot

    • Adrian Rosebrock March 8, 2016 at 4:15 pm #

      Be sure to tune the parameters to detectMultiScale, specifically the minNeighbors and scaleFactor. They have a dramatic impact on detection accuracy.

  10. Esha Mishra March 20, 2016 at 7:39 pm #

    Thanks Adrian for this simple explaination on the face detection. I have been thinking of a high school research project to detect gender for a given photograph using openCV3. I am new to the field but love to use this project to enhance my knowledge in this field. Any guidance and direction will be very appreciated.

    Thanks – Esha

    • Adrian Rosebrock March 21, 2016 at 7:29 am #

      There are many ways to apply gender + age detection. Currently, the most accurate methods use Convolutional Neural Networks (CNNs), but these methods require a lot of labeled data. That said, for a high school research project I would suggest using a much more simple feature-based approach such as Eigenfaces or LBPs. These methods are traditionally used for face recognition, for the same features can also be used for age + gender identification as well.

  11. Ghassan Albadowi March 28, 2016 at 2:04 am #

    thank you for this post , its great

    I’m trying to use boilerplate code with code in this post :
    Detecting machine-readable zones in passport images

    would you help me ?

    • Adrian Rosebrock March 28, 2016 at 1:31 pm #

      What specifically are you having a problem with? Make sure you download the code to both blog posts. Your web API endpoint should accept an input image, pass the image onto the MRZ code, and then return the result.

      • Ghassan Albadowi March 29, 2016 at 7:42 am #

        Thank you for your replay,

        How to pass the image to file ? and get the result to use it in view

        • Adrian Rosebrock March 29, 2016 at 3:42 pm #

          You’ll need to modify the two files and merge them together. I don’t recommend calling directly from the view. Start with the boilerplate code in this post (Step 3a) and then insert the MRZ code, starting at Line 34

  12. Thales May 16, 2016 at 5:31 pm #

    Hi, I am brazilian and my english is not very good, so I have gone unnoticed at some point. I created a django project and an application the way you taught, but when I run it, however says “No module named ‘cv2′”

    • Adrian Rosebrock May 17, 2016 at 11:34 am #

      Make sure you have OpenCV and Django installed into the same virtual environment, otherwise you will not be able to import the OpenCV bindings.

      • Thales May 17, 2016 at 4:40 pm #

        I’m trying to get out of the virtual environment, while it worked. I’m trying to make a django application to load any image and apply some digital image processing filter and return the filtered image, have any suggestions? thanks a lot for the reply!

        • Adrian Rosebrock May 19, 2016 at 6:11 pm #

          If you’re trying to exit the virtual environment you can use the deactivate command. As for your Django application, I would suggest accepting an uploaded image, processing it to your liking, and then returning a URL where the end user can access the processed image.

          • Thales May 20, 2016 at 9:29 pm #

            Thanks again!

  13. Farid June 4, 2016 at 7:56 pm #

    hai adrian,i am newbie in linux and python,i want to try motion detection with open cv,and stream it from web in another computer.could you help me how to do it? sorry for bad english

    • Adrian Rosebrock June 5, 2016 at 11:25 am #

      It is certainly possible. I do not have any tutorials related to video streaming from one system to another, but I’ve made note of the suggestion and will try to give it in a future blog post.

  14. Orhan June 11, 2016 at 7:33 am #

    Did you work on Gender Detection?
    Good day

    • Adrian Rosebrock June 12, 2016 at 9:35 am #

      I don’t have any public tutorials on gender detection and recognition, but this is something I would like to cover in the future.

  15. Paula Moraes July 15, 2016 at 6:37 pm #

    Hi Adrian,

    I currently have a CV project that runs locally with live feed from picam. Do you think it’s possible to turn this code into an Web API ?
    I mean, I’d have to pass my camera device (e.g. /dev/video0) as a parameter and the web api would loop over it? Or each captured frame individually would have to be send for the API? Thanks

    • Adrian Rosebrock July 18, 2016 at 5:23 pm #

      You can certainly send your frames to an API endpoint, that’s not an issue. But keep in mind that this will be much slower than simply processing the frames locally. You’ll be introducing lots of network I/O which will really slow down the process.

      • Lea January 22, 2020 at 3:33 pm #

        Would introducing sockets help make this faster. I’m trying to run face recognition on a user’s camera stream from their phone.

  16. abderrahmane August 14, 2016 at 1:40 pm #

    Thnaks ,it’s very useful

  17. Ash September 15, 2016 at 8:03 am #

    While running the code in python, the error came like
    Import error: requests module.
    I have downloaded the zip file from mail.pls help.

    • Adrian Rosebrock September 15, 2016 at 9:26 am #

      Make sure you have installed the requests Python package (Step #1):

      $ pip install requests

  18. Gregory October 4, 2016 at 6:52 pm #

    Note that must be changed in newer versions of django as the library ‘patterns’ as well as string paths to applications appear to no longer be used. I’m using 1.10.2 and was able to resolve the issue with the following

    • Adrian Rosebrock October 6, 2016 at 7:01 am #

      Thanks for sharing Gregory!

  19. vivek October 24, 2016 at 7:06 am #

    hi adrian how to use predict function to get name for face stored in database and confidence for recognition and if face is unknown to database how to show its confidence in open cv python ?
    help me on this please….

    • Adrian Rosebrock October 24, 2016 at 8:24 am #

      Hey Vivek — I assume you are referring to creating a piece of software what can not only detect faces in images but also recognize who the face is? If so, that is called “facial recognition”. Popular algorithms include Eigenfaces and LBPs for face recognition. You can also use CNNs for face recognition as well. I cover these methods for face recognition inside the PyImageSearch Gurus course.

  20. ritesh patel January 10, 2017 at 9:58 am #

    hi this is grate thing to use make web api of python code. i have just want to know that if instead of image if some one want to upload video than what change we should do?? suppose we have to count number persons pass from particular area than how to do that if we have python code ready. how to use web api with it. i think we need to upload video but i dont know how to do that. so if you guide me regarding to this than it will be helpful. thanks

    • Adrian Rosebrock January 10, 2017 at 1:01 pm #

      Your goal is to process a video rather than an image? If so, you’ll want to update the code to work with reading video streams. I demonstrate how to use the cv2.VideoCapture method in in this blog post. I discuss it more thoroughly inside my book, Practical Python and OpenCV.

  21. Peiyang March 9, 2017 at 11:42 am # was replaced with cv2.CASCADE_SCALE_IMAGE
    so in, line 44,
    minSize=(30, 30),
    should be corrected or else python won’t work

    • Adrian Rosebrock March 10, 2017 at 3:50 pm #

      You are correct if you are using OpenCV 3, the flag should be cv2.CASCADE_SCALE_IMAGE. For OpenCV 2.4 (when this blog post was written) the flag is

  22. tuba March 18, 2017 at 2:24 am #

    hi adrian thanks for the post. i just tried it but i couldnt pass an image file myself, i’ve been using postman as a rest client but the server was requiring urls for each time. i believe the code should grab the file, could you please help me how can i post the image file

    • Adrian Rosebrock March 21, 2017 at 7:38 am #

      I haven’t used postman, but I have provided a cURL example of how to POST the image in this post.

  23. abdou Elmes April 6, 2017 at 7:50 pm #

    Hello, im working on an api that works with openCv and i was wondering what is the best way to receive images from the android app that will capture them. in order to read them later with cv2.
    i will have to send 2 images, 1 string and 1 json object.

    • abdou Elmes April 6, 2017 at 7:51 pm #

      note that the android doesnt have have to save them , so i cant get them by url .

      • Adrian Rosebrock April 8, 2017 at 12:52 pm #

        I haven’t developed an Android app before, but I would suggest looking into “message passing” libraries for this.

  24. Nurulhasan August 1, 2017 at 12:08 am #

    Thanks sir. Really helpful article.can it extended to face recognition??

  25. Kevin Hadi August 26, 2017 at 9:23 pm #

    Superb article. i got a question though. if i want to make an android application that detect faces online combining with django. will it works? like the android upload the image to the django’s db then the app read the image’s url and then processed it. afterward the detected image is saved on the db once again then downloaded on the android. will it works? since you’re using cURL i thought it might work thoguh

    • Adrian Rosebrock August 27, 2017 at 10:34 am #

      Yes, using this template you can build your own computer vision REST-like APIs. You would need to perform the face detection + recognition on the server and then send the result back to the device. I cover face recognition inside the PyImageSearch Gurus course.

      • Kevin Hadi August 31, 2017 at 7:27 am #

        whoa awesome. one more question though. your process is on because the template didnt need to play with db at all. if i build my own APIs, the process should be on or

        • Adrian Rosebrock August 31, 2017 at 8:27 am #

          Any code logic should be taken care of in the view. Any database models inside

          • Kevin Hadi August 31, 2017 at 3:24 pm #

            ahh i see, thank you for the insight

          • Kevin Hadi August 31, 2017 at 7:14 pm #

            i want to ask one more question haha. where do you place the

          • Adrian Rosebrock September 1, 2017 at 11:59 am #

            The script can be placed anywhere on your system.

          • Kevin September 10, 2017 at 3:12 am #

            hi im getting error when running your code even after download it directly from your website.

            the error says

            ValueError: No JSON object could be decoded


            r =, data=payload).json()

            when running

            do you have any idea what the error means? thank you

          • Adrian Rosebrock September 11, 2017 at 9:13 am #

            If a JSON object could not be decoded then the server returned an invalid response. This could be due to an invalid image trying to be uploaded. Double-check your code and try again. I would also suggest using cURL to validate this as well.

  26. Theo September 6, 2017 at 1:20 pm #


    I am getting a Bad Request (400) when trying to perform the obama cURL operation. I am using an Ubuntu 16.04 VPS, and I have two putty windows open, one with the django server running and the other i run the cURL command. Can’t figure out why it is a bad request.

    Thanks for your tutorials by the way, they’ve been very helpful!

    • Adrian Rosebrock September 7, 2017 at 7:00 am #

      Hi Theo — I’m not sure what the exact issue is here. You may be running a different version of Django than the one I was using when writing this tutorial a few years ago or your host server may be misconfigured.

  27. ABCDE January 31, 2018 at 7:27 am #

    How to deploy it on heroku ?

  28. Carlos January 31, 2018 at 10:01 am #

    I have a question, If i want only recognize my face and labeling with my name, I should training a cascade classifier only with my face? and how put a label?. Thank you for your help

    • Adrian Rosebrock January 31, 2018 at 10:05 am #

      You cannot use Haar cascades for face recognition, only face detection. Popular face recognition algorithms include Eigenfaces, LBPs for face recognition, and using deep learning to construct face embeddings. I cover face recognition inside the PyImageSearch Gurus course. I hope that helps give you a starting point!

  29. Sarah February 5, 2018 at 12:43 pm #

    Hi Adrian.
    For face detection, is it possible to know the coordinate of the detected face?

    • Adrian Rosebrock February 6, 2018 at 10:11 am #

      Line 47 gives you the (x, y)-coordinates of each detected face.

  30. Nishank Singla February 24, 2018 at 8:14 pm #

    That’s a great article. I was reading it because I was finding the solution for the problem I am facing in face detection. There are 2 problems which I faced.
    1.) OpenCV was detecting wrong face boundaries i.e. there was no face in the face boundary that was detected,
    2.) If I upload a high-resolution image for example (2000,1500), sometimes the program was not able to detect the face.
    3.) Also, I upload different sizes of images, then minSize=(30, 30) parameter does not helps.

    Can you provide me your views or solution regarding these problems?

    • Adrian Rosebrock February 26, 2018 at 1:57 pm #

      I actually just published an updated tutorial on face detection using deep learning. Take a look as it will help address your questions and reduce the number of parameters you have to tune.

  31. amine February 25, 2018 at 6:42 pm #

    Thank you very much Adrian. you are amazing man. keep up.

    • Adrian Rosebrock February 26, 2018 at 1:52 pm #

      Thank you amine 🙂

  32. Muhammad April 2, 2018 at 9:00 am #

    thank you for your tutorial adrian…but i have a problem that when i run the server from the command line just like what you say
    there is an error in the import of patterns in that line in your code

    from django.conf.urls import patterns, include, url

    the error is that django not support the import patterns
    and i use 1.11 django version with python 2.7 just like u and i run your original code too
    can i get some help please!!

  33. Yiğit April 30, 2018 at 4:40 pm #

    Hi Adrian,

    Your tutorials might be the best there are, explaining each line of code!

    Got a problem running the server though, it seems import patterns has been depreciated since Django 1.8. Would it be possible to update the tutorial.

    Thank you for sharing your knowledge!

    • Adrian Rosebrock May 1, 2018 at 1:42 pm #

      Hi Yiğit, I’ll update the post soon. In the meantime, the changes are very minor and you should be able to work through them with a little bit of research.

  34. Emanuele Martini June 15, 2018 at 12:55 pm #

    dear Adrian,
    is it possible to pass frames from webcam to the using this django framework?

    • Adrian Rosebrock June 19, 2018 at 9:04 am #

      You could, but you would need to:

      1. Poll frames from the camera
      2. Upload each frame to the API
      3. Display the results

      If you’re looking for real-time performance you should perform the face detection locally on the device.

  35. Jibin John November 27, 2018 at 1:36 am #

    Which version of Django that you have used for his project?. I think the code is now deprecated.

    • Adrian Rosebrock November 30, 2018 at 9:35 am #

      This tutorial is over 3 years old at this point so I cannot recall which version of Django I used. Either way, yes, the Django library has changed a lot since then. I would suggest you refer to the Django documentation if you would like to reimplement.

  36. Pliable Pixels April 28, 2019 at 10:33 am #

    Adrian, thanks for the article. This was my initial motivation to try my own.
    For those reading, if you want to try a flask version that is updated to work with recent versions, see (of course, Adrian’s post is credited there)

    • Adrian Rosebrock May 1, 2019 at 11:51 am #

      Nice job, Pliable! And thank you for crediting the blog as well, I really appreciate that.

  37. hassan September 25, 2019 at 6:05 am #

    I am trying use that API for face comparison. I mean i have two face, on which I will make comparison that either these both faces are same or not. How I can modify that API to accept two images, via curl command. Pleas help me out to send two images via URL.
    thanks for your cooperation


  1. Announcing the PyImageSearch Web API - PyImageSearch - May 18, 2015

    […] been planning on building this API for awhile now, and finally last weeks blog post on building a face detection Web API was just the kick in the ass I needed to finish up the project and push it […]

Before you leave a comment...

Hey, Adrian here, author of the PyImageSearch blog. I'd love to hear from you, but before you submit a comment, please follow these guidelines:

  1. If you have a question, read the comments first. You should also search this page (i.e., ctrl + f) for keywords related to your question. It's likely that I have already addressed your question in the comments.
  2. If you are copying and pasting code/terminal output, please don't. Reviewing another programmers’ code is a very time consuming and tedious task, and due to the volume of emails and contact requests I receive, I simply cannot do it.
  3. Be respectful of the space. I put a lot of my own personal time into creating these free weekly tutorials. On average, each tutorial takes me 15-20 hours to put together. I love offering these guides to you and I take pride in the content I create. Therefore, I will not approve comments that include large code blocks/terminal output as it destroys the formatting of the page. Kindly be respectful of this space.
  4. Be patient. I receive 200+ comments and emails per day. Due to spam, and my desire to personally answer as many questions as I can, I hand moderate all new comments (typically once per week). I try to answer as many questions as I can, but I'm only one person. Please don't be offended if I cannot get to your question
  5. Do you need priority support? Consider purchasing one of my books and courses. I place customer questions and emails in a separate, special priority queue and answer them first. If you are a customer of mine you will receive a guaranteed response from me. If there's any time left over, I focus on the community at large and attempt to answer as many of those questions as I possibly can.

Thank you for keeping these guidelines in mind before submitting your comment.

Leave a Reply