Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read depth data at a CGPoint from AVDepthData buffer

I am attempting to find the depth data at a certain point in the captured image and return the distance in meters.

I have enabled depth data and am capturing the data alongside the image. I get the point from the X,Y coordinates of the center of the image (and when pressed) and convert it to the buffers index using

Int((width - touchPoint.x) * (height - touchPoint.y))

with WIDTH and HEIGHT being the dimensions of the captured image. I am not sure if this is the correct method to achieve this though.

I handle the depth data as such:

func handlePhotoDepthCalculation(point : Int) {

    guard let depth = self.photo else {
        return
    }

    //
    // Convert Disparity to Depth
    //
    let depthData = (depth.depthData as AVDepthData!).converting(toDepthDataType: kCVPixelFormatType_DepthFloat32)
    let depthDataMap = depthData.depthDataMap //AVDepthData -> CVPixelBuffer

    //
    // Set Accuracy feedback
    //
    let accuracy = depthData.depthDataAccuracy
    switch (accuracy) {
    case .absolute:
        /* 
        NOTE - Values within the depth map are absolutely 
        accurate within the physical world.
        */
        self.accuracyLbl.text = "Absolute"
        break
    case .relative:
        /* 
        NOTE - Values within the depth data map are usable for 
        foreground/background separation, but are not absolutely 
        accurate in the physical world. iPhone always produces this.
        */
        self.accuracyLbl.text = "Relative"
    }

    //
    // We convert the data
    //
    CVPixelBufferLockBaseAddress(depthDataMap, CVPixelBufferLockFlags(rawValue: 0))
    let depthPointer = unsafeBitCast(CVPixelBufferGetBaseAddress(depthDataMap), to: UnsafeMutablePointer<Float32>.self)

    //
    // Get depth value for image center
    //
    let distanceAtXYPoint = depthPointer[point]

    //
    // Set UI
    //
    self.distanceLbl.text = "\(distanceAtXYPoint) m" //Returns distance in meters?
    self.filteredLbl.text = "\(depthData.isDepthDataFiltered)" 
}

I am not convinced I am getting the correct position. From my research as well it looks like accuracy is only returned in .relative or .absolute and not a float/integer?

like image 583
Allreadyhome Avatar asked Nov 10 '17 19:11

Allreadyhome


1 Answers

To access the depth data at a CGPoint do:

let point = CGPoint(35,26)
let width = CVPixelBufferGetWidth(depthDataMap)
let distanceAtXYPoint = depthPointer[Int(point.y * CGFloat(width) + point.x)]

I hope it works.

like image 173
Sergio Bonilla Avatar answered Sep 19 '22 20:09

Sergio Bonilla