Read pixels from raw camera texture

Hello, I’m trying to use webxr on a phone to simultaneously get phone pose and the camera image. In a later step I’d like to run some computer vision functions on the image.

I’m trying to combine these two examples:

This is the playground I’m using:

At the moment it can save the first image correctly, but all subsequent images come out black.

Additionally I’m concerned about the efficiency of read-pixels: Speeding up readPixels - #8 by Cort

Could anyone give any pointers as to whether I’m on the right track? I’m not currently clear if this will be achievable in babylon.js or not.

As an alternative I’ve found this example doing something similar in webxr (no babylon.js):
https://storage.googleapis.com/chromium-webxr-test/r1255390/proposals/camera-access-marker.html

That works well for me, but I’m not sure how to use it alongside babylon.js.

cc @RaananW

WebXR already has marker tracking, so there is no need to re-implement it. It is available on all mobile browsers that support raw camera access. Babylon has the feature as well.
Having said that - this demo is nothing more than a wrapper for readPixel calls (sync or async), that is passed to OpenCV.js. you can achieve the same with babylon.

I’ll have to look into that - this should work every time and not only on the first image.

Thank you, appreciate the input.

Yes, I’m not interested in the ability to do marker tracking per se, just the ability to capture the raw image and run some computer vision algorithms on it. The webxr demo is the only one I found that can read the camera texture at 30 Hz. As mentioned I’d like to achieve the same within babylon.js, but I’m unsure how to achieve that.

This playground works as expected - https://playground.babylonjs.com/#UV8FAB#27 (the ground is taking the canvas as a texture, just for visual approval of the readPixels procedure).

There is one issue on my end that needs to be solved, but this playground will continue working after I fix it (the texture is defined as cube, but it is not a cube texture).

Hi @RaananW, I am trying to implement the same configuration and looking for some guidance. The https://playground.babylonjs.com/#UV8FAB#27 playground produce an error for me and I can’t seem to extract the image from the texture data. Here is the error code: “glReadPixels: format and type incompatible with the current read framebuffer”

What device are you running this on?

Samsung Galaxy A52S and Magic Leap 2

Seems like the browser(s) have changed the format without notifying. This is an issue stated in the specs:

Sadly not defined correctly. I will play around with it, find out what happened. Thanks for reporting!

Also a question, what exactly are you trying to achieve?

This PG is working as expected - https://playground.babylonjs.com/#UV8FAB#43.
Read texture also works as expected.

Thanks! But it seems the same issue still persist after I tried to uncomment the readPixels() part. I am trying to get the image/pixels data from the texture and use it for a computer vision model.

on a samsung s23 the readpixel works and return pixels, but parsing it to a context2d doesn’t seem to work. however, if you don’t require this part and only need the actual texture it should be fine to use as well

Yeah, I wanted to put the pixels into a canvas element to feed into a CV model. I aim to deploy the model on the webpage as well, do you think it’s possible?

sure, should be possible, but I assume not in real time (or not in 30 FPS). But that’s just an assumption, it really depends what you want to do.
you get the pixel data from the readTexture call, read it using your CV library and process it as you wish. You will be at least 1 frame behind, but I assume this kind of delay is acceptable.

Hi, I’ve managed to extract the texture by adding

texture.getInternalTexture().type = 0

The problem is that raw camera module describe texture as float but the actual data from webxr is unsigned int resulting in an array of zeros when readPixels() is called.

I’m happy to start a PR if my assessment is correct.

2 Likes

i’d be happy to merge it

1 Like