> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.stereolabs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.stereolabs.com/_mcp/server.

# Tutorial - Using 3D Object Detection

This tutorial shows how to enable the AI-based Object Detection module to detect, classify and localize objects in 3D space, with a runtime-adjustable confidence threshold. Detection and localization work with both a static and a moving camera. This module requires a stereo camera with an integrated IMU (ZED 2/2i, ZED Mini, or ZED X family); the original ZED is **not** supported.

## Getting Started

* First, download the latest version of the [ZED SDK](https://www.stereolabs.com/developers/).
* Download the [Object Detection](https://github.com/stereolabs/zed-sdk/tree/master/tutorials/tutorial%206%20-%20object%20detection) sample code in C, C++, Python or C#.

## Code Overview

### Open the camera

In this tutorial, we will use the [Object Detection](/docs/development/zed-sdk/modules/object-detection/) AI module of the ZED SDK.
As in previous tutorials, we create, configure and open the camera.

**`C++`**

```cpp C++
// Create ZED objects
Camera zed;
InitParameters init_parameters;
init_parameters.camera_resolution = RESOLUTION::HD720;
init_parameters.depth_mode = DEPTH_MODE::NEURAL;

// Open the camera
ERROR_CODE zed_error = zed.open(init_parameters);
if (zed_error != ERROR_CODE::SUCCESS) {
	std::cout << "Error " << zed_error << ", exit program.\n";
	return 1; // Quit if an error occurred
}
```

**`Python`**

```python Python
# Create ZED objects
zed = sl.Camera()
init_params = sl.InitParameters()
init_params.camera_resolution = sl.RESOLUTION.HD720
init_params.depth_mode = sl.DEPTH_MODE.NEURAL

# Open the camera
err = zed.open(init_params)
if err != sl.ERROR_CODE.SUCCESS:
    # Quit if an error occurred
    exit()
```

**`C#`**

```csharp C#
// Create a ZED camera object
Camera zed = new Camera(0);
// Set configuration parameters
InitParameters init_params = new InitParameters();
init_params.resolution = RESOLUTION.HD720; 
init_params.depthMode = DEPTH_MODE.NEURAL;

// Open the camera
ERROR_CODE err = zed.Open(ref init_params);
if (err != ERROR_CODE.SUCCESS)
    Environment.Exit(-1);
```

### Enable 3D Object detection

Before enabling object detection, we specify the `ObjectDetectionParameters` of the module. In this tutorial, we use the following settings:

**`C++`**

```cpp C++
// Define the Object Detection module parameters
ObjectDetectionParameters detection_parameters;
detection_parameters.enable_tracking = true;
detection_parameters.enable_segmentation = true;

// Object tracking requires camera tracking to be enabled
if (detection_parameters.enable_tracking)
	zed.enablePositionalTracking();
```

**`Python`**

```python Python
# Define the Object Detection module parameters
detection_parameters = sl.ObjectDetectionParameters()
detection_parameters.enable_tracking = True
detection_parameters.enable_segmentation = True

# Object tracking requires camera tracking to be enabled
if detection_parameters.enable_tracking:
    zed.enable_positional_tracking()
```

**`C#`**

```csharp C#
// Define the Object Detection module parameters
ObjectDetectionParameters detection_parameters = new ObjectDetectionParameters();
detection_parameters.enableObjectTracking = true;
detection_parameters.enableSegmentation = true;

if (detection_parameters.enableObjectTracking){
    PositionalTrackingParameters trackingParams = new PositionalTrackingParameters();
    zed.EnablePositionalTracking(ref trackingParams);
}
```

* `enable_tracking` allows objects to be tracked across frames and keep the same ID as long as possible. Positional tracking must be active in order to track objects' movements independently from camera motion.
* `enable_segmentation` outputs 2D masks over detected objects. Since it requires additional processing, disable this option if not used.

Now let's enable object detection which will load an AI model. This operation can take a few seconds. The first time the module is used, the model will be optimized for your hardware and this can take up to a few minutes. The model optimization operation is done only once.

**`C++`**

```cpp C++
cout << "Object Detection: Loading Module..." << endl;
zed_error = zed.enableObjectDetection(detection_parameters);
if (zed_error != ERROR_CODE::SUCCESS) {
	cout << "Error " << zed_error << ", exit program.\n";
	zed.close();
	return 1;
}
```

**`Python`**

```python Python
print("Object Detection: Loading Module...")
err = zed.enable_object_detection(detection_parameters)
if err != sl.ERROR_CODE.SUCCESS:
    print("Error {}, exit program".format(err))
    zed.close()
    exit()
```

**`C#`**

```csharp C#
Console.WriteLine("Object Detection: Loading Module...");
err = zed.EnableObjectDetection(ref detection_parameters);
if (err != ERROR_CODE.SUCCESS) {
    Console.WriteLine("Error " + err + ", exit program.");
    zed.Close();
    Environment.Exit(-1);
}
```

### Retrieve object data

To retrieve detected objects in an image, use the `retrieveObjects()` function with an `Objects` parameter that will store objects' data.

For each `grab` call, the image is fed into the AI module, which outputs the objects detected in that frame. We also set the object confidence threshold at 40: detections with a lower confidence are discarded. Raise it to keep only the most confident detections.

**`C++`**

```cpp C++
// Set runtime parameter confidence to 40
ObjectDetectionRuntimeParameters detection_parameters_runtime;
detection_parameters_runtime.detection_confidence_threshold = 40;

Objects objects;

// Grab new frames and detect objects
while (zed.grab() == ERROR_CODE::SUCCESS) {
	zed.retrieveObjects(objects, detection_parameters_runtime);

	if (objects.is_new && !objects.object_list.empty()) {
        // Count the number of objects detected
        cout << objects.object_list.size() << " Object(s) detected" << endl;

        // Display the 3D location of an object  
        auto &first_object = objects.object_list[0];
        cout << " 3D position: " << first_object.position;

        // Display its 3D bounding box coordinates        
        cout << " Bounding box 3D \n";
        for (auto it : first_object.bounding_box)
          cout << "    " << it;    
	}
}
```

**`Python`**

```python Python
# Set runtime parameter confidence to 40
detection_parameters_runtime = sl.ObjectDetectionRuntimeParameters()
detection_parameters_runtime.detection_confidence_threshold = 40

objects = sl.Objects()

# Grab new frames and detect objects
while zed.grab() == sl.ERROR_CODE.SUCCESS:
    err = zed.retrieve_objects(objects, detection_parameters_runtime)

    if objects.is_new:
        # Count the number of objects detected
        print("{} Object(s) detected".format(len(objects.object_list)))

        if len(objects.object_list):
            # Display the 3D location of an object
            first_object = objects.object_list[0]
            position = first_object.position
            print(" 3D position : [{0},{1},{2}]".format(position[0],position[1],position[2]))

            # Display its 3D bounding box coordinates
            bounding_box = first_object.bounding_box
            print(" Bounding box 3D :")
            for it in bounding_box:            
                print(" " + str(it), end='')
```

**`C#`**

```csharp C#
// Set runtime parameter confidence to 40
ObjectDetectionRuntimeParameters detection_parameters_runtime = new ObjectDetectionRuntimeParameters();
detection_parameters_runtime.detectionConfidenceThreshold = 40;

Objects objects = new Objects();

// Grab new frames and detect objects
RuntimeParameters runtimeParameters = new RuntimeParameters();
while (zed.Grab(ref runtimeParameters) == ERROR_CODE.SUCCESS) {
    err = zed.RetrieveObjects(ref objects, ref detection_parameters_runtime);

    if (objects.isNew != 0) {
        // Count the number of objects detected
        Console.WriteLine(objects.numObject + " Object(s) detected");

        if (objects.numObject > 0) {
            // Display the 3D location of an object
            ObjectData first_object = objects.objectData[0];
            Console.WriteLine(" 3D position: " + first_object.position);

            // Display its 3D bounding box coordinates
            Console.WriteLine(" Bounding box 3D");
            foreach (Vector3 it in first_object.boundingBox)
                Console.WriteLine("    " + it);
        }
    }
}
```

### Disable modules and exit

Before exiting the application, modules need to be disabled and the camera closed.

> **Note**
>
> `zed.close()` can also disable properly all active modules. The `close()` function is also called automatically by the destructor if necessary.

**`C++`**

```cpp C++
// Disable object detection and close the camera
zed.disableObjectDetection();
zed.close();
```

**`Python`**

```python Python
# Disable object detection and close the camera
zed.disable_object_detection()
zed.close()
```

**`C#`**

```csharp C#
// Disable object detection and close the camera
zed.DisableObjectDetection();
zed.Close();
```

And this is it!