11 votes

Comment normaliser les données de disparité dans iOS ?

Dans la session WWDC "Image Editing with Depth" ils ont mentionné plusieurs fois normalizedDisparity y normalizedDisparityImage :

"L'idée de base est que nous allons convertir nos valeurs de disparité normalisées en valeurs entre 0 et 1"

"Donc, une fois que vous connaissez le min et le max, vous pouvez normaliser la profondeur ou la disparité entre 0 et 1."

J'ai d'abord essayé d'obtenir l'image disparate comme ceci :

let disparityImage = depthImage.applyingFilter(
    "CIDepthToDisparity", withInputParameters: nil)

Puis j'ai essayé d'obtenir depthDataMap et faire la normalisation mais cela n'a pas fonctionné. Suis-je sur la bonne voie ? J'aimerais avoir des conseils sur ce qu'il faut faire.

Edit :

Ceci est mon code de test, désolé pour la qualité. J'obtiens le min y max puis j'essaie de boucler sur les données pour les normaliser ( let normalizedPoint = (point - min) / (max - min) )

let depthDataMap = depthData!.depthDataMap
let width = CVPixelBufferGetWidth(depthDataMap) //768 on an iPhone 7+
let height = CVPixelBufferGetHeight(depthDataMap) //576 on an iPhone 7+
CVPixelBufferLockBaseAddress(depthDataMap, CVPixelBufferLockFlags(rawValue: 0))
// Convert the base address to a safe pointer of the appropriate type
let floatBuffer = unsafeBitCast(CVPixelBufferGetBaseAddress(depthDataMap), 
    to: UnsafeMutablePointer<Float32>.self)
var min = floatBuffer[0]
var max = floatBuffer[0]
for x in 0..<width{
    for y in 0..<height{
        let distanceAtXYPoint = floatBuffer[Int(x * y)]
        if(distanceAtXYPoint < min){
            min = distanceAtXYPoint
        }
        if(distanceAtXYPoint > max){
            max = distanceAtXYPoint
        }
    }
}

Ce que j'attendais, c'est que les données reflètent la disparité lorsque l'utilisateur a cliqué sur l'image mais qu'elle ne correspond pas. Le code pour trouver la disparité où l'utilisateur a cliqué est le suivant aquí :

// Apply the filter with the sampleRect from the user’s tap. Don’t forget to clamp!
let minMaxImage = normalized?.clampingToExtent().applyingFilter(
    "CIAreaMinMaxRed", withInputParameters: 
        [kCIInputExtentKey : CIVector(cgRect:rect2)])
// A four-byte buffer to store a single pixel value
var pixel = [UInt8](repeating: 0, count: 4)
// Render the image to a 1x1 rect. Be sure to use a nil color space.
context.render(minMaxImage!, toBitmap: &pixel, rowBytes: 4,
    bounds: CGRect(x:0, y:0, width:1, height:1), 
    format:  kCIFormatRGBA8, colorSpace: nil)
// The max is stored in the green channel. Min is in the red.
let disparity = Float(pixel[1]) / 255.0

6voto

Feras Points 267

Il y a un nouvel article de blog sur raywenderlich.com intitulé " Tutoriel sur les cartes de profondeur d'image pour iOS "contient un exemple d'application et des détails relatifs au travail avec la profondeur. L'exemple de code montre comment normaliser les données de profondeur à l'aide d'une fonction CVPixelBuffer extension :

extension CVPixelBuffer {

  func normalize() {

    let width = CVPixelBufferGetWidth(self)
    let height = CVPixelBufferGetHeight(self)

    CVPixelBufferLockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))
    let floatBuffer = unsafeBitCast(CVPixelBufferGetBaseAddress(self), to: UnsafeMutablePointer<Float>.self)

    var minPixel: Float = 1.0
    var maxPixel: Float = 0.0

    for y in 0 ..< height {
      for x in 0 ..< width {
        let pixel = floatBuffer[y * width + x]
        minPixel = min(pixel, minPixel)
        maxPixel = max(pixel, maxPixel)
      }
    }

    let range = maxPixel - minPixel

    for y in 0 ..< height {
      for x in 0 ..< width {
        let pixel = floatBuffer[y * width + x]
        floatBuffer[y * width + x] = (pixel - minPixel) / range
      }
    }

    CVPixelBufferUnlockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))
  }
}  

Il faut garder à l'esprit, lorsque l'on travaille avec des données de profondeur, qu'elles ont une résolution inférieure à celle de l'image réelle et qu'il faut donc les mettre à l'échelle (plus d'informations dans le blog et dans la rubrique Vidéo de la WWDC )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X