在 Android NDK 上稳定相机图像 (C)
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
ARCore 现在支持电子防抖 (EIS),这有助于生成流畅的相机预览。EIS 通过使用陀螺仪观察手机的移动情况,并在相机纹理边界内应用补偿对称转换网格来实现防抖。EIS 仅在设备的纵向模式下受支持。ARCore 1.39.0 版本将支持所有屏幕方向。
查询 EIS 支持并启用 EIS
如需启用 EIS,请将您的会话配置为使用 AR_IMAGE_STABILIZATION_MODE_EIS
。如果设备不支持 EIS 功能,这将导致 ARCore 抛出异常。
int enableEis = 0;
ArSession_isImageStabilizationModeSupported(
ar_session, AR_IMAGE_STABILIZATION_MODE_EIS, &enableEis);
if (!enableEis) {
return;
}
// Create a session config.
ArConfig* ar_config = NULL;
ArConfig_create(ar_session, &ar_config);
// Enable Electronic Image Stabilization.
ArConfig_setImageStabilizationMode(ar_session, ar_config, AR_IMAGE_STABILIZATION_MODE_EIS);
CHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS);
// Release config resources.
ArConfig_destroy(ar_config);
EIS 处于开启状态时,渲染程序在渲染相机背景时需要使用经过修改的设备坐标和包含 EIS 补偿的匹配纹理坐标。如需获取 EIS 补偿坐标,请使用 ArFrame_transformCoordinates3d
,将 AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES
作为输入,将 AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES
作为输出以获取 3D 设备坐标,并将 AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED
作为输出以获取 3D 纹理坐标。目前,ArFrame_transformCoordinates3d
唯一支持的输入坐标类型为 AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES
。
int kNumVertices = 4;
// Positions of the quad vertices in clip space (X, Y).
const GLfloat kVertices[] = {
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,
};
float transformed_vertices_[4 * 3];
float transformed_uvs_[4 * 3];
ArFrame_transformCoordinates3d(
session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
kNumVertices, kVertices,
AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES,
transformed_vertices_);
ArFrame_transformCoordinates3d(
session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
kNumVertices, kVertices, AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED,
transformed_uvs_);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, camera_texture_id_);
glUseProgram(camera_program_);
glUniform1i(camera_texture_uniform_, 0);
// Set the vertex positions and texture coordinates.
glVertexAttribPointer(camera_position_attrib_, 3, GL_FLOAT, false, 0,
transformed_vertices_);
glVertexAttribPointer(camera_tex_coord_attrib_, 3, GL_FLOAT, false, 0,
transformed_uvs_);
glEnableVertexAttribArray(camera_position_attrib_);
glEnableVertexAttribArray(camera_tex_coord_attrib_);
EIS 处于关闭状态时,输出的 3D 坐标与其 2D 坐标等效,z 值设置为不会产生任何变化。
修改着色器
计算出的 3D 坐标应传递给后台渲染着色器。顶点缓冲区现在是 3D 且具有 EIS:
layout(location = 0) in vec4 a_Position;
layout(location = 1) in vec3 a_CameraTexCoord;
out vec3 v_CameraTexCoord;
void main() {
gl_Position = a_Position;
v_CameraTexCoord = a_CameraTexCoord;
}
此外,片段着色器需要应用透视校正:
precision mediump float;
uniform samplerExternalOES u_CameraColorTexture;
in vec3 v_CameraTexCoord;
layout(location = 0) out vec4 o_FragColor;
void main() {
vec3 tc = (v_CameraTexCoord / v_CameraTexCoord.z);
o_FragColor = texture(u_CameraColorTexture, tc.xy);
}
如需了解详情,请参阅 hello_eis_kotlin 示例应用。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-26。
[null,null,["最后更新时间 (UTC):2025-07-26。"],[[["\u003cp\u003eARCore now utilizes Electronic Image Stabilization (EIS) to create a smoother camera preview by compensating for minor shakes using gyro data.\u003c/p\u003e\n"],["\u003cp\u003eEIS support can be queried, and enabled if available, through specific ARCore session configuration settings using \u003ccode\u003eAR_IMAGE_STABILIZATION_MODE_EIS\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eWhen EIS is active, developers should utilize \u003ccode\u003eArFrame_transformCoordinates3d\u003c/code\u003e to acquire the modified device and texture coordinates for accurate camera background rendering.\u003c/p\u003e\n"],["\u003cp\u003eBackground rendering shaders must be adjusted to accommodate the 3D coordinates and apply perspective correction when EIS is enabled.\u003c/p\u003e\n"],["\u003cp\u003eCurrently, EIS is only supported in portrait orientation, with full orientation support planned for the upcoming ARCore 1.39.0 release.\u003c/p\u003e\n"]]],["ARCore's Electronic Image Stabilization (EIS) smooths the camera preview by compensating for minor shakes, using gyro-detected phone movement. To use EIS, enable it via `AR_IMAGE_STABILIZATION_MODE_EIS` after checking for device support. When EIS is on, utilize `ArFrame_transformCoordinates3d` with specified input and output coordinate types to get modified device and texture coordinates for rendering. Renderers must use these compensated coordinates in vertex buffers, which are now 3D. Shaders also require modification to handle 3D coordinates and perspective correction. EIS is currently only supported in portrait mode.\n"],null,["# Stabilize camera images on Android NDK (C)\n\nARCore now supports Electronic Image Stabilization (EIS), which helps produce a smooth camera preview. EIS achieves stabilization by observing phone movement using gyro and applying compensation homography mesh within the boundaries of camera texture that counters the minor shakes. EIS is only supported in the device's portrait orientation. All orientations will be supported in the 1.39.0 release of ARCore.\n\nQuery for EIS support and enable EIS\n------------------------------------\n\nTo enable EIS, configure your session to use [`AR_IMAGE_STABILIZATION_MODE_EIS`](/ar/reference/c/group/ar-config#ar_image_stabilization_mode_eis). If the device doesn't support the EIS feature, this will cause an exception to be thrown from ARCore. \n\n```c\nint enableEis = 0;\nArSession_isImageStabilizationModeSupported(\n ar_session, AR_IMAGE_STABILIZATION_MODE_EIS, &enableEis);\nif (!enableEis) {\n return;\n}\n// Create a session config.\nArConfig* ar_config = NULL;\nArConfig_create(ar_session, &ar_config);\n\n// Enable Electronic Image Stabilization.\nArConfig_setImageStabilizationMode(ar_session, ar_config, AR_IMAGE_STABILIZATION_MODE_EIS);\nCHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS);\n\n// Release config resources.\nArConfig_destroy(ar_config);\n```\n\nTransform coordinates\n---------------------\n\nWhen EIS is on, the renderer needs to use the modified device coordinates and matching texture coordinates that incorporate the EIS compensation when rendering the camera background. To get the EIS compensated coordinates, use [`ArFrame_transformCoordinates3d`](/ar/reference/c/group/ar-frame#arframe_transformcoordinates3d), using [`AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES`](/ar/reference/c/group/ar-frame#ar_coordinates_2d_opengl_normalized_device_coordinates) as input and [`AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES`](/ar/reference/c/group/ar-frame#ar_coordinates_3d_eis_normalized_device_coordinates) as output to get 3D device coordinates and [`AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED`](/ar/reference/c/group/ar-frame#ar_coordinates_3d_eis_texture_normalized) as output to get 3D texture coordinates. For now, the only supported input coordinate type for `ArFrame_transformCoordinates3d` is `AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES`. \n\n```c\nint kNumVertices = 4;\n// Positions of the quad vertices in clip space (X, Y).\nconst GLfloat kVertices[] = {\n -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,\n};\nfloat transformed_vertices_[4 * 3];\nfloat transformed_uvs_[4 * 3];\n\nArFrame_transformCoordinates3d(\n session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,\n kNumVertices, kVertices,\n AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES,\n transformed_vertices_);\nArFrame_transformCoordinates3d(\n session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,\n kNumVertices, kVertices, AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED,\n transformed_uvs_);\n\nglActiveTexture(GL_TEXTURE0);\nglBindTexture(GL_TEXTURE_EXTERNAL_OES, camera_texture_id_);\nglUseProgram(camera_program_);\nglUniform1i(camera_texture_uniform_, 0);\n\n// Set the vertex positions and texture coordinates.\nglVertexAttribPointer(camera_position_attrib_, 3, GL_FLOAT, false, 0,\n transformed_vertices_);\nglVertexAttribPointer(camera_tex_coord_attrib_, 3, GL_FLOAT, false, 0,\n transformed_uvs_);\nglEnableVertexAttribArray(camera_position_attrib_);\nglEnableVertexAttribArray(camera_tex_coord_attrib_);\n```\n\nWhen EIS is off, the output 3D coordinates are equivalent to their 2D counterparts, with z values set to produce no change.\n\nModify shaders\n--------------\n\nThe 3D coordinates calculated about should be passed to background rendering shaders. The vertex buffers are now 3D with EIS: \n\n layout(location = 0) in vec4 a_Position;\n layout(location = 1) in vec3 a_CameraTexCoord;\n out vec3 v_CameraTexCoord;\n void main() {\n gl_Position = a_Position;\n v_CameraTexCoord = a_CameraTexCoord;\n }\n\nAdditionally, the fragment shader needs to apply perspective correction: \n\n precision mediump float;\n uniform samplerExternalOES u_CameraColorTexture;\n in vec3 v_CameraTexCoord;\n layout(location = 0) out vec4 o_FragColor;\n void main() {\n vec3 tc = (v_CameraTexCoord / v_CameraTexCoord.z);\n o_FragColor = texture(u_CameraColorTexture, tc.xy);\n }\n\nSee the [hello_eis_kotlin](https://github.com/google-ar/arcore-android-sdk/tree/master/samples/hello_eis_kotlin) sample app for more details."]]