# SpatialLocationCalculator

SpatialLocationCalculator node calculates the spatial coordinates of the ROI (region-of-interest) based on the depth map from the
inputDepth. It will average the depth values in the ROI and remove the ones out of range.

You can also calculate spatial coordinates on host side, [demo
here](https://github.com/luxonis/oak-examples/tree/master/gen2-calc-spatials-on-host). The demo also has the same logic that's
performed on the device (calc.py file).

## How to place it

#### Python

```python
pipeline = dai.Pipeline()
spatialCalc = pipeline.create(dai.node.SpatialLocationCalculator)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto spatialCalc = pipeline.create<dai::node::SpatialLocationCalculator>();
```

## Inputs and Outputs

## Usage

#### Python

```python
pipeline = dai.Pipeline()
spatialCalc = pipeline.create(dai.node.SpatialLocationCalculator)
spatialCalc.setWaitForConfigInput(False)

# Set initial config
config = dai.SpatialLocationCalculatorConfigData()
config.depthThresholds.lowerThreshold = 100
config.depthThresholds.upperThreshold = 10000

topLeft = dai.Point2f(0.4, 0.4)
bottomRight = dai.Point2f(0.6, 0.6)
config.roi = dai.Rect(topLeft, bottomRight)

spatial_calc.initialConfig.addROI(config)

# You can later send configs from the host (XLinkIn) / Script node to the InputConfig
```

#### C++

```cpp
dai::Pipeline pipeline;
auto spatialCalc = pipeline.create<dai::node::SpatialLocationCalculator>();
spatialCalc->setWaitForConfigInput(false);

// Set initial config
dai::SpatialLocationCalculatorConfigData config;
config.depthThresholds.lowerThreshold = 100;
config.depthThresholds.upperThreshold = 10000;

dai::Point2f topLeft(0.4f, 0.4f);
dai::Point2f bottomRight(0.6f, 0.6f);
config.roi = dai::Rect(topLeft, bottomRight);

spatialCalc->initialConfig.addROI(config);

// You can later send configs from the host (XLinkIn) / scripting node to the InputConfig
```

## Examples of functionality

 * [Spatial location
   calculator](https://docs.luxonis.com/software-v3/depthai/examples/spatial_location_calculator/spatial_location_calculator.md)

## Spatial coordinate system

OAK camera uses the RDF (Right-Down-Forward) coordinate system for all spatial coordinates.

Middle of the frame is 0,0 in terms of X,Y coordinates. If you go down, Y will increase, and if you go right, X will increase.

## Reference

### dai::node::SpatialLocationCalculator

Kind: class

SpatialLocationCalculator node. Calculates the spatial locations of detected objects based on the input depth map. Spatial
location calculations can be additionally refined by using a segmentation mask. If keypoints are provided, the spatial location is
calculated around each keypoint.

#### std::shared_ptr< SpatialLocationCalculatorConfig > initialConfig

Kind: variable

Initial config to use when calculating spatial location data.

#### Input inputConfig

Kind: variable

Input SpatialLocationCalculatorConfig message with ability to modify parameters in runtime. Default queue is non-blocking with
size 4.

#### Input inputDetections

Kind: variable

Input messages on which spatial location will be calculated. Possible datatypes are ImgDetections or Keypoints.

#### Input inputDepth

Kind: variable

Input message with depth data used to retrieve spatial information about detected object. Default queue is non-blocking with size
4.

#### Output out

Kind: variable

Outputs SpatialLocationCalculatorData message that carries spatial locations for each additional ROI that is specified in the
config.

#### Output outputDetections

Kind: variable

Outputs SpatialImgDetections message that carries spatial locations along with original input data.

#### Output passthroughDepth

Kind: variable

Passthrough message on which the calculation was performed. Suitable for when input queue is set to non-blocking behavior.

#### SpatialLocationCalculator()

Kind: function

#### SpatialLocationCalculator(std::unique_ptr< Properties > props)

Kind: function

#### void setRunOnHost(bool runOnHost)

Kind: function

Specify whether to run on host or device By default, the node will run on device.

#### bool runOnHost()

Kind: function

Check if the node is set to run on host

#### void run()

Kind: function

#### DeviceNodeCRTP()

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props, bool confMode)

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device, std::unique_ptr< Properties > props, bool confMode)

Kind: function

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
