Ổn định hình ảnh máy ảnh trên Android NDK (C)

ARCore hiện hỗ trợ tính năng Ổn định hình ảnh điện tử (EIS), giúp tạo bản xem trước máy ảnh mượt mà. EIS đạt được độ ổn định bằng cách quan sát chuyển động của điện thoại bằng con quay hồi chuyển và áp dụng lưới homography bù trong phạm vi kết cấu của máy ảnh để chống lại các chuyển động rung nhỏ. EIS chỉ được hỗ trợ ở hướng dọc của thiết bị. Tất cả hướng sẽ được hỗ trợ trong bản phát hành 1.39.0 của ARCore.

Truy vấn để hỗ trợ EIS và bật EIS

Để bật EIS, hãy định cấu hình phiên của bạn để sử dụng AR_IMAGE_STABILIZATION_MODE_EIS. Nếu thiết bị không hỗ trợ tính năng EIS, thì điều này sẽ khiến ARCore gửi một ngoại lệ.

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);

Chuyển đổi toạ độ

Khi EIS đang bật, trình kết xuất cần sử dụng toạ độ thiết bị đã sửa đổi và toạ độ kết cấu phù hợp kết hợp với thông tin bù EIS khi kết xuất nền của máy ảnh. Để lấy toạ độ được bù EIS, hãy sử dụng ArFrame_transformCoordinates3d, sử dụng AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES làm dữ liệu đầu vào và AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES làm dữ liệu đầu ra để lấy toạ độ thiết bị 3D và AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED làm dữ liệu đầu ra để lấy toạ độ kết cấu 3D. Hiện tại, loại toạ độ đầu vào duy nhất được hỗ trợ cho ArFrame_transformCoordinates3dAR_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_);

Khi EIS tắt, toạ độ 3D đầu ra tương đương với toạ độ 2D, với các giá trị z được đặt để không tạo ra thay đổi nào.

Sửa đổi chương trình đổ bóng

Toạ độ 3D được tính toán phải được truyền đến chương trình đổ bóng kết xuất trong nền. Vùng đệm đỉnh hiện là 3D với 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;
}

Ngoài ra, chương trình đổ bóng mảnh cần áp dụng tính năng chỉnh sửa phối cảnh:

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);
}

Hãy xem ứng dụng mẫu hello_eis_kotlin để biết thêm thông tin chi tiết.