# Detect Objects in an Image

> Locate and segment specific objects within an image with one synchronous Copyleaks API call. Submit via multipart and get a per-object RLE mask.

The Copyleaks Object Detection API locates specific objects within an image and returns a Run-Length Encoded (RLE) segmentation mask for each object it finds. The API is synchronous, so you get the results in the same API call.

This guide walks you through submitting an image with a list of objects to locate using `multipart/form-data`, and interpreting the results.

<Note>
  Object detection performs segmentation only - it does not classify whether the image is AI-generated. To detect AI-generated content, see the [AI Image Detection guide](/guides/ai-detector/ai-image-detection).
</Note>

## Get started

<Steps>
  <Step>
    ### Before you begin
    Before you start, ensure you have the following:
    - An active Copyleaks account. If you don't have one, **[sign up for free](https://api.copyleaks.com/signup)**.
    - You can find your API key on the **[API Dashboard](https://api.copyleaks.com/dashboard)**.
  </Step>

  <Step>
    ### Login
    <GuideLogin />
  </Step>

  <Step>
    ### Submit for analysis
    Use the [Object Detection Endpoint](/reference/actions/object-detection/check) to send an image for analysis. We suggest you provide a unique `scanId` for each submission.

    Provide the objects to locate in the `objectDetection` field as a JSON-encoded array of objects, for example `[{"object":"face"},{"object":"hand"}]`.

    #### Image Requirements
    - **Size:** Minimum 512x512px, maximum 6000x4500px (27 megapixels)
    - **File size:** Less than 32MB
    - **Formats:** PNG, JPG, JPEG, BMP, WebP, HEIC/HEIF

    #### Object Detection Requirements
    - At least one entry, maximum 3 entries.
    - Each entry's `object` value must be a non-empty string of at most 32 characters.

    <Tip>
    For testing, set `sandbox=true`. Sandbox mode is free and returns mock results.
    </Tip>

    <CodeGroup>
    ```bash title="cURL" icon="terminal"
    curl -X POST "https://api.copyleaks.com/v1/object-detection/my-scan-123/check" \
         -H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
         -F "image=@/path/to/test-image.png" \
         -F "filename=test-image.png" \
         -F "sandbox=true" \
         -F 'objectDetection=[{"object":"face"},{"object":"hand"}]'
    ```
    ```python title="Python" icon="python"
    import requests

    url = 'https://api.copyleaks.com/v1/object-detection/my-scan-123/check'
    headers = {'Authorization': 'Bearer YOUR_LOGIN_TOKEN'}

    with open('test-image.png', 'rb') as image_file:
        files = {'image': ('test-image.png', image_file, 'image/png')}
        data = {
            'filename': 'test-image.png',
            'sandbox': 'true',
            'objectDetection': '[{"object":"face"},{"object":"hand"}]',
        }
        response = requests.post(url, files=files, data=data, headers=headers)

    result = response.json()
    print(f"Detected objects: {result.get('detectedObjects')}")
    ```
    ```javascript title="JavaScript" icon="square-js"
    const imageFile = document.getElementById('fileInput').files[0];
    const formData = new FormData();

    formData.append('image', imageFile);
    formData.append('filename', imageFile.name);
    formData.append('sandbox', 'true');
    formData.append('objectDetection', JSON.stringify([{ object: 'face' }, { object: 'hand' }]));

    const response = await fetch('https://api.copyleaks.com/v1/object-detection/my-scan-123/check', {
      method: 'POST',
      headers: { 'Authorization': 'Bearer YOUR_LOGIN_TOKEN' },
      body: formData,
    });

    const result = await response.json();
    console.log('Detected objects:', result.detectedObjects);
    ```
    </CodeGroup>
  </Step>

  <Step>
    ### Interpreting the response
    The API response contains:
    - `imageInfo` with the image dimensions, used to decode the masks.
    - `detectedObjects` - one entry per object located in the image, each with an `object` name and a Run-Length Encoded (RLE) `mask`.
    - `scannedImage` with scan details including credits used.

    Objects that were requested but not found are omitted from `detectedObjects`, so look entries up by `object` rather than by position.

    #### Understanding the RLE Mask
    Run-Length Encoding (RLE) represents each object's region efficiently as arrays of `starts` positions and `lengths` over a flattened 1D version of the image. Decode it into a binary mask to visualize the object's region:

    ```python title="Python" icon="python"
    def decode_mask(rle_data, image_width, image_height):
        total_pixels = image_width * image_height
        mask = [0] * total_pixels
        starts = rle_data.get('starts', [])
        lengths = rle_data.get('lengths', [])
        for start, length in zip(starts, lengths):
            for j in range(length):
                position = start + j
                if position < total_pixels:
                    mask[position] = 1
        return mask

    # Example usage:
    # result = response.json()
    # width = result['imageInfo']['shape']['width']
    # height = result['imageInfo']['shape']['height']
    # for entry in result.get('detectedObjects', []):
    #     mask = decode_mask(entry['mask'], width, height)
    ```

    For a complete breakdown of all fields in the response, see the [Object Detection Response](/reference/data-types/object-detection/object-detection-response) documentation.
  </Step>

  <Step>
    ### Summary
    You have successfully submitted an image for object detection. You can now use the per-object masks in your application, for example to crop, blur, or highlight the detected regions.
  </Step>
</Steps>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Is the Object Detection API synchronous?">
    Yes. You send the image to the [check endpoint](/reference/actions/object-detection/check) and receive the results in the same API call, with no webhook required.
  </Accordion>
  <Accordion title="How many objects can I request?">
    Between 1 and 3 objects per request. Each object's name must be a non-empty string of at most 32 characters.
  </Accordion>
  <Accordion title="Does it tell me if the image is AI-generated?">
    No. Object detection performs segmentation only. Use the [AI Image Detection API](/reference/actions/ai-image-detector/check) to detect AI-generated content.
  </Accordion>
  <Accordion title="What happens if an object is not found?">
    Objects that are not found are omitted from the `detectedObjects` array. Look entries up by their `object` name rather than by position.
  </Accordion>
</AccordionGroup>

## Next steps
<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/reference/actions/object-detection/check">Explore the full API reference for the Object Detection endpoint.</Card>
  <Card title="Object Detection Response" icon="brackets-curly" href="/reference/data-types/object-detection/object-detection-response">Explore the full response structure for Object Detection.</Card>
</CardGroup>
