luxonis / depthai-python

DepthAI Python Library
MIT License
362 stars 192 forks source link

Pixel Location on the frame #873

Open skshareef opened 1 year ago

skshareef commented 1 year ago

Hi, My inention is get the depth at every 10*10 pixel (or any legnth But we need the depth of the frame in all regions and we can filter the regions we dont want) in the frame and save them to a CSV with the pixel cordinates.

After setting the pipelines I have found this command: spatialData = spatialCalcQueue.get().getSpatialLocations()

The spaitial data have the spatial cordinates, so I can calculate the depth . But the when I print the spatial data

It gives the following output:

<depthai.SpatialLocations object at 0x000002023FC012F0> <depthai.SpatialLocations object at 0x000002023FC23EF0> <depthai.SpatialLocations object at 0x000002023FC012F0>

Well I can see that it is calculating the depth at differnt points in the frame,but I am not avle to undertand at whoch point the depth is calculated. I can use ROI , But I am able to get pnly depth at a region.

Is there a way where I can map the objects using the spaital data from spatialData = spatialCalcQueue.get().getSpatialLocations(). So I can convert them into pixel locations and save them into a csv,

Thank you

skshareef commented 1 year ago

This is the code I am currently using: _import math import cv2 import depthai as dai import numpy as np stepSize = 0.05

newConfig = False

Create pipeline

pipeline = dai.Pipeline()

Define sources and outputs

monoLeft = pipeline.create(dai.node.MonoCamera) monoRight = pipeline.create(dai.node.MonoCamera) stereo = pipeline.create(dai.node.StereoDepth) spatialLocationCalculator = pipeline.create(dai.node.SpatialLocationCalculator)

xoutDepth = pipeline.create(dai.node.XLinkOut) xoutSpatialData = pipeline.create(dai.node.XLinkOut) xinSpatialCalcConfig = pipeline.create(dai.node.XLinkIn)

xoutDepth.setStreamName("depth") xoutSpatialData.setStreamName("spatialData") xinSpatialCalcConfig.setStreamName("spatialCalcConfig")

Properties

monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P) monoLeft.setCamera("left") monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P) monoRight.setCamera("right")

stereo.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.HIGH_DENSITY) stereo.setLeftRightCheck(True) stereo.setSubpixel(True)

Config

topLeft = dai.Point2f(0.3, 0.3) bottomRight = dai.Point2f(0.35, 0.35)

config = dai.SpatialLocationCalculatorConfigData() config.depthThresholds.lowerThreshold = 100 config.depthThresholds.upperThreshold = 10000 calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MEDIAN config.roi = dai.Rect(topLeft, bottomRight)

spatialLocationCalculator.inputConfig.setWaitForMessage(False) spatialLocationCalculator.initialConfig.addROI(config)

Linking

monoLeft.out.link(stereo.left) monoRight.out.link(stereo.right)

spatialLocationCalculator.passthroughDepth.link(xoutDepth.input) stereo.depth.link(spatialLocationCalculator.inputDepth)

spatialLocationCalculator.out.link(xoutSpatialData.input) xinSpatialCalcConfig.out.link(spatialLocationCalculator.inputConfig) def calculate_distance(x,y,z): return math.sqrt(x 2 + y 2 + z ** 2)

Connect to device and start pipeline

with dai.Device(pipeline) as device:

# Output queue will be used to get the depth frames from the outputs defined above
depthQueue = device.getOutputQueue(name="depth", maxSize=4, blocking=False)
spatialCalcQueue = device.getOutputQueue(name="spatialData", maxSize=4, blocking=False)
spatialCalcConfigInQueue = device.getInputQueue("spatialCalcConfig")

color = (255, 255, 255)

print("Use WASD keys to move ROI!")

while True:
    inDepth = depthQueue.get() # Blocking call, will wait until a new data has arrived

    depthFrame = inDepth.getFrame() # depthFrame values are in millimeters

    depth_downscaled = depthFrame[::4]
    min_depth = np.percentile(depth_downscaled[depth_downscaled != 0], 1)
    max_depth = np.percentile(depth_downscaled, 99)
    depthFrameColor = np.interp(depthFrame, (min_depth, max_depth), (0, 255)).astype(np.uint8)
    depthFrameColor = cv2.applyColorMap(depthFrameColor, cv2.COLORMAP_HOT)

    spatialData = spatialCalcQueue.get().getSpatialLocations()
    for depthData in spatialData:
        roi = depthData.config.roi
        roi = roi.denormalize(width=depthFrameColor.shape[1], height=depthFrameColor.shape[0])
        xmin = int(roi.topLeft().x)
        ymin = int(roi.topLeft().y)
        xmax = int(roi.bottomRight().x)
        ymax = int(roi.bottomRight().y)

        depthMin = depthData.depthMin
        depthMax = depthData.depthMax
        depth_data=calculate_distance(depthData.spatialCoordinates.x,depthData.spatialCoordinates.y,depthData.spatialCoordinates.z)
        print(depth_data)

        fontType = cv2.FONT_HERSHEY_TRIPLEX
        cv2.rectangle(depthFrameColor, (xmin, ymin), (xmax, ymax), color, 1)
        cv2.putText(depthFrameColor, f"X: {int(depthData.spatialCoordinates.x)} mm", (xmin + 10, ymin + 20), fontType, 0.5, color)
        cv2.putText(depthFrameColor, f"Y: {int(depthData.spatialCoordinates.y)} mm", (xmin + 10, ymin + 35), fontType, 0.5, color)
        cv2.putText(depthFrameColor, f"Z: {int(depthData.spatialCoordinates.z)} mm", (xmin + 10, ymin + 50), fontType, 0.5, color)
        cv2.putText(depthFrameColor, f"depth: {int(depth_data)} mm", (xmin + 10, ymin + 70), fontType, 0.5, color)

    # Show the frame
    cv2.imshow("depth", depthFrameColor)

    key = cv2.waitKey(1)
    if key == ord('q'):
        break
    elif key == ord('w'):
        if topLeft.y - stepSize >= 0:
            topLeft.y -= stepSize
            bottomRight.y -= stepSize
            newConfig = True
    elif key == ord('a'):
        if topLeft.x - stepSize >= 0:
            topLeft.x -= stepSize
            bottomRight.x -= stepSize
            newConfig = True
    elif key == ord('s'):
        if bottomRight.y + stepSize <= 1:
            topLeft.y += stepSize
            bottomRight.y += stepSize
            newConfig = True
    elif key == ord('d'):
        if bottomRight.x + stepSize <= 1:
            topLeft.x += stepSize
            bottomRight.x += stepSize
            newConfig = True
    elif key == ord('1'):
        calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MEAN
        print('Switching calculation algorithm to MEAN!')
        newConfig = True
    elif key == ord('2'):
        calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MIN
        print('Switching calculation algorithm to MIN!')
        newConfig = True
    elif key == ord('3'):
        calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MAX
        print('Switching calculation algorithm to MAX!')
        newConfig = True
    elif key == ord('4'):
        calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MODE
        print('Switching calculation algorithm to MODE!')
        newConfig = True
    elif key == ord('5'):
        calculationAlgorithm = dai.SpatialLocationCalculatorAlgorithm.MEDIAN
        print('Switching calculation algorithm to MEDIAN!')
        newConfig = True

    if newConfig:
        config.roi = dai.Rect(topLeft, bottomRight)
        config.calculationAlgorithm = calculationAlgorithm
        cfg = dai.SpatialLocationCalculatorConfig()
        cfg.addROI(config)
        spatialCalcConfigInQueue.send(cfg)
        newConfig = False_
Erol444 commented 1 year ago

Hi @skshareef , You can get bounding box (xmin,ymin,xmax,ymax) of the spatial location data. Example here: https://github.com/luxonis/depthai/blob/main/depthai_sdk/examples/mixed/collision_avoidance.py#L20-L27