What is Cropper?

Cropper enables users to retrieve the coordinates of cropped images from a document through our APIs.

1246

Receipt cropping and background removal

How it Works

The cropper feature can be used on any API on the prediction route:

https://api.mindee.net/v1/products/<account_name>/<api_name>/<api_version>/predict?cropper=true

?cropper=true is the additional parameter to add to your API calls.

Cropper Output

The cropper results are located at the page level when retrieving document prediction. The cropper results are returned in the following JSON object document.inference.pages[].extras.cropper.cropping[].xxxxxx. Most of the time, taking the first element of the cropper output is sufficient for most use case.

The results show the polygon vertices at the page level, for each possible cropped document within the image:

  • bounding_box: straight rectangle (always inside canvas).
  • rectangle: rectangle that may be oriented (can go beyond the canvas, ie. vertices coordinate < 0 and > 1).
  • quadrangle: free polygon with 4 vertices (always inside canvas).
  • polygon: free polygon with up to 30 vertices (always inside canvas).

The vertices format are a list of (x, y) relative coordinates to your document, always in clockwise order. Starting vertex may not be fixed (depends if this is a rectangle or a free polygon).

Example:

...
"rectangle": [
	[0, 0.996],
	[0.002, -0.002],
	[0.996, 0],
	[0.994, 0.998]
]
...

📘

Orientation

The coordinates returned by the cropper take in consideration the rotation of the document. You can find this information in document.inference.pages[].orientation in the form of clockwise degrees. The value is the clockwise rotation to apply on the source page document to get the page upright.

Example With Receipts V3

Using this sample receipt document we append the cropper additional param ?cropper=true to the receipts API URL.

curl -X POST 
  https://api.mindee.net/v1/products/mindee/expense_receipts/v3/predict?cropper=true
  -H 'Authorization: Token my-token' 
  -F document=@/path/to/your/file.png
import requests

url = "https://api.mindee.net/v1/products/mindee/expense_receipts/v3/predict?cropper=true"

with open("/path/to/my/file", "rb") as myfile:
    files = {"document": myfile}
    headers = {"Authorization": "Token my-api-key-here"}
    response = requests.post(url, files=files, headers=headers)
    print(response.text)
// works for NODE > v10
const axios = require('axios');
const fs = require("fs");
const FormData = require('form-data')

async function makeRequest() {
    let data = new FormData()
    data.append('document', fs.createReadStream('./file.jpg'))
    const config = {
        method: 'POST',
        url: 'https://api.mindee.net/v1/products/mindee/expense_receipts/v3/predict?cropper=true',
        headers: { 
          'Authorization':'Token my-api-key-here',
          ...data.getHeaders()
           },
        data
    }

    try {
      let response = await axios(config)
      console.log(response.data);
    } catch (error) {
      console.log(error)
    }

}

makeRequest()
# tested with Ruby 2.5
require 'uri'
require 'net/http'
require 'net/https'
require 'mime/types'

url = URI("https://api.mindee.net/v1/products/mindee/expense_receipts/v3/predict?cropper=true")
file = "/path/to/your/file.png"

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Token my-api-key-here'
request.set_form([['document', File.open(file)]], 'multipart/form-data')

response = http.request(request)
puts response.read_body
<form onsubmit="mindeeSubmit(event)" >
  <input type="file" id="my-file-input" name="file" />
  <input type="submit" />
</form>

<script type="text/javascript">
const mindeeSubmit = (evt) => {
  evt.preventDefault()
  let myFileInput = document.getElementById('my-file-input');
  let myFile = myFileInput.files[0]
  if (!myFile) { return }
  let data = new FormData();
  data.append("document", myFile, myFile.name);

  let xhr = new XMLHttpRequest();

  xhr.addEventListener("readystatechange", function () {
    if (this.readyState === 4) {
      console.log(this.responseText);
    }
  });

  xhr.open("POST", "https://api.mindee.net/v1/products/mindee/expense_receipts/v3/predict?cropper=true");
  xhr.setRequestHeader("Authorization", "Token my-api-key-here");
  xhr.send(data);
}
</script>

Our result shows the different polygon vertices (bounding_box, rectangle, quadrangle, polygon) at the page level.

{
	...
    "document": {
        "id": "62c6198c-e0a8-4ee7-b922-7b5b98bedb79",
        "inference": {
            "extras": {},
            "finished_at": "2022-03-25T16:17:18+00:00",
            "is_rotation_applied": true,
            "pages": [
                {
                    "extras": {
                        "cropper": {
                            "cropping": [
                                {
                                    "bounding_box": [
                                        [0.121, 0],
                                        [0.787, 0],
                                        [0.787, 0.998],
                                        [0.121, 0.998]
                                    ],
                                    "polygon": [
                                        [0.152, 0.416],
                                        [0.16, 0.186],
                                        [0.172, 0.02],
                                        [0.211, 0.006],
                                        [0.357, 0.006],
                                        [0.592, 0.006],
                                        [0.656, 0.023],
                                        [0.775, 0.043],
                                        [0.789, 0.055],
                                        [0.756, 0.549],
                                        [0.756, 0.637],
                                        [0.736, 0.955],
                                        [0.719, 0.994],
                                        [0.607, 0.996],
                                        [0.197, 0.996],
                                        [0.131, 0.994],
                                        [0.123, 0.982],
                                        [0.125, 0.855],
                                        [0.139, 0.668],
                                        [0.139, 0.584]
                                    ],
                                    "quadrangle": [
                                        [0.173, 0],
                                        [0.786, 0.012],
                                        [0.737, 0.994],
                                        [0.122, 0.996]
                                    ],
                                    "rectangle": [
                                        [0.172, -0.019],
                                        [0.785, 0.012],
                                        [0.735, 1.027],
                                        [0.121, 0.996]
                                    ]
                                }
                            ]
                        }
                    },
                    "id": 0,
                    "orientation": {
                        "value": 0
                    },
                    ...
				}
			]
		}
    }
}

 

Questions?
Slack Logo Icon  Join our Slack