# Cropper

## What is Cropper?

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

Cropper can be used in two ways:

* On any API by adding a parameter.
* By using the stand-alone API Cropper.

<figure><img src="https://126655343-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2al1MDqAP9Dg9iDRjkWg%2Fuploads%2Fgit-blob-1ffd301c9aad717321f3652f801fb573993b9730%2Feb88f8e-cropper.png?alt=media" alt="Receipt cropping and background removal" width="563"><figcaption></figcaption></figure>

## How it Works

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

```http
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, i.e. 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:

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

{% hint style="info" %}
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.
{% endhint %}

#### Example With Receipts V5

Using this [sample receipt document](https://files.readme.io/1ff3082-4.1.jpg) we append the cropper additional param `?cropper=true` to the receipts API URL.

{% tabs %}
{% tab title="Python" %}

```python
from mindee import Client, PredictResponse, product

# Init a new client
mindee_client = Client(api_key="my-api-key-here")

# Load a file from disk
input_doc = mindee_client.source_from_path("/path/to/the/file.ext")

# Load a file from disk and parse it.
result: PredictResponse = mindee_client.parse(
    product.ReceiptV5,
    input_doc,
    # Add the cropper param to the API call
    cropper=True
)

# Print a summary of the API result
print(result.document)

# Print the document-level summary
# print(result.document.inference.prediction)
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const mindee = require("mindee");
// for TS or modules:
// import * as mindee from "mindee";

// Init a new client
const mindeeClient = new mindee.Client({ apiKey: "my-api-key" });

// Load a file from disk
const inputSource = mindeeClient.docFromPath("/path/to/the/file.ext");

// Parse the file
const apiResponse = mindeeClient.parse(
    mindee.product.ReceiptV5,
    inputSource,
    // Add the cropper param to the API call}
    {cropper: true}
);

// Handle the response Promise
apiResponse.then((resp) => {
    // print a string summary
    console.log(resp.document.toString());
});
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

use Mindee\Client;
use Mindee\Product\Receipt\ReceiptV5;

// Init a new client
$mindeeClient = new Client("my-api-key");

// Load a file from disk
$inputSource = $mindeeClient->sourceFromPath("/path/to/the/file.ext");

// Set the cropper option
$options = new PredictMethodOptions();
$options->setCropper(true);

// Parse the file
$apiResponse = $mindeeClient->parse(
    ReceiptV5::class,
    $inputSource,
    $options
);

echo $apiResponse->document;
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'mindee'

# Init a new client
mindee_client = Mindee::Client.new(api_key: 'my-api-key')

# Load a file from disk
input_source = mindee_client.source_from_path('/path/to/the/file.ext')

# Parse the file
result = mindee_client.parse(
  input_source,
  Mindee::Product::Receipt::ReceiptV5,
  # Add the cropper param to the API call
  options: { cropper: true },
  enqueue: false
)

# Print a full summary of the parsed data in RST format
puts result.document

# Print the document-level parsed data
# puts result.document.inference.prediction
```

{% endtab %}

{% tab title="Bash" %}

```bash
curl -X POST 
  https://api.mindee.net/v1/products/mindee/expense_receipts/v5/predict?cropper=true
  -H 'Authorization: Token my-api-key-here' 
  -F document=@/path/to/your/file.png
```

{% endtab %}
{% endtabs %}

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

```json
{
	...
    "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.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
                    },
                    ...
				}
			]
		}
    }
}
```

* Replace **my-api-key-here** with your new API key, or use the **select an API key** feature and it will be filled automatically.
* Copy and paste the sample code of your desired choice in your application, code environment, terminal etc.
* Replace `/path/to/the/file.ext` with the path to your input document.

{% hint style="warning" %}
Remember to replace with your V1 API key.
{% endhint %}

### Cropper standalone API

#### Setup the API

1. Access your Cropper API by clicking on the **Cropper** card in the Utilities tab:

<figure><img src="https://126655343-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2al1MDqAP9Dg9iDRjkWg%2Fuploads%2Fgit-blob-9294c52744c2cff1474546ec56e913c799a1ef21%2F91ece9df8c23254729ae40861cc97dae73216bce8abc23bf6dc67ef74801e100-image.png?alt=media" alt=""><figcaption></figcaption></figure>

2. From the left navigation, go to [documentation](https://docs.mindee.com/v1/platform-ui-tour/api-documentation) **> API Reference**, you'll find sample code in popular languages and command line.

{% tabs %}
{% tab title="Python" %}

```python
from mindee import Client, PredictResponse, product

# Init a new client
mindee_client = Client(api_key="my-api-key-here")

# Load a file from disk
input_doc = mindee_client.source_from_path("/path/to/the/file.ext")

# Load a file from disk and parse it.
# The endpoint name must be specified since it cannot be determined from the class.
result: PredictResponse = mindee_client.parse(product.CropperV1, input_doc)

# Print a summary of the API result
print(result.document)

# Print the document-level summary
# print(result.document.inference.prediction)
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const mindee = require("mindee");
// for TS or modules:
// import * as mindee from "mindee";

// Init a new client
const mindeeClient = new mindee.Client({ apiKey: "my-api-key-here" });

// Load a file from disk
const inputSource = mindeeClient.docFromPath("/path/to/the/file.ext");

// Parse the file
const apiResponse = mindeeClient.parse(
  mindee.product.CropperV1,
  inputSource
);

// Handle the response Promise
apiResponse.then((resp) => {
  // print a string summary
  console.log(resp.document.toString());
});
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

use Mindee\Client;
use Mindee\Product\Cropper\CropperV1;

// Init a new client
$mindeeClient = new Client("my-api-key-here");

// Load a file from disk
$inputSource = $mindeeClient->sourceFromPath("/path/to/the/file.ext");

// Parse the file
$apiResponse = $mindeeClient->parse(CropperV1::class, $inputSource);

echo $apiResponse->document;
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using Mindee;
using Mindee.Input;
using Mindee.Product.Cropper;

string apiKey = "my-api-key-here";
string filePath = "/path/to/the/file.ext";

// Construct a new client
MindeeClient mindeeClient = new MindeeClient(apiKey);

// Load an input source as a path string
// Other input types can be used, as mentioned in the docs
var inputSource = new LocalInputSource(filePath);

// Call the API and parse the input
var response = await mindeeClient
    .ParseAsync<CropperV1>(inputSource);

// Print a summary of all the predictions
System.Console.WriteLine(response.Document.ToString());
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'mindee'

# Init a new client
mindee_client = Mindee::Client.new(api_key: 'my-api-key')

# Load a file from disk
input_source = mindee_client.source_from_path('/path/to/the/file.ext')

# Parse the file
result = mindee_client.parse(
  input_source,
  Mindee::Product::Cropper::CropperV1
)

# Print a full summary of the parsed data in RST format
puts result.document
```

{% endtab %}

{% tab title="Java" %}

```java
import com.mindee.MindeeClient;
import com.mindee.input.LocalInputSource;
import com.mindee.parsing.common.PredictResponse;
import com.mindee.product.cropper.CropperV1;
import java.io.File;
import java.io.IOException;

public class SimpleMindeeClient {

  public static void main(String[] args) throws IOException {
    String apiKey = "my-api-key-here";
    String filePath = "/path/to/the/file.ext";

    // Init a new client
    MindeeClient mindeeClient = new MindeeClient(apiKey);

    // Load a file from disk
    LocalInputSource inputSource = new LocalInputSource(filePath);

    // Parse the file
    PredictResponse<CropperV1> response = mindeeClient.parse(
        CropperV1.class,
        inputSource
    );

    // Print a summary of the response
    System.out.println(response.toString());

    // Print a summary of the predictions
//  System.out.println(response.getDocument().toString());

    // Print the page-level predictions
//    response.getDocument().getInference().getPages().forEach(
//        page -> System.out.println(page.toString())
//    );
  }

}
```

{% endtab %}

{% tab title="Bash" %}

```bash
curl -X POST \\
  https://api.mindee.net/v1/products/mindee/cropper/v1/predict \\
  -H 'Authorization: Token my-api-key-here' \\
  -H 'content-type: multipart/form-data' \\
  -F document=@/path/to/your/file.png
```

{% endtab %}
{% endtabs %}

* Replace **my-api-key-here** with your new API key, or use the **select an API key** feature and it will be filled automatically.
* Copy and paste the sample code of your desired choice in your application, code environment, terminal etc.
* Replace `/path/to/the/file.ext` with the path to your input document.

{% hint style="warning" %}
Remember to replace with your V1 API key.
{% endhint %}

### API Response

Here is the full JSON response you get when you call the API:

```json
{
  "extras": {},
  "finished_at": "2023-04-18T14:15:13.557525",
  "is_rotation_applied": null,
  "pages": [
    {
      "extras": {},
      "id": 0,
      "orientation": {
        "value": null
      },
      "prediction": {
        "cropping": [
          {
            "bounding_box": [
              [
                0.547,
                0.096
              ],
              [
                0.883,
                0.096
              ],
              [
                0.883,
                0.977
              ],
              [
                0.547,
                0.977
              ]
            ],
            "polygon": [
              [
                0.605,
                0.332
              ],
              [
                0.613,
                0.188
              ],
              [
                0.645,
                0.15
              ],
              [
                0.672,
                0.168
              ],
              [
                0.766,
                0.166
              ],
              [
                0.791,
                0.152
              ],
              [
                0.869,
                0.158
              ],
              [
                0.871,
                0.234
              ],
              [
                0.859,
                0.277
              ],
              [
                0.859,
                0.402
              ],
              [
                0.836,
                0.658
              ],
              [
                0.562,
                0.885
              ],
              [
                0.568,
                0.654
              ],
              [
                0.594,
                0.514
              ],
              [
                0.596,
                0.445
              ],
              [
                0.609,
                0.406
              ]
            ],
            "quadrangle": [
              [
                0.625,
                0.096
              ],
              [
                0.882,
                0.157
              ],
              [
                0.803,
                0.975
              ],
              [
                0.549,
                0.9
              ]
            ],
            "rectangle": [
              [
                0.625,
                0.096
              ],
              [
                0.886,
                0.121
              ],
              [
                0.803,
                0.975
              ],
              [
                0.542,
                0.949
              ]
            ]
          },
          {
            "bounding_box": [
              [
                0.195,
                0
              ],
              [
                0.482,
                0
              ],
              [
                0.482,
                0.988
              ],
              [
                0.195,
                0.988
              ]
            ],
            "polygon": [
              [
                0.201,
                0.439
              ],
              [
                0.191,
                0.281
              ],
              [
                0.197,
                0.291
              ],
              [
                0.191,
                0.117
              ],
              [
                0.197,
                0.041
              ],
              [
                0.254,
                0.037
              ],
              [
                0.33,
                0.006
              ],
              [
                0.436,
                0.006
              ],
              [
                0.467,
                0.301
              ],
              [
                0.213,
                0.986
              ],
              [
                0.215,
                0.797
              ],
              [
                0.186,
                0.793
              ],
              [
                0.197,
                0.744
              ],
              [
                0.193,
                0.689
              ],
              [
                0.211,
                0.629
              ],
              [
                0.197,
                0.576
              ]
            ],
            "quadrangle": [
              [
                0.197,
                0.019
              ],
              [
                0.456,
                0
              ],
              [
                0.481,
                0.963
              ],
              [
                0.197,
                0.988
              ]
            ],
            "rectangle": [
              [
                0.169,
                0.008
              ],
              [
                0.455,
                0
              ],
              [
                0.481,
                0.979
              ],
              [
                0.195,
                0.986
              ]
            ]
          }
        ]
      }
    }
  ],
  "prediction": {},
  "processing_time": 0.519,
  "product": {
    "features": [
      "cropping"
    ],
    "name": "mindee/cropper",
    "type": "standard",
    "version": "1.0"
  },
  "started_at": "2023-04-18T14:15:13.038768"
}
```
