API Documentation

 

LPR (License Plate Recognition) API 2.0 (Coding Examples)


Our LPR API can be deployed in one of two basic approaches; one allows for the entire process to be performed at the location in real-time, the other transmits all the images from multiple locations to a central location and performs the LPR/OCR process there via our LPR API at some later point in time. When done on the spot, the information captured of the plate alphanumeric, date-time, location identification, and any other information that is required is completed and transmitted to remote computers for further processing if necessary, or stored at the location for later retrieval.


Please note that the output from this service might require a further sanity check, since there are a lot of complications that can arise during the recognition and translation process.

To achieve the highest possible recognition speed, the image size is a key factor.

 

Do Not Send The Same Image More Than Once

Our system will take one credit off from your account balance when result in XML or Json format is returned regardless of what the result turns out to be. So please be sure to have a mechanism in place in your system to prevent the same image from being sent to the API service more than once.

REST API Description

This API uses multipart POST HTTP method. Ensure HTTP POST is a multipart/form-data request. The following three parameters and their values are required.

Parameter Name Parameter Value Used in URL
API Key accesscode xxxxx-xxxxx-xxxxx-xxxxx POST https://lpr.recognition.ws/v2?acccesscode=xxxxx-xxxxx-xxxxx-xxxxx&saveimage=TRUE
Input Image* Image File* JPG, JPEG, PNG, GIF, BMP POST https://lpr.recognition.ws/v2?acccesscode=xxxxx-xxxxx-xxxxx-xxxxx&saveimage=TRUE
Save Image** saveimage** TRUE or FALSE (default: FALSE) POST https://lpr.recognition.ws/v2?acccesscode=xxxxx-xxxxx-xxxxx-xxxxx&saveimage=TRUE
Data Format*** format*** XML or JSON (default: XML) POST https://lpr.recognition.ws/v2?acccesscode=xxxxx-xxxxx-xxxxx-xxxxx&saveimage=TRUE&format=JSON
* Only one image file is allowed in a POST request. A POST request with multiple files would be rejected immediately. Only the first found license plate will be processed if an input image contains more than one license plate.
** Set parameter "saveimage" to "TRUE" if you'd like our system to save the input image so that later you can log in to your account to review it. Set the value of this parameter to "FALSE" otherwise.
*** Set parameter "format" to "JSON" if you'd like the service to send data in Json format. If you don't include this parameter at all in the API URL, or explicitly set the value of this parameter to "XML" to get data in XML format.

        
    <html>
       <form enctype="multipart/form-data" action="https://lpr.recognition.ws/v2?accesscode=xxxxx-xxxxx-xxxxx-xxxxxx&saveimage=FALSE" method="POST">
          Choose an image to process: <input name="anyName" type="file" />
          <input type="submit" value="Go" />
       </form>
    </html>
        
    

 

Input Image Specs

Standard license plate characters have to meet the specification of at least 25 pixels high characters. In general, OCR can decode characters lower than this requirement but not at the extremely high(99.8%) accuracies required.

From an APR/OCR perspective, resolution well above the 25-pixel requirement does not significantly translate into better performance but can lead to significantly increase real-time execution due to larger image sizes. To mitigate this, incoming images are typically resized such that the nominal plate character height is in a range of 25-35 pixels high. This creates a problem for motorcycle images since the resizing appropriate for passenger cars and trucks causes motorcycle plate characters to fall well below the 25-pixel requirement. The vehicle type input into ALPR would allow the algorithm to dynamically adjust the resizing, based on the known vehicle type, in order to capture motorcycle plates accurately. As it stands today, motorcycle plates are typically missed completely or recognized with much higher error rates.

More often than not, the "jurisdiction" characters are much smaller than the plate characters.

Input Image Specs Without Reading Region/Country To Read Region/Country
Height of the License Number portion in a License Plate 20 - 150 pixels 100 - 750 pixels
Width of the License Number portion in a License Plate 80 - 400 pixels 80 - 400 pixels
Length of License Number 4 - 10 characters 4 - 10 characters
Size of Input Image < 2.0 MB < 2.0 MB

Output in XML or Json

  • License Number: Plate number in ASCII
  • Region: USA State or Canadian Province
  • Country: Canada or USA
  • Position of the License Number portion in an input image: Top(pixels), Left(pixels), Width(pixels), Height(pixels). The origin(0,0) is the top-left corner of an input image.
        

    // XML

    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <LPR Version="2.0" Date="4/22/2015" Status="SUCCESS">
      <License_Number>ABCD-1234</License_Number>
      <Region>New York</Region>
      <Country>USA</Country>
      <Confidence>0.915</Confidence>
      <Left>279</Left>
      <Top>357</Top>
      <Width>243</Width>
      <Height>69</Height>
    </LPR>
        
    
        
    
    //Json

    {
      "service": "lpr",
      "version": "2.0",
      "date": "3/8/2021 11:07:21 PM",
      "status": SUCCESS,
      "license_number": "ABCD-1234",
      "region": "New York",
      "country": "USA",
      "confidence": 0.915,
      "left": 279.0,
      "top": 357.0,
      "width": 243.0,
      "height": 69.0
    }
        
    

Error Codes

Error Code (Key) Description (Value)
0 Database Errors.
23 Insufficient balance for Recognition.
25 No image has been uploaded.
26 Recognition failed.
27 Unknown error(s) occured.
29 One or more required parameters missing.
        

    // XML

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <LPR version="2.0" Date="5/28/2015 1:39:10 PM" Status="FAILED">
      <Message Key="0" Value="Database Errors." />
    </LPR>
        
    
        
    {
      "service": "lpr",
      "version": "2.0",
      "date": "03/08/21 3:23:27 PM",
      "status": "FAILED",
      "message_key": 0,
      "message": "Database Errors." 
    }
        
    

Coding Examples (XML and Json)

JavaScript(Python, C#, Java)


    <html>
    <head></head>
    <body>
    <form id = "form">
        <label>Please submit an image containing a license number:<input type = "file" id = "input"></label>
        <br>
        <a href="javascript: fetchResponseXml()"> Submit (XML Output) </a>
        <br>
        <a href="javascript: fetchResponseJson()"> Submit (Json Output) </a>
    </form>

    <pre id = "p1"></pre>
    </body>

    <script>

    const form = document.getElementById("form")
    const out = document.getElementById("p1")


    // XML

    async function fetchResponseXml() {
        console.log("XML")
        const url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE"
        var imgInput = document.getElementById("input")
        var img = imgInput.files[0]
        var formData = new FormData();
        formData.append('file', img)

        var parser = new DOMParser();
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("POST", url, false);
        xmlHttp.send(formData);
        var xmlResponse = parser.parseFromString(xmlHttp.responseText, "text/xml");
        var text = "";
        var children = xmlResponse.documentElement.children;
        for (var i = 0; i < children.length; i++) {
            text += children[i].nodeName + ": " + children[i].textContent + "\n"
        }

        out.textContent = text;
    }

    // Json

    async function fetchResponseJson() {
        console.log("JSON")
        const url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE&format=JSON"
            
        var imgInput = document.getElementById("input")
        var img = imgInput.files[0]
        var formData = new FormData();
        formData.append('file', img)

        var xHttp = new XMLHttpRequest();
        xHttp.open("POST", url, false);
        xHttp.send(formData);
        var jsonResponse = JSON.parse(xHttp.responseText)
        var text = "";
            
        for (let childProperty in jsonResponse) {
            let childValue = jsonResponse[childProperty];
                
            if (typeof childValue === 'object') {
                text += childProperty + ": \n" 
                for (let nestedChildProperty in childValue) {
                    let nestedChildValue = childValue[nestedChildProperty]
                    text += "\t" + nestedChildProperty + ": " + nestedChildValue + "\n";
                }
            } else {
                text += childProperty + ": " + childValue + "\n";
            }
        }

        out.textContent = text;
    }

    </script>
    </html>
Python(JavaScript, C#, Java)


    ### XML

    import xml.etree.ElementTree as ET
    import requests

    url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE"
    path = "YOUR_IMAGE_PATH"

    with open(path, 'rb') as img:
        imgName = os.path.basename(path)
        images = {'image': (imgName, img)}
        with requests.Session() as s:
            r = s.post(url, files = images)
            xml = ET.fromstring(r.text)
            output = "License Number: " + xml[0].text
            print(output)

    ### Json

    import requests
    import json
    import os

    url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE&format=JSON"
    path = "YOUR_IMAGE_PATH"

    with open(path, 'rb') as img:
        imgName = os.path.basename(path)
        images = {'image': (imgName, img)}
        with requests.Session() as s:
            r = s.post(url, files = images)
            result = r.json()
            for attribute, value in result.items():
                print(attribute, ":", value)


C#(JavaScript, Python, Java)


    // XML

    using System;
    using System.IO;
    using System.Net;
    using System.Xml.Linq;


    static void Main(string[] args)
    {
        String url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE";
        String imagePath = "YOUR_IMAGE_PATH";
        WebClient client = new WebClient();
        byte[] response = client.UploadFile(url, imagePath);
        String responseString = client.Encoding.GetString(response);
        XElement root = XElement.Parse(responseString);

        // Iterating for "License_Number" item in the root tag.
        var el = root.Elements("License_Number");
        Console.WriteLine("License Number: " + (string) el.Value);

        IEnumerable<XElement> test =
             from el in root.Elements("License_Number")
             where (string) el.Value != null
             select el;
         foreach (XElement el in test)
             Console.WriteLine("License Number: " + (string)el.Value);
    }

    // Json

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Xml;
    using Newtonsoft.Json.Linq;

    static void Main(string[] args)
    {
        String url = "https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE&format=JSON";
        String imagePath = "YOUR_IMAGE_PATH";
        WebClient client = new WebClient();
        byte[] response = client.UploadFile(url, imagePath);
        String responseString = client.Encoding.UTF8.GetString(response);

		Console.WriteLine("\nJSON Output (Parsed): \n");

		JObject jsonResponse = JObject.Parse(responseString);

		foreach (var node in jsonResponse)
		{
			Console.WriteLine(node.Key + ": " + node.Value);
		}
    }


Java(JavaScript, Python, C#)


    // XML

    ...
    import java.net.HttpURLConnection;
    import java.net.URL;
    

    public static void main( String[] args )
    {
        URL url;
        String response = "";
        try {
            
            url = new URL("https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE");

            final HttpURLConnection con = (HttpURLConnection) url.openConnection();
            
            final String imagePath = "YOUR_IMAGE_PATH";
            postImage(con, imagePath);
            
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder sb = new StringBuilder();
            while ((response = br.readLine()) != null) {
                sb.append(response);

            }
        
            response = sb.toString();
            System.out.println(response);

	    con.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Json

    ...
    import java.net.HttpURLConnection;
    import java.net.URL;
    

    public static void main( String[] args )
    {
        URL url;
        String response = "";
        try {
            
            url = new URL("https://lpr.recognition.ws/v2?accesscode=YOUR_ACCESS_CODE&format=JSON");

            final HttpURLConnection con = (HttpURLConnection) url.openConnection();
            
            final String imagePath = "YOUR_IMAGE_PATH";
            postImage(con, imagePath);
            
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder sb = new StringBuilder();
            while ((response = br.readLine()) != null) {
                sb.append(response);

            }
        
            response = sb.toString();
            System.out.println(response);

	    con.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /////////////////////////////////////////////////////////////////
    /// function postImage(HttpURLConnection con, String filePath) //
    ////////////////////////////////////////////////////////////////

    public static void postImage(HttpURLConnection con, String filePath) {
        String charSet = "UTF-8";
        File binaryFile = new File(filePath);
        String boundary = "--";
        String CRLF = "\r\n";
        try {
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

            OutputStream output = con.getOutputStream();
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(output, charSet));
            pw.append("--" + boundary).append(CRLF);
            pw.append("Content-Disposition: form-data; name \"file\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
            pw.append("Content-Type: image/gif").append(CRLF);
            pw.append(CRLF).flush();

            Files.copy(binaryFile.toPath(), output);
            output.flush();

            pw.append(CRLF).append("--" + boundary + "--").flush();

            pw.close();
            output.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }