Расчет расстояния между двумя точками обзора с использованием точки глубины камеры TrueDepth ⇐ IOS
Расчет расстояния между двумя точками обзора с использованием точки глубины камеры TrueDepth
Думаю, я близок к этому, но уже несколько дней не могу понять, как вычислить реальное расстояние между двумя точками обзора.
Используя переднюю камеру TrueDepth, я собрал две точки обзора на руке, использовал эти точки, чтобы определить расстояние от камеры с помощью карты глубины, а затем применил функцию Camera Intrinsics — focusLength — для создания точек X и Y. Вместе с глубиной карты, которую я использую в качестве Z, я использую simd_precision_distance, чтобы получить расстояние между двумя точками. Я также выполнил тот же расчет с помощью созданной вручную функции евклидова расстояния, и результаты были такими же.
Однако полученное расстояние не близко к реальному миру. Это где-то половина, но я не могу сказать, что именно половина. Глядя на этот пост Энди Джаза, он упоминает, что область просмотра iPhone может быть 1/2 или 1/3, но я не уверен, что это означает, что я действительно могу удвоить это число.
В своем исследовании я нашел множество способов решить эту проблему, и вы можете видеть, что я тоже пытался найти точки зрения таким же образом:
/* let xrwPoint1 = (Float(convertedPoints[0].x) - cameraIntrinsics[2][0]) * distanceValue1 / cameraIntrinsics[0][0]; let yrwPoint1 = (Float(convertedPoints[0].y) - cameraIntrinsics[2][1]) * distanceValue1 / cameraIntrinsics[1][1]; let xrwPoint2 = (Float(convertedPoints[1].x) - cameraIntrinsics[2][0]) * distanceValue2 / cameraIntrinsics[0][0]; let yrwPoint2 = (Float(convertedPoints[1].y) - cameraIntrinsics[2][1]) * distanceValue2 / cameraIntrinsics[1][1]; print("xrw = ", xrwPoint1); print("yrw = ", yrwPoint1); */ Однако это тоже было неверно. Что мне сейчас интересно, но я не смог найти в своих исследованиях, так это то, нужно ли мне преобразовать фактическую глубину в метрах в другое значение Z перед расчетом расстояния. Но я там практически потерялся.
Вот функция. Я оставил прокомментированный код, чтобы показать, что я пробовал.
funcprocessPoints(_handPoints: [CGPoint],_ deepPixelBuffer: CVImageBuffer,_ videoPixelBuffer: CVImageBuffer,_ cameraIntrinsics: simd_float3x3) { пусть ConvertPoints = HandPoints.map { cameraView.previewLayer.layerPointConverted(fromCaptureDevicePoint: $0) } если HandPoints.count == 2 { пусть HandVisionPoint1 = HandPoints[0] пусть HandVisionPoint2 = HandPoints[1] пусть ScaleFactor = CGFloat(CVPixelBufferGetWidth(глубинаPixelBuffer)) / CGFloat(CVPixelBufferGetWidth(videoPixelBuffer)) / CGFloat(CVPixelBufferGetWidth(videoPixelBuffer)) CVPixelBufferLockBaseAddress(глубинаPixelBuffer, .readOnly) let floatBuffer = unsafeBitCast (CVPixelBufferGetBaseAddress (глубинаPixelBuffer), to: UnsafeMutablePointer.self) пусть ширина = CVPixelBufferGetWidth (глубинаPixelBuffer) пусть высота = CVPixelBufferGetHeight (глубинаPixelBuffer) пусть colPosition1 = Int(handVisionPoint1.x * CGFloat(ширина)) пусть rowPosition1 = Int(handVisionPoint1.y * CGFloat(высота)) пусть colPosition2 = Int(handVisionPoint2.x * CGFloat(ширина)) пусть rowPosition2 = Int(handVisionPoint2.y * CGFloat(высота)) lethandVisionPixelX = Int((handVisionPoint1.x * ScaleFactor).rounded()) lethandVisionPixelY = Int((handVisionPoint1.y * ScaleFactor).rounded()) lethandVisionPixel2X = Int((handVisionPoint2.x * ScaleFactor).rounded()) lethandVisionPixel2Y = Int((handVisionPoint2.y * ScaleFactor).rounded()) Guard CVPixelBufferGetPixelFormatType (глубинаPixelBuffer) == kCVPixelFormatType_DepthFloat32 else { return } CVPixelBufferLockBaseAddress(глубинаPixelBuffer, .readOnly) if let baseAddress = CVPixelBufferGetBaseAddress(глубинаPixelBuffer) { пусть ширина = CVPixelBufferGetWidth (глубинаPixelBuffer) пусть index1 = colPosition1 + (rowPosition1 * ширина) пусть index2 = colPosition2 + (rowPosition2 * ширина) пусть offset1 = index1 * MemoryLayout.stride пусть offset2 = index2 * MemoryLayout.stride пусть distanceValue1 = baseAddress.load(fromByteOffset: offset1, as: Float.self) пусть distanceValue2 = baseAddress.load(fromByteOffset: offset2, как: Плавать.самостоятельно) print("РАСТОЯННАЯ ТОЧКА 1 ЕСТЬ", distanceValue1) print("РАСТОЯНИЕ ТОЧКА 2 ЕСТЬ", distanceValue2) /* let xrwPoint1 = (Float(convertedPoints[0].x) - cameraIntrinsics[2][0]) * distanceValue1 / cameraIntrinsics[0][0]; let yrwPoint1 = (Float(convertedPoints[0].y) - cameraIntrinsics[2][1]) * distanceValue1 / cameraIntrinsics[1][1]; let xrwPoint2 = (Float(convertedPoints[1].x) - cameraIntrinsics[2][0]) * distanceValue2 / cameraIntrinsics[0][0]; let yrwPoint2 = (Float(convertedPoints[1].y) - cameraIntrinsics[2][1]) * distanceValue2 / cameraIntrinsics[1][1]; print("xrw = ", xrwPoint1); print("yrw = ", yrwPoint1); */ пусть uPoint1 = Float(convertedPoints[0].x - CGFloat(ширина))/2 пусть vPoint1 = Float(CGFloat(height)/2-convertedPoints[0].y) пусть uPoint2 = Float(convertedPoints[1].x - CGFloat(ширина))/2 пусть vPoint2 = Float(CGFloat(height)/2-convertedPoints[1].y) пусть focusLengthPx = cameraIntrinsics.columns.0.x; пусть xPoint1 = Float(uPoint1 * Float(distanceValue1) / Float(focalLengthPx)) пусть yPoint1 = Float(vPoint1 * Float(distanceValue1) / Float(focalLengthPx)) пусть xPoint2 = Float(uPoint2 * Float(distanceValue2) / Float(focalLengthPx)) пусть yPoint2 = Float(vPoint2 * Float(distanceValue2) / Float(focalLengthPx)) пусть VisionPoint1In3D = simd_float3(xPoint1, -yPoint1, distanceValue1) пусть VisionPoint2In3D = simd_float3(xPoint2, -yPoint2, distanceValue2) // Это та же функция, что и евклидова функция ниже let dist = simd_precision_distance(visionPoint1In3D, VisionPoint2In3D) print("Расстояние в метрах", dist) /* Х = и*Z/f; Y = v*Z/f, где f — фокусное расстояние камеры в пикселях, Z - метр расстояния u = ширина столбца/2 v = высота/2 ряда расстояние в 3D определяется формулой Евклида: d = √[(x2 - x1)² + (y2 - y1)² + (z2 - z1)²]. */ CVPixelBufferUnlockBaseAddress(глубинаPixelBuffer, .readOnly) } CVPixelBufferUnlockBaseAddress(глубинаPixelBuffer, .readOnly) } } Спасибо за любые мысли!
Думаю, я близок к этому, но уже несколько дней не могу понять, как вычислить реальное расстояние между двумя точками обзора.
Используя переднюю камеру TrueDepth, я собрал две точки обзора на руке, использовал эти точки, чтобы определить расстояние от камеры с помощью карты глубины, а затем применил функцию Camera Intrinsics — focusLength — для создания точек X и Y. Вместе с глубиной карты, которую я использую в качестве Z, я использую simd_precision_distance, чтобы получить расстояние между двумя точками. Я также выполнил тот же расчет с помощью созданной вручную функции евклидова расстояния, и результаты были такими же.
Однако полученное расстояние не близко к реальному миру. Это где-то половина, но я не могу сказать, что именно половина. Глядя на этот пост Энди Джаза, он упоминает, что область просмотра iPhone может быть 1/2 или 1/3, но я не уверен, что это означает, что я действительно могу удвоить это число.
В своем исследовании я нашел множество способов решить эту проблему, и вы можете видеть, что я тоже пытался найти точки зрения таким же образом:
/* let xrwPoint1 = (Float(convertedPoints[0].x) - cameraIntrinsics[2][0]) * distanceValue1 / cameraIntrinsics[0][0]; let yrwPoint1 = (Float(convertedPoints[0].y) - cameraIntrinsics[2][1]) * distanceValue1 / cameraIntrinsics[1][1]; let xrwPoint2 = (Float(convertedPoints[1].x) - cameraIntrinsics[2][0]) * distanceValue2 / cameraIntrinsics[0][0]; let yrwPoint2 = (Float(convertedPoints[1].y) - cameraIntrinsics[2][1]) * distanceValue2 / cameraIntrinsics[1][1]; print("xrw = ", xrwPoint1); print("yrw = ", yrwPoint1); */ Однако это тоже было неверно. Что мне сейчас интересно, но я не смог найти в своих исследованиях, так это то, нужно ли мне преобразовать фактическую глубину в метрах в другое значение Z перед расчетом расстояния. Но я там практически потерялся.
Вот функция. Я оставил прокомментированный код, чтобы показать, что я пробовал.
funcprocessPoints(_handPoints: [CGPoint],_ deepPixelBuffer: CVImageBuffer,_ videoPixelBuffer: CVImageBuffer,_ cameraIntrinsics: simd_float3x3) { пусть ConvertPoints = HandPoints.map { cameraView.previewLayer.layerPointConverted(fromCaptureDevicePoint: $0) } если HandPoints.count == 2 { пусть HandVisionPoint1 = HandPoints[0] пусть HandVisionPoint2 = HandPoints[1] пусть ScaleFactor = CGFloat(CVPixelBufferGetWidth(глубинаPixelBuffer)) / CGFloat(CVPixelBufferGetWidth(videoPixelBuffer)) / CGFloat(CVPixelBufferGetWidth(videoPixelBuffer)) CVPixelBufferLockBaseAddress(глубинаPixelBuffer, .readOnly) let floatBuffer = unsafeBitCast (CVPixelBufferGetBaseAddress (глубинаPixelBuffer), to: UnsafeMutablePointer.self) пусть ширина = CVPixelBufferGetWidth (глубинаPixelBuffer) пусть высота = CVPixelBufferGetHeight (глубинаPixelBuffer) пусть colPosition1 = Int(handVisionPoint1.x * CGFloat(ширина)) пусть rowPosition1 = Int(handVisionPoint1.y * CGFloat(высота)) пусть colPosition2 = Int(handVisionPoint2.x * CGFloat(ширина)) пусть rowPosition2 = Int(handVisionPoint2.y * CGFloat(высота)) lethandVisionPixelX = Int((handVisionPoint1.x * ScaleFactor).rounded()) lethandVisionPixelY = Int((handVisionPoint1.y * ScaleFactor).rounded()) lethandVisionPixel2X = Int((handVisionPoint2.x * ScaleFactor).rounded()) lethandVisionPixel2Y = Int((handVisionPoint2.y * ScaleFactor).rounded()) Guard CVPixelBufferGetPixelFormatType (глубинаPixelBuffer) == kCVPixelFormatType_DepthFloat32 else { return } CVPixelBufferLockBaseAddress(глубинаPixelBuffer, .readOnly) if let baseAddress = CVPixelBufferGetBaseAddress(глубинаPixelBuffer) { пусть ширина = CVPixelBufferGetWidth (глубинаPixelBuffer) пусть index1 = colPosition1 + (rowPosition1 * ширина) пусть index2 = colPosition2 + (rowPosition2 * ширина) пусть offset1 = index1 * MemoryLayout.stride пусть offset2 = index2 * MemoryLayout.stride пусть distanceValue1 = baseAddress.load(fromByteOffset: offset1, as: Float.self) пусть distanceValue2 = baseAddress.load(fromByteOffset: offset2, как: Плавать.самостоятельно) print("РАСТОЯННАЯ ТОЧКА 1 ЕСТЬ", distanceValue1) print("РАСТОЯНИЕ ТОЧКА 2 ЕСТЬ", distanceValue2) /* let xrwPoint1 = (Float(convertedPoints[0].x) - cameraIntrinsics[2][0]) * distanceValue1 / cameraIntrinsics[0][0]; let yrwPoint1 = (Float(convertedPoints[0].y) - cameraIntrinsics[2][1]) * distanceValue1 / cameraIntrinsics[1][1]; let xrwPoint2 = (Float(convertedPoints[1].x) - cameraIntrinsics[2][0]) * distanceValue2 / cameraIntrinsics[0][0]; let yrwPoint2 = (Float(convertedPoints[1].y) - cameraIntrinsics[2][1]) * distanceValue2 / cameraIntrinsics[1][1]; print("xrw = ", xrwPoint1); print("yrw = ", yrwPoint1); */ пусть uPoint1 = Float(convertedPoints[0].x - CGFloat(ширина))/2 пусть vPoint1 = Float(CGFloat(height)/2-convertedPoints[0].y) пусть uPoint2 = Float(convertedPoints[1].x - CGFloat(ширина))/2 пусть vPoint2 = Float(CGFloat(height)/2-convertedPoints[1].y) пусть focusLengthPx = cameraIntrinsics.columns.0.x; пусть xPoint1 = Float(uPoint1 * Float(distanceValue1) / Float(focalLengthPx)) пусть yPoint1 = Float(vPoint1 * Float(distanceValue1) / Float(focalLengthPx)) пусть xPoint2 = Float(uPoint2 * Float(distanceValue2) / Float(focalLengthPx)) пусть yPoint2 = Float(vPoint2 * Float(distanceValue2) / Float(focalLengthPx)) пусть VisionPoint1In3D = simd_float3(xPoint1, -yPoint1, distanceValue1) пусть VisionPoint2In3D = simd_float3(xPoint2, -yPoint2, distanceValue2) // Это та же функция, что и евклидова функция ниже let dist = simd_precision_distance(visionPoint1In3D, VisionPoint2In3D) print("Расстояние в метрах", dist) /* Х = и*Z/f; Y = v*Z/f, где f — фокусное расстояние камеры в пикселях, Z - метр расстояния u = ширина столбца/2 v = высота/2 ряда расстояние в 3D определяется формулой Евклида: d = √[(x2 - x1)² + (y2 - y1)² + (z2 - z1)²]. */ CVPixelBufferUnlockBaseAddress(глубинаPixelBuffer, .readOnly) } CVPixelBufferUnlockBaseAddress(глубинаPixelBuffer, .readOnly) } } Спасибо за любые мысли!
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Расчет расстояния между двумя точками с использованием широты и высоты (высота)
Anonymous » » в форуме Python - 0 Ответы
- 35 Просмотры
-
Последнее сообщение Anonymous
-