arcore-android-sdk icon indicating copy to clipboard operation
arcore-android-sdk copied to clipboard

Feature Request: Provide Camera Intrinsics

Open nbsrujan opened this issue 7 years ago • 34 comments

AR-Core doesn't seem to provide us Camera Instrinsics matrix. Tango and AR-Kit provides Intrinsic and distortion parameters. All Photogrammetry or Marker based applications require Camera Instrinsics. If they are provided by AR-Core, how can we access them?

nbsrujan avatar Jan 05 '18 11:01 nbsrujan

This is definitely on our radar. For now you can back out a pinhole model from the projection matrix and transformed UVs, but we hope to provide a directly-defined pinhole model with distortion parameters in the future.

inio avatar Jan 05 '18 18:01 inio

@nbsrujan or anyone at google, is this also on your radar for the ARCore Unity SDK and the other platforms as well?

eisenbruch avatar Jan 06 '18 15:01 eisenbruch

@eisenbruch I've asked and we expect the Unity and Unreal engine integrations to offer feature parity on this topic.

inio avatar Jan 08 '18 23:01 inio

As far as I understand the matter using the projection matrix to derive a pinhole model is problematic since ARCore adjusts it for crop before returning to the app. This effectively scales one of the axes and cannot be corrected since the app doesn't know the actual values of fx and fy. Am I missing something (if so could you please provide a hint)?

andrdmi avatar Jan 09 '18 07:01 andrdmi

@andrdmi That's why I mentioned "and transformed UVs". Frame.transformDisplayUvCoords() lets you discover the current crop factor.

Note: transformDisplayUvCoords may not use the entire 0-1 texture range, even when the texture is not cropped. Some android camera drivers always generate a square texture for example.

inio avatar Jan 09 '18 18:01 inio

@inio Indeed, thanks!

andrdmi avatar Jan 09 '18 19:01 andrdmi

@inio ,@andrdmi projection matrix gets us to normalized device coordinates. Could you please explain how we can use transformDisplayUvCoords to transform normalized device coords to window coords? I am confused because the output of transformDisplayUvCoords seems to be in 0-1 range and I was expecting the output to be in pixel coords. Thank you!

ilamanov avatar Jan 20 '18 03:01 ilamanov

@namnov Apologies for the super pseudocodey logic below, but hopefully it's enough to follow:

First call transformDisplayUvCoords with the point set (0,0), (1,0), (0,1) and call the output point set (a,b),(c,-),(-,d). where - is a don't-care. From this you can form the matrix M_uv_disp

c-a   0    0    a
 0   d-b   0    b
 0    0    1    0
 0    0    0    1 

which transforms normalized display coordinates into UV coordinates.

now you just need to do M_uv_camera = M_uv_disp * scale(0.5) * translate(1, 1, 0) * proj_matrix. The scale and translate are needed to convert clip-space coordinates (-1,1) into normalized display coordinates (0,1).

inio avatar Jan 22 '18 13:01 inio

@inio Thanks!

ilamanov avatar Jan 23 '18 15:01 ilamanov

Seconding this. If ARCore can just give us the calibration file it is using, would be nice.

iBicha avatar Mar 22 '18 16:03 iBicha

I know it's an old issue, but I think that @inio's example is incomplete for cases where the screen is rotated. For that, you need the off axis elements too, using "g", "h" instead of "don't care" values.

So given outputs (a,b),(c,g),(h,d), the matrix would be something like this:

c-a  h-a   0    a
g-b  d-b   0    b
 0    0    1    0
 0    0    0    1 

This is untested and may be in the wrong order, I just wanted to follow up in case it helps someone.

klausw avatar Apr 16 '18 03:04 klausw

Trying a few things inspired by the first step described here, I was able to find the intrinsic parameters for the supported devices in the ARCore APKs. You need to get the apktool and run this in the same folder where you downloaded the ARCore APK (v1.2 in this example):

apktool -q d -s -r ARCore_1_2.apk -o ARCore_1_2

This will create a folder called ARCore_1_2, then go to ./lib/arm64-v8a and unpack libdevice_profile_loader.so (with 7zip for instance) into a new folder for convenience. Then, open the file .rodata in the newly created folder with a text editor. Most of the file's content is formatted as an XML, just look for the name of the phone you're working with and you'll find the intrinsic parameters within the tag <camera>. There are also some IMU calibration data and extrinsics, but it's not clear how are they're used.

I haven't tested the parameters myself, but will do in the next few days...

rmonroy84 avatar May 10 '18 16:05 rmonroy84

@inio I find the function you mentioned in https://github.com/google-ar/arcore-android-sdk/blob/master/samples/hello_ar_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/BackgroundRenderer.java#L133. However, c-a and d-b are 0 or 1e-8 when I run the code on Google Pixel. Is it normal?

fengyang0317 avatar Jun 16 '18 02:06 fengyang0317

ARCore 1.3 adds access to a simple pinhole model for both the GPU texture and CPU image. It does not include distortion parameters yet so I'm leaving this open

inio avatar Jun 22 '18 14:06 inio

@rmonroy84 do u know how to use imu calibration from arcore

ghost avatar Aug 27 '18 08:08 ghost

IMU↔︎camera extrinsics are now available (once tracking starts) by comparing Frame.getAndroidSensorPose and Camera.getPose (but note bug #535).

inio avatar Aug 28 '18 17:08 inio

@gao-ouyang I've only used the distortion coefficients & intrinsics for the camera. On the file I mentioned here there are some tags related to IMU intrinsics (b_w_b_a, intrinsics, gyro_noise_sigma, gyro_bias_sigma, accel_noise_sigma, accel_bias_sigma), but I wouldn't know how to use them.

rmonroy84 avatar Aug 28 '18 17:08 rmonroy84

I believe this issue can be closed now since the camera intrinsics are now available. Please open a new issue if you still have questions about how to use these APIs.

claywilkinson avatar Nov 20 '18 18:11 claywilkinson

Reopening as original request for distortion parameters has not been resolved.

inio avatar Nov 20 '18 18:11 inio

@inio Are distortion parameters obtainable now ?

alexs7 avatar Nov 20 '19 14:11 alexs7

@inio Still relevant in 2020.

This is a possible linked issue with the current method via ARCore: https://github.com/google-ar/arcore-android-sdk/issues/836

gblikas avatar Apr 21 '20 21:04 gblikas

@gblikas Hello, I went ahead in my case and assumed the CPU image is undistorted. Are you using that same aswell?

alexs7 avatar Apr 21 '20 21:04 alexs7

@alexs7 No, I am not. For my application, that is not a good assumption for us to make. My hope was that ARCore themselves are un-distorting the image their API and exposing that; everything I read implies that ARCore doesn't manipulate the Texture (which they shouldn't).

However, I am not sure why exposing distortion coeffs has been put off for so long. It's such an essential feature in computer vision that it makes little sense for it not to be one of the first things surfaced.

gblikas avatar Apr 21 '20 21:04 gblikas

@alexs7 It also seems like the arcore-for-all project, was also accepted with zero consideration for the accuracy of the AR in question for "all" devices. There is also no warning about this, other than visual inaccuracies.

gblikas avatar Apr 21 '20 21:04 gblikas

@gblikas I am working on localization against an offline map and I am using the CPU image, which is 480 by 640 in dimension. I think the reason that I didn't use the Texture which is because sending a 1080 by 1920 image to a server caused some delays.

I am not sure but is this something you might find relevant ? https://developers.google.com/ar/reference/java/arcore/reference/com/google/ar/core/ImageMetadata#LENS_RADIAL_DISTORTION

I remember I was looking at distortion aswell and found that but I couldn't get my head around those LENS_RADIAL_DISTORTION params . If I got this right those are for the actual camera frame but in ARCore you get a CPU Image or a Texture...

alexs7 avatar Apr 21 '20 21:04 alexs7

@alexs7 I tried the LENS_RADIAL_DISTORTION ImageMetadata accessor way back when it first came out. When it was first implemented, I was only every receiving 0's from it; has this changed?

gblikas avatar Apr 21 '20 21:04 gblikas

@gblikas It's been ages I don't even remember trying it to be honest

alexs7 avatar Apr 21 '20 21:04 alexs7

Hi, I'm new to ARCore and I wanted to know how to extract the Camera's Intrinsic Parameters. I tried using LENS_INTRINSIC_CALIBRATION but that just returned an array of zeros. I tried using camera.getImageIntrinsics() for extracting the intrinsics of the CPU Image but this does not provide me the axis skew parameter which is required by my application. How do I extract this parameter?

aashish2000 avatar Mar 08 '21 04:03 aashish2000

I'm using CameraManager.getCameraCharacteristics(), but it returns valid lens characteristics only for Pixel devices...

pawegio avatar Mar 08 '21 06:03 pawegio

@devbridie, any update on this? LENS_RADIAL_DISTORTION is not working and no clue how to access the distortion parameters in ARCore API. This will be very useful feature since texture images returend by ARCore are highly distorted (at close distances).

Basel-Salahieh avatar Aug 02 '21 19:08 Basel-Salahieh