تثبیت تصاویر دوربین در Android NDK (C)

ARCore اکنون از تثبیت‌کننده تصویر الکترونیکی (EIS) پشتیبانی می‌کند، که به ایجاد پیش‌نمایش روان دوربین کمک می‌کند. EIS با مشاهده حرکت تلفن با استفاده از ژیروسکوپ و اعمال مش هموگرافی جبرانی در محدوده بافت دوربین که لرزش های جزئی را مقابله می کند، به تثبیت می رسد. EIS فقط در جهت عمودی دستگاه پشتیبانی می شود. همه جهت‌ها در نسخه 1.39.0 ARCore پشتیبانی خواهند شد.

پرس و جو برای پشتیبانی 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 به عنوان خروجیDORDIN و AR_COORDINATES_DEVICE_COORDINATES به‌عنوان مختصات خروجیDORDINATES_DEVICE_COORDIN استفاده کنید. AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED به عنوان خروجی برای دریافت مختصات بافت سه بعدی. در حال حاضر، تنها نوع مختصات ورودی پشتیبانی شده برای 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 خاموش است، مختصات 3 بعدی خروجی معادل مشابه دوبعدی خود هستند، با مقادیر z برای ایجاد هیچ تغییری تنظیم شده است.

سایه بان ها را اصلاح کنید

مختصات سه بعدی محاسبه شده باید به سایه بان های رندر پس زمینه ارسال شود. بافرهای رأس اکنون سه بعدی با 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 مراجعه کنید.