Android NDK (C) पर कैमरे की इमेज को स्थिर करें

ARCore अब इलेक्ट्रॉनिक इमेज स्टेबलाइज़ेशन (ईआईएस) के साथ काम करता है, जिससे कैमरे की बेहतरीन झलक मिलती है. ईआईएस, जाइरो का इस्तेमाल करके फ़ोन की गतिविधि पर नज़र रखता है. साथ ही, कैमरा टेक्सचर की सीमाओं में मुआवज़ा वाला होमोग्राफ़ी मेश लगाकर, छोटे-छोटे झटकों का सामना करता है. EIS सिर्फ़ डिवाइस के पोर्ट्रेट ओरिएंटेशन में काम करता है. ARCore की रिलीज़ 1.39.0 में सभी ओरिएंटेशन की सुविधा मिलेगी.

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

निर्देशांक बदलना

ईआईएस चालू होने पर, रेंडरर को डिवाइस के बदले गए निर्देशांक और मिलते-जुलते टेक्सचर कोऑर्डिनेट का इस्तेमाल करना होगा जिनमें कैमरे के बैकग्राउंड को रेंडर करते समय ईआईएस मुआवज़ा शामिल होता है. ईआईएस के लिए मुआवज़ा पाने के लिए, ArFrame_transformCoordinates3d का इस्तेमाल इनपुट के तौर पर AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES और 3D डिवाइस कोऑर्डिनेट पाने के लिए आउटपुट के तौर पर AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES और 3D टेक्सचर कोऑर्डिनेट पाने के लिए आउटपुट के तौर पर 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 बंद होने पर, आउटपुट 3D निर्देशांक उनके 2D मिलते-जुलते निर्देशांकों के बराबर होते हैं, जिनमें z मानों के लिए कोई बदलाव नहीं किया जाता है.

शेडर में बदलाव करें

जिन 3D निर्देशांक की गणना की जाती है वे बैकग्राउंड रेंडरिंग शेडर को भेजे जाने चाहिए. वर्टेक्स बफ़र अब EIS के साथ 3D हो गए हैं:

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 ऐप्लिकेशन का नमूना देखें.