Post

Replies

Boosts

Views

Activity

Reply to Access depth data purely from lidar
Hi I successfully saved the depth map to 32-bit binary file. Then I can read the file and convert it to png using python opencv. func convertDepthData(depthMap: CVPixelBuffer) -> [[Float32]] { let width = CVPixelBufferGetWidth(depthMap) let height = CVPixelBufferGetHeight(depthMap) var convertedDepthMap: [[Float32]] = Array( repeating: Array(repeating: 0, count: width), count: height ) CVPixelBufferLockBaseAddress(depthMap, CVPixelBufferLockFlags(rawValue: 2)) let floatBuffer = unsafeBitCast( CVPixelBufferGetBaseAddress(depthMap), to: UnsafeMutablePointer<Float32>.self ) for row in 0 ..< height { for col in 0 ..< width { convertedDepthMap[row][col] = floatBuffer[width * row + col] } } CVPixelBufferUnlockBaseAddress(depthMap, CVPixelBufferLockFlags(rawValue: 2)) return convertedDepthMap } Then save it to app container. func saveFloat32ArrayToDocumentsDirectory(array: [[Float32]], fileName: String, folderName: String) -> URL? { let fileManager = FileManager.default let datasetDirectory = getDatasetDirectory() let depthDirectory = datasetDirectory.appendingPathComponent(folderName) if !FileManager.default.fileExists(atPath: depthDirectory.path) { do { try FileManager.default.createDirectory(at: depthDirectory, withIntermediateDirectories: true, attributes: nil) } catch { print("Error creating depth directory: \(error.localizedDescription)") return nil } } let fileURL = depthDirectory.appendingPathComponent(fileName) let rowCount = array.count let colCount = array[0].count var flatArray = array.flatMap { $0 } do { let data = Data(bytes: &flatArray, count: MemoryLayout<Float32>.size * rowCount * colCount) try data.write(to: fileURL, options: .atomic) return fileURL } catch { print("Error saving float32 array: \(error)") return nil } } You can call these two function in this way, please note that the frame is ARFrame. guard let depthMap = frame.sceneDepth?.depthMap let convertedDepthMap = convertDepthData(depthMap: depthMap) // Save the converted depth map let fileName = String(format: "%06d.bin", frameNumber) if let savedFileURL = saveFloat32ArrayToDocumentsDirectory(array: convertedDepthMap, fileName: fileName, folderName: "depth") { print("Array saved to: \(savedFileURL)") } else { print("Error saving float32 array to the app container.") } In openCV, you can get the depth array or convert to png. The depth image is 256*192. Because the original value is in float and we can only save int in png, I times 1000. Meanwhile, I save a .bin file to a 16-bit grayscale png. import numpy as np import cv2 import glob import os from PIL import Image # Set the number of rows and columns in your 2D Float32 array row_count = 192 col_count = 256 # Replace this with the path to the folder containing the binary files folder_path = "./depth/" output_path = "./depthImg2/" # Loop through all the .bin files in the folder for bin_file_path in glob.glob(os.path.join(folder_path, "*.bin")): # Read the binary file and convert it to a NumPy array with open(bin_file_path, "rb") as f: float32_array = np.fromfile(f, dtype=np.float32).reshape(row_count, col_count) print(float32_array) float32_array *= 1000 # Normalize the float32 array to the range [0, 2**16 - 1] and convert it to a 16-bit unsigned integer format # normalized_array = cv2.normalize(float32_array, None, 0, 2**16 - 1, cv2.NORM_MINMAX) max_depth = np.max(float32_array) min_depth = np.min(float32_array) print(f"Max depth: {max_depth}, Min depth: {min_depth}") uint16_array = float32_array.astype(np.uint16) # Get the filename without the extension filename = os.path.splitext(os.path.basename(bin_file_path))[0] # Save the 16-bit grayscale depth image with the same filename as the original file depth_image_path = os.path.join(output_path, filename + ".png") cv2.imwrite(depth_image_path, uint16_array)
Jun ’23