Неточности расстояния между пикселями камеры TrueDepthIOS

Программируем под IOS
Ответить
Гость
 Неточности расстояния между пикселями камеры TrueDepth

Сообщение Гость »

Я использую фронтальную камеру TrueDepth в сочетании с Vision для распознавания точек на изображении и проведения некоторых измерений. Я понимаю, что координаты Vision нормализованы, поэтому я конвертирую нормализованные точки Vision в CGPoints, соответствующие представлению, а затем сопоставляю их с глубиной данных в dataOutputSynchronizer, чтобы получить значение z. Затем, используя встроенные функции камеры, я пытаюсь получить расстояние между двумя точками в трехмерном пространстве.
Я успешно нашел точки и (я полагаю) преобразовал их в точки экрана. Я думаю, что эти точки CGP ничем не будут отличаться от тех, если бы я коснулся их экрана.
Моя проблема в том, что, несмотря на то, что преобразованные точки CGPoint остаются в основном одинаковыми (моя рука перемещается по во время тестирования немного, но остается в основном плоским по отношению к камере) и я пытаюсь вычислить положение глубины таким же образом, глубины могут сильно различаться - особенно точка 2. Точка глубины 2 кажется более точной с точки зрения рассчитанного расстояния (мой рука находится примерно в 1 футе от камеры), но она сильно варьируется и все равно не точна.
Вот отпечаток консоли с соответствующими данными

Код: Выделить всё

there are 2 points found
recognized points
[(499.08930909633636, 634.0807711283367), (543.7462849617004, 1061.8824380238852)]
DEPTH POINT 1 =  3.6312041
DEPTH POINT 2 =  0.2998223

there are 2 points found
recognized points
[(498.33644700050354, 681.3769372304281), (602.3667773008347, 1130.4955183664956)]
DEPTH POINT 1 =  3.6276162
DEPTH POINT 2 =  0.560331
Вот часть соответствующего кода.
dataOutputSynchronizer

Код: Выделить всё

func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer,
didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {

var handPoints: [CGPoint] = []

// Read all outputs
guard renderingEnabled,
let syncedDepthData: AVCaptureSynchronizedDepthData =
synchronizedDataCollection.synchronizedData(for: depthDataOutput) as? AVCaptureSynchronizedDepthData,
let syncedVideoData: AVCaptureSynchronizedSampleBufferData =
synchronizedDataCollection.synchronizedData(for: videoDataOutput) as? AVCaptureSynchronizedSampleBufferData else {
// only work on synced pairs
return
}

if syncedDepthData.depthDataWasDropped || syncedVideoData.sampleBufferWasDropped {
return
}

let depthPixelBuffer = syncedDepthData.depthData.depthDataMap
guard let videoPixelBuffer = CMSampleBufferGetImageBuffer(syncedVideoData.sampleBuffer) else {
return
}

// Get the cameraIntrinsics
guard let  cameraIntrinsics = syncedDepthData.depthData.cameraCalibrationData?.intrinsicMatrix else {
return
}

let image = CIImage(cvPixelBuffer: videoPixelBuffer)

let handler = VNImageRequestHandler(
cmSampleBuffer: syncedVideoData.sampleBuffer,
orientation: .up,
options: [:]
)

do {
try handler.perform([handPoseRequest])
guard
let results = handPoseRequest.results?.prefix(2),
!results.isEmpty
else {
return
}

var recognizedPoints: [VNRecognizedPoint] = []

try results.forEach { observation in
let fingers = try observation.recognizedPoints(.all)

if let middleTipPoint = fingers[.middleDIP] {
recognizedPoints.append(middleTipPoint)
}

if let wristPoint = fingers[.wrist] {
recognizedPoints.append(wristPoint)
}
}

// Store the Points in handPoints if they are confident points
handPoints = recognizedPoints.filter {
$0.confidence >  0.90
}
.map {
// Adjust the Y
CGPoint(x: $0.location.x, y: 1 - $0.location.y)
}

// Process the Points Found
DispatchQueue.main.sync {
self.processPoints(handPoints,depthPixelBuffer,videoPixelBuffer,cameraIntrinsics)
}
} catch {
// Be more graceful here
}
}
Точки процесса

Код: Выделить всё

func processPoints(_ handPoints: [CGPoint],_ depthPixelBuffer: CVImageBuffer,_ videoPixelBuffer: CVImageBuffer,_ cameraIntrinsics: simd_float3x3) {

// This converts the normalized point to screen points
// cameraView.previewLayer is a AVCaptureVideoPreviewLayer inside a UIView
let convertedPoints = handPoints.map {
cameraView.previewLayer.layerPointConverted(fromCaptureDevicePoint: $0)
}

// We need 2 hand points to get the distance
if handPoints.count == 2 {
print("there are 2 points found");
print("recognized points")
print(convertedPoints)

let handVisionPoint1 = convertedPoints[0]

let handVisionPoint2 = convertedPoints[1]

let scaleFactor = CGFloat(CVPixelBufferGetWidth(depthPixelBuffer)) / CGFloat(CVPixelBufferGetWidth(videoPixelBuffer))

CVPixelBufferLockBaseAddress(depthPixelBuffer, .readOnly)
let floatBuffer = unsafeBitCast(CVPixelBufferGetBaseAddress(depthPixelBuffer), to: UnsafeMutablePointer.self)

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

let handVisionPixelX = Int((handVisionPoint1.x * scaleFactor).rounded())
let handVisionPixelY = Int((handVisionPoint1.y * scaleFactor).rounded())

let handVisionPixe2X = Int((handVisionPoint2.x * scaleFactor).rounded())
let handVisionPixe2Y = Int((handVisionPoint2.y * scaleFactor).rounded())

CVPixelBufferLockBaseAddress(depthPixelBuffer, .readOnly)

let rowDataPoint1 = CVPixelBufferGetBaseAddress(depthPixelBuffer)! + handVisionPixelY * CVPixelBufferGetBytesPerRow(depthPixelBuffer)
let handVisionPoint1Depth = rowDataPoint1.assumingMemoryBound(to: Float32.self)[handVisionPixelX]

print("DEPTH POINT 1 = ", handVisionPoint1Depth)

let rowDataPoint2 = CVPixelBufferGetBaseAddress(depthPixelBuffer)! + handVisionPixe2Y * CVPixelBufferGetBytesPerRow(depthPixelBuffer)
let handVisionPoint2Depth = rowDataPoint2.assumingMemoryBound(to: Float32.self)[handVisionPixe2X]

print("DEPTH POINT 2 = ", handVisionPoint2Depth)
//Int((width - touchPoint.x) * (height - touchPoint.y))
}
Сейчас я думаю, что моя логика поиска правильного пикселя на карте глубины неверна. Если это не так, то мне интересно, не синхронизирован ли поток данных. Но, честно говоря, я сейчас немного растерян. Спасибо за любую помощь!

Источник: https://stackoverflow.com/questions/777 ... accuracies
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»