google-ar / arcore-android-sdk

ARCore SDK for Android Studio
https://developers.google.com/ar
Other
4.95k stars 1.22k forks source link

depth api sample value is 0 #1302

Open kaj777 opened 2 years ago

kaj777 commented 2 years ago

SPECIFIC ISSUE ENCOUNTERED

calls to frame.acquireRawDepthImage() or frame.acquireDepthImage() returns all 0 for all depthSample when you launch the camera. It only returns non zeros value after you move the phone (with motion). how do we know if the depth data is valid?
for acquireRawDepthImage, it is expected that some pixels might be 0, so a 0 validity check for each pixel will not help.

VERSIONS USED

kaj777 commented 2 years ago

@devbridie could you advice pls thanks

devbridie commented 2 years ago

Could you show how you're using acquireDepthImage()? Instead of returning an image containing all zeros, the API should return NotAvailableException:

throws NotYetAvailableException: if the number of observed frames is not yet sufficient for depth estimation; or depth estimation was not possible due to poor lighting, camera occlusion, or insufficient motion observed.

kaj777 commented 2 years ago

@devbridie thanks for your prompt reply, here is my code using acquireDepthImage. I did receive NotAvailableException initially, but once the acquire call is successful, the first frames without motion is 0. with GLSurfaceView implementation.

            override fun onDrawFrame(render: SampleRender) {
                val frame = session.update()

             ->    drawbackground etc xxx

                val camera = frame.acquireCameraImage()
                val depth = frame.acquireDepthImage()

                if (camera != null && depth != null
                        && (camera.timestamp == depth.timestamp)) {
                    val depthByteBufferOriginal = depth.planes[0].buffer
                    val depthByteBuffer = ByteBuffer.allocate(depthByteBufferOriginal.capacity())
                    depthByteBuffer.order(ByteOrder.LITTLE_ENDIAN)
                    while (depthByteBufferOriginal.hasRemaining()) {
                        depthByteBuffer.put(depthByteBufferOriginal.get())
                    }
                    depthByteBuffer.rewind()
                    val shortDepthBuffer = depthByteBuffer.asShortBuffer()
                    val width = depth.width
                    val height = depth.height
                    for (h in 0 until height) {
                        for (w in 0 until width) {
                            val sample: Int = shortDepthBuffer.get().toInt()
                            if (sample == 0) {
                                // Pixels with value zero are invalid, meaning depth estimates are missing from
                                // this location.
                                return;
                            }
                        }
                    }
                }
            }