Browse Source

Implemented stereo image output.

jcsyshc 1 year ago
parent
commit
4564105e16

+ 1 - 0
CMakeLists.txt

@@ -33,6 +33,7 @@ add_executable(${PROJECT_NAME} src/main.cpp
         src/core/impl/object_manager.cpp
         src/core/impl/pc_utility.cpp
         src/module_v3/registration.cpp
+        src/module/guidance/cursor_guide.cpp
         src/module/impl/augment_manager.cpp
         src/module/impl/augment_manager_v2.cpp
         src/module/impl/camera_augment_helper.cpp

+ 4 - 1
data/config_depth_guide_v2.yaml

@@ -27,4 +27,7 @@ registration_list:
     collect_obj: point_picker_in_tibia_ref
     collect_var: picked_point_in_tibia_ref
     target_var: tibia_in_tibia_ref
-    probe_var: probe_in_tibia
+    probe_var: probe_in_tibia
+
+output_width: 1920
+output_height: 1080

+ 1 - 1
src/impl/apps/depth_guide/depth_guide.cpp

@@ -110,7 +110,7 @@ app_depth_guide::app_depth_guide(const create_config &_conf) {
                 .ctx = conf.asio_ctx,
         };
         aug_helper_left = std::make_unique<camera_augment_helper_v2>(aug_conf);
-        aug_helper_left->set_interactive(true);
+        aug_helper_left->set_active_guidance(true);
     }
 }
 

+ 43 - 3
src/impl/apps/depth_guide_v2/depth_guide_v2.cpp

@@ -2,6 +2,8 @@
 #include "core/imgui_utility.hpp"
 #include "image_process/process_funcs.h"
 
+#include <glm/gtx/transform.hpp>
+
 app_depth_guide_v2::app_depth_guide_v2(const create_config &_conf) {
     main_conf = _conf;
     auto conf = main_conf.ext_conf;
@@ -12,6 +14,9 @@ app_depth_guide_v2::app_depth_guide_v2(const create_config &_conf) {
     OBJ_SAVE(img_remap, image_ptr());
     OBJ_SAVE(pc_raw, pc_ptr());
     OBJ_SAVE(scene_out, scene_ptr());
+    OBJ_SAVE(img_out_left, image_ptr());
+    OBJ_SAVE(img_out_right, image_ptr());
+    OBJ_SAVE(img_out, image_ptr());
 
     // initialize meta
     OBJ_PIN_META(pc_raw, META_SERIES_NAME, meta_hash("pc_raw"));
@@ -26,6 +31,14 @@ app_depth_guide_v2::app_depth_guide_v2(const create_config &_conf) {
     });
     OBJ_SIG(pc_raw)->connect([this](auto _) {
         aug_manager->update(aug_helper->get_camera());
+
+        auto out_conf = camera_augment_helper_v2::output_config{
+                .size = aug_stereo->get_suggest_size(), .stream = default_cuda_stream,
+        };
+        out_conf.img_name = img_out_left;
+        aug_left->render_image(out_conf);
+        out_conf.img_name = img_out_right;
+        aug_right->render_image(out_conf);
     });
 
     // initialize sophiar
@@ -60,15 +73,37 @@ app_depth_guide_v2::app_depth_guide_v2(const create_config &_conf) {
     auto view_conf = camera_augment_helper_v2::create_config{
             .camera = camera_augment_helper_v2::create_config::freedom_camera_config{
                     .transform_var = LOAD_STR("camera_transform_var")},
-            .sophiar_conn= sophiar_conn.get(),
+            .sophiar_conn = sophiar_conn.get(),
             .manager = aug_manager.get(),
             .ctx = main_conf.asio_ctx,
     };
     aug_helper = std::make_unique<camera_augment_helper_v2>(view_conf);
-    aug_helper->set_interactive(true);
+    aug_helper->set_active_guidance(true);
+
+    view_conf.camera = camera_augment_helper_v2::create_config::relative_camera_config{
+            .parent = aug_helper.get(),
+            .transform  = glm::translate(glm::vec3(-baseline_dis / 2, 0, 0))};
+    aug_left = std::make_unique<camera_augment_helper_v2>(view_conf);
+    aug_left->sync_with(aug_helper.get());
+
+    view_conf.camera = camera_augment_helper_v2::create_config::relative_camera_config{
+            .parent = aug_helper.get(),
+            .transform  = glm::translate(glm::vec3(baseline_dis / 2, 0, 0))};
+    aug_right = std::make_unique<camera_augment_helper_v2>(view_conf);
+    aug_right->sync_with(aug_helper.get());
+
+    auto output_size = cv::Size(
+            LOAD_NUMBER(int, "output_width"),
+            LOAD_NUMBER(int, "output_height"));
+    auto stereo_conf = stereo_augment_helper::create_config{
+            .left_name = img_out_left, .right_name = img_out_right,
+            .out_name = img_out, .fbo_size = output_size,
+            .flip_image = true, .stream = default_cuda_stream,
+    };
+    aug_stereo = std::make_unique<stereo_augment_helper>(stereo_conf);
 
     auto out_conf = image_streamer::create_config{
-            .img_name = scene_out, .encode_scene = true,
+            .img_name = img_out, .encode_scene = false,
             .asio_ctx = main_conf.asio_ctx,
             .cuda_ctx = main_conf.cuda_ctx, .stream = default_cuda_stream
     };
@@ -111,6 +146,11 @@ void app_depth_guide_v2::show_ui() {
                 auto id_guard = imgui_id_guard("augment_camera");
                 aug_helper->show();
             }
+            {
+                ImGui::SeparatorText("Stereo");
+                auto id_guard = imgui_id_guard("stereo");
+                aug_stereo->show();
+            }
         }
 
         if (ImGui::CollapsingHeader("Streamer")) {

+ 11 - 1
src/impl/apps/depth_guide_v2/depth_guide_v2.h

@@ -6,6 +6,7 @@
 #include "module_v3/registration.h"
 #include "module/augment_manager_v2.h"
 #include "module/camera_augment_helper_v2.h"
+#include "module/image_augment_helper.h"
 #include "module/image_streamer.h"
 #include "impl/app_base.h"
 
@@ -36,9 +37,13 @@ private:
         // point cloud from device
         pc_raw,
 
-        // output image
+        // output scene
         scene_out,
 
+        // output image
+        img_out_left, img_out_right,
+        img_out,
+
         name_end,
     };
 
@@ -58,6 +63,11 @@ private:
     std::unique_ptr<augment_manager_v2> aug_manager;
     std::unique_ptr<camera_augment_helper_v2> aug_helper;
 
+    static constexpr auto baseline_dis = 65.0f; // mm
+    std::unique_ptr<camera_augment_helper_v2> aug_left;
+    std::unique_ptr<camera_augment_helper_v2> aug_right;
+    std::unique_ptr<stereo_augment_helper> aug_stereo;
+
     bool enable_reg = false;
     std::unique_ptr<registration> reg;
 

+ 0 - 1
src/impl/apps/remote_ar/remote_ar.cpp

@@ -119,7 +119,6 @@ app_remote_ar::app_remote_ar(const create_config &_conf) {
 
     auto right_aug_conf = camera_augment_helper_v2::create_config{
             .camera = camera_augment_helper_v2::create_config::relative_camera_config{
-                    .fov = view_angle,
                     .parent = cam_left.aug_helper.get(),
                     .transform = glm::inverse(to_mat4(stereo_info.transform)),
             },

+ 1 - 1
src/impl/apps/scene_player/scene_player.cpp

@@ -28,7 +28,7 @@ app_scene_player::app_scene_player(const create_config &_conf) {
             .ctx = main_conf.asio_ctx,
     };
     aug_helper = std::make_unique<camera_augment_helper_v2>(view_conf);
-    aug_helper->set_interactive(true);
+    aug_helper->set_active_guidance(true);
 
     register_mesh_list(LOAD_LIST("mesh_list"));
 }

+ 6 - 0
src/module/augment_manager_v2.h

@@ -14,6 +14,8 @@
 
 #include <memory>
 
+class camera_augment_helper_v2;
+
 class augment_manager_v2 {
 public:
 
@@ -68,6 +70,10 @@ public:
     render_sig_type pre_render_sig;
     render_sig_type post_render_sig;
 
+    void record_current_camera_helper(camera_augment_helper_v2 *cam);
+
+    camera_augment_helper_v2 *get_current_camera_helper();
+
 private:
     struct impl;
     std::unique_ptr<impl> pimpl;

+ 11 - 2
src/module/camera_augment_helper_v2.h

@@ -22,7 +22,6 @@ public:
         };
 
         struct relative_camera_config {
-            float fov = 60.0f; // field of view
             camera_augment_helper_v2 *parent = nullptr;
             glm::mat4 transform = glm::mat4(1.0f); // viewed in parent
         };
@@ -61,7 +60,15 @@ public:
 
     void show();
 
-    void set_interactive(bool flag);
+    void sync_with(camera_augment_helper_v2 *other);
+
+    void set_active_guidance(bool flag);
+
+    struct guide_info {
+        glm::vec2 pos;
+    };
+
+    void set_passive_guidance(bool flag, const guide_info &info);
 
     camera_info get_camera();
 
@@ -70,4 +77,6 @@ private:
     std::unique_ptr<impl> pimpl;
 };
 
+
+
 #endif //DEPTHGUIDE_CAMERA_AUGMENT_HELPER_V2_H

+ 51 - 0
src/module/guidance/cursor_guide.cpp

@@ -0,0 +1,51 @@
+#include "cursor_guide.h"
+
+#include <glm/gtx/transform.hpp>
+
+#include <vtkSphereSource.h>
+
+struct cursor_guide::impl {
+
+    std::optional<glm::vec3> cursor_pos; // in world coordinate
+    mesh_ptr cursor_symbol;
+
+    void update(const guide_info &info) {
+        cursor_pos = info.position;
+    }
+
+    void pre_render_slot(const scene_ptr &info) {
+        if (!cursor_pos.has_value()) return;
+
+        if (cursor_symbol == nullptr) [[unlikely]] {
+            vtkNew<vtkSphereSource> source;
+            source->SetRadius(5); // TODO: make this adjustable
+            source->SetCenter(0, 0, 0);
+            source->Update();
+            cursor_symbol = mesh_type::from_vtk(source->GetOutput());
+        }
+
+        auto color = glm::vec3(0.0f, 1.0f, 0.0f); // TODO: make this adjustable
+        auto amb_factor = 0.9f;
+        auto item_info = scene_render_info::mesh_info{
+                .mesh = cursor_symbol,
+                .material = {.ambient = color * amb_factor, .diffuse = color,},
+        };
+        info->items.push_back(
+                {.info = item_info, .transform = glm::translate(*cursor_pos),});
+    }
+
+};
+
+cursor_guide::cursor_guide()
+        : pimpl(std::make_unique<impl>()) {
+}
+
+cursor_guide::~cursor_guide() = default;
+
+void cursor_guide::update(const guide_info &info) {
+    pimpl->update(info);
+}
+
+void cursor_guide::pre_render_slot(const scene_ptr &info) {
+    pimpl->pre_render_slot(info);
+}

+ 34 - 0
src/module/guidance/cursor_guide.h

@@ -0,0 +1,34 @@
+#ifndef DEPTHGUIDE_CURSOR_GUIDE_H
+#define DEPTHGUIDE_CURSOR_GUIDE_H
+
+#include "module/camera_augment_helper_v2.h"
+
+#include <memory>
+
+class cursor_guide {
+public:
+
+//    struct create_config {
+////        camera_augment_helper_v2 *parent;
+//    };
+
+    cursor_guide();
+
+    ~cursor_guide();
+
+    struct guide_info {
+        std::optional<glm::vec3> position; // 3D position of cursor
+        float mouse_wheel = 0.f;
+    };
+
+    void update(const guide_info &info);
+
+    void pre_render_slot(const scene_ptr &info);
+
+private:
+    struct impl;
+    std::unique_ptr<impl> pimpl;
+};
+
+
+#endif //DEPTHGUIDE_CURSOR_GUIDE_H

+ 2 - 0
src/module/image_augment_helper.h

@@ -59,6 +59,8 @@ public:
 
     void resize(cv::Size size);
 
+    cv::Size get_suggest_size() const;
+
     struct ui_config {
         bool follow_image_size = false;
         bool enable_halve_width = false;

+ 8 - 0
src/module/impl/augment_manager_v2.cpp

@@ -216,4 +216,12 @@ augment_manager_v2::item_list_from_v1(const item_list_v1_type &items,
         OBJ_SAVE(item.name, mesh);
     }
     return ret;
+}
+
+void augment_manager_v2::record_current_camera_helper(camera_augment_helper_v2 *cam) {
+    pimpl->cam_helper = cam;
+}
+
+camera_augment_helper_v2 *augment_manager_v2::get_current_camera_helper() {
+    return pimpl->cam_helper;
 }

+ 2 - 0
src/module/impl/augment_manager_v2_impl.h

@@ -64,6 +64,8 @@ struct augment_manager_v2::impl {
 
     vgm::Vec3 light_direction = {0.0f, 0.0f, -1.0f};
 
+    camera_augment_helper_v2 *cam_helper = nullptr;
+
     // low-level GL_POINT info
     struct {
         GLfloat min, max;

+ 50 - 62
src/module/impl/camera_augment_helper_v2.cpp

@@ -6,12 +6,8 @@
 #include <glm/gtc/type_ptr.hpp>
 #include <glm/gtx/rotate_vector.hpp>
 
-#include <glm/gtx/string_cast.hpp>
-
 #include <boost/asio/post.hpp>
 
-#include <vtkSphereSource.h>
-
 using boost::asio::post;
 
 void camera_augment_helper_v2::impl::freedom_info_type::reset() {
@@ -60,7 +56,6 @@ void camera_augment_helper_v2::impl::freedom_info_type::move_right(float dis) {
     translate(-axis * dis);
 }
 
-// TODO: using accelerometer determined world coordinate
 void camera_augment_helper_v2::impl::freedom_info_type::move_up(float dis) {
     translate(view_up * dis);
 }
@@ -115,7 +110,6 @@ camera_augment_helper_v2::impl::impl(const create_config &conf) {
         case 3: {
             mode = MODE_RELATIVE;
             auto info = std::get<3>(conf.camera);
-            fov = info.fov;
             relative_info.parent = info.parent->pimpl.get();
             relative_info.transform = info.transform;
             break;
@@ -162,6 +156,7 @@ void camera_augment_helper_v2::impl::update_relative() {
     par->update_transform();
     is_missing = par->is_missing;
     transform = par->transform * relative_info.transform;
+    fov = par->fov;
 }
 
 void camera_augment_helper_v2::impl::update_transform() {
@@ -178,15 +173,16 @@ void camera_augment_helper_v2::impl::update_camera() {
     update_transform();
     last_camera = camera_info{
             .transform = transform, .fov = fov,
-            .near = near, .far = far
+            .near = ui->near, .far = ui->far
     };
 }
 
 void camera_augment_helper_v2::impl::render() {
-    if (!is_missing || ignore_missing) {
+    if (!is_missing || ui->ignore_missing) {
         update_camera();
-        manager->render(last_camera);
         last_vp_size = query_viewport_size();
+        manager->record_current_camera_helper(q_this);
+        manager->render(last_camera);
     }
 }
 
@@ -265,9 +261,11 @@ void camera_augment_helper_v2::impl::show_fixed() {
 }
 
 void camera_augment_helper_v2::impl::show() {
-    ImGui::Checkbox("Ignore Missing", &ignore_missing); // TODO: enable sync with another
-    ImGui::SliderFloat("Clip Near", &near, 1.0f, far, "%.f", ImGuiSliderFlags_Logarithmic);
-    ImGui::SliderFloat("Clip Far", &far, near, 10000.0f, "%.f", ImGuiSliderFlags_Logarithmic);
+    ImGui::Checkbox("Ignore Missing", &ui->ignore_missing); // TODO: enable sync with another
+    ImGui::SameLine();
+    ImGui::Checkbox("Guidance", &ui->enable_active_guide);
+    ImGui::SliderFloat("Clip Near", &ui->near, 1.0f, ui->far, "%.f", ImGuiSliderFlags_Logarithmic);
+    ImGui::SliderFloat("Clip Far", &ui->far, ui->near, 10000.0f, "%.f", ImGuiSliderFlags_Logarithmic);
 
     switch (mode) {
         // @formatter:off
@@ -279,25 +277,18 @@ void camera_augment_helper_v2::impl::show() {
             RET_ERROR;
         }
     }
-
-    if (is_interactive) {
-        ImGui::Checkbox("Cursor Guide", &enable_cursor_guide);
-    }
 }
 
-void camera_augment_helper_v2::impl::update_cursor_coordinate() {
-    assert(enable_cursor_guide);
-    cursor_pos = {};
-
-    auto s_pos = ImGui::GetMousePos();
+std::optional<glm::vec3> camera_augment_helper_v2::impl::
+get_cursor_coordinate(glm::vec2 s_pos) {
     auto w = last_vp_size.width, h = last_vp_size.height;
-    if (s_pos.x < 0 || s_pos.x > w) return;
-    if (s_pos.y < 0 || s_pos.y > h) return;
+    if (s_pos.x < 0 || s_pos.x > w) return {};
+    if (s_pos.y < 0 || s_pos.y > h) return {};
     s_pos.y = h - s_pos.y; // flip y to texture coordinate
 
     float depth;
     glReadPixels(s_pos.x, s_pos.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
-    if (depth == 1.f) return;
+    if (depth == 1.f) return {};
 
     auto proj = last_camera.projection(last_vp_size.aspectRatio());
     auto ndc = glm::vec3(s_pos.x / w, s_pos.y / h, depth);
@@ -308,52 +299,40 @@ void camera_augment_helper_v2::impl::update_cursor_coordinate() {
                                glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); // camera -> viewport
     auto w_pos_h = cam_mat * to_homo(c_pos);
     auto w_pos = from_homo(w_pos_h);
-    cursor_pos = w_pos;
+    return w_pos;
 }
 
-void camera_augment_helper_v2::impl::cursor_guide_slot(const scene_ptr &info) {
-    assert(enable_cursor_guide);
-
-    if (cursor_symbol == nullptr) [[unlikely]] {
-        vtkNew<vtkSphereSource> source;
-        source->SetRadius(5); // TODO: make this adjustable
-        source->SetCenter(0, 0, 0);
-        source->Update();
-        cursor_symbol = mesh_type::from_vtk(source->GetOutput());
-    }
-
-    // record cursor position
-    auto rec_info = scene_render_info::custom_info{
-            .func = [this] { update_cursor_coordinate(); },
-    };
-    info->items.push_back({.info = rec_info});
-
-    if (cursor_pos.has_value()) {
-        auto color = glm::vec3(0.0f, 1.0f, 0.0f); // TODO: make this adjustable
-        auto amb_factor = 0.9f;
-        auto item_info = scene_render_info::mesh_info{
-                .mesh = cursor_symbol,
-                .material = {.ambient = color * amb_factor, .diffuse = color,},
-                .enable_depth_alpha = true, .alpha_factor = 0.f,
+void camera_augment_helper_v2::impl::pre_render_slot(const scene_ptr &info) {
+    if (ui->enable_active_guide && allow_active_guide) {
+        auto s_pos = ImGui::GetMousePos();
+        auto rec_info = scene_render_info::custom_info{
+                .func = [=, this] {
+                    if (manager->get_current_camera_helper() != q_this) {
+                        return; // not current camera helper
+                    }
+                    auto w_pos = get_cursor_coordinate(to_vec2(s_pos));
+                    act_guide.update({.position = w_pos});
+                },
         };
-        info->items.push_back(
-                {.info = item_info, .transform = glm::translate(*cursor_pos),});
+        info->items.push_back({.info = rec_info});
+        act_guide.pre_render_slot(info);
     }
-}
 
-void camera_augment_helper_v2::impl::pre_render_slot(const scene_ptr &info) {
-    if (!is_interactive) return;
-    if (enable_cursor_guide) {
-        cursor_guide_slot(info);
+    if (enable_passive_guide) {
+        auto rec_info = scene_render_info::custom_info{
+                .func = [=, this] {
+                    auto w_pos = get_cursor_coordinate(pas_info.pos);
+                    pas_guide.update({.position = w_pos});
+                },
+        };
+        info->items.push_back({.info = rec_info});
+        pas_guide.pre_render_slot(info);
     }
 }
 
-void camera_augment_helper_v2::impl::set_interactive(bool flag) {
-    is_interactive = flag;
-}
-
 camera_augment_helper_v2::camera_augment_helper_v2(const create_config &conf)
         : pimpl(std::make_unique<impl>(conf)) {
+    pimpl->q_this = this;
 }
 
 camera_augment_helper_v2::~camera_augment_helper_v2() = default;
@@ -370,11 +349,20 @@ void camera_augment_helper_v2::show() {
     pimpl->show();
 }
 
-void camera_augment_helper_v2::set_interactive(bool flag) {
-    pimpl->set_interactive(flag);
+void camera_augment_helper_v2::sync_with(camera_augment_helper_v2 *other) {
+    pimpl->ui = other->pimpl->ui;
 }
 
 camera_info camera_augment_helper_v2::get_camera() {
     pimpl->update_camera();
     return pimpl->last_camera;
+}
+
+void camera_augment_helper_v2::set_active_guidance(bool flag) {
+    pimpl->allow_active_guide = flag;
+}
+
+void camera_augment_helper_v2::set_passive_guidance(bool flag, const guide_info &info) {
+    pimpl->enable_passive_guide = flag;
+    pimpl->pas_info = info;
 }

+ 25 - 13
src/module/impl/camera_augment_helper_v2_impl.h

@@ -3,13 +3,15 @@
 
 #include "module/camera_augment_helper_v2.h"
 #include "module/viewport_downloader.hpp"
+#include "module/guidance/cursor_guide.h"
 
 struct camera_augment_helper_v2::impl {
 
+    camera_augment_helper_v2 *q_this = nullptr;
+
     std::string transform_var; // sophiar
     std::optional<glm::mat4> tracked_transform; // transform matrix from sophiar
     bool is_missing = false;
-    bool ignore_missing = false;
 
     augment_manager_v2 *manager = nullptr;
     using sophiar_conn_type = create_config::sophiar_conn_type;
@@ -17,10 +19,18 @@ struct camera_augment_helper_v2::impl {
     using io_context = boost::asio::io_context;
     io_context *ctx = nullptr;
 
+    struct ui_conf {
+        bool ignore_missing = false;
+        bool enable_active_guide = false;
+        float near = 10.0f;
+        float far = 1000.0f; // clip range (mm)
+    };
+
+    std::shared_ptr<ui_conf> ui =
+            std::make_shared<ui_conf>();
+
     // for all
     float fov = 60.0f; // field of view
-    float near = 10.0f;
-    float far = 1000.0f; // clip range (mm)
     glm::mat4 transform; // standard camera transform
 
     struct fixed_info_type {
@@ -87,14 +97,17 @@ struct camera_augment_helper_v2::impl {
     using conn_type = boost::signals2::connection;
     conn_type pre_render_conn;
 
-    bool is_interactive = false;
-
     camera_info last_camera;
     cv::Size last_vp_size;
 
-    bool enable_cursor_guide = false;
-    std::optional<glm::vec3> cursor_pos; // in world coordinate
-    mesh_ptr cursor_symbol;
+    // active guidance
+    bool allow_active_guide = false;
+    cursor_guide act_guide;
+
+    // passive guidance
+    bool enable_passive_guide = false;
+    guide_info pas_info;
+    cursor_guide pas_guide;
 
     explicit impl(const create_config &conf);
 
@@ -122,14 +135,13 @@ struct camera_augment_helper_v2::impl {
 
     void show();
 
-    void update_cursor_coordinate();
-
-    void cursor_guide_slot(const scene_ptr &info);
+    // get cursor position in world coordinate
+    // must be called during rendering process
+    // s_pos: mouse position in screen
+    std::optional<glm::vec3> get_cursor_coordinate(glm::vec2 s_pos);
 
     void pre_render_slot(const scene_ptr &info);
 
-    void set_interactive(bool flag);
-
 };
 
 #endif //DEPTHGUIDE_CAMERA_AUGMENT_HELPER_V2_IMPL_H

+ 15 - 2
src/module/impl/image_augment_helper.cpp

@@ -86,7 +86,7 @@ stereo_augment_helper::impl::impl(const create_config &_conf) {
 }
 
 void stereo_augment_helper::impl::process() {
-    auto img_size = get_image_size(conf.left_name);
+    auto img_size = to_image(conf.left_name)->size();
     if (img_size.empty()) return;
     if (ui.follow_image_size) {
         auto fbo_size = cv::Size(img_size.width * 2, img_size.height);
@@ -120,7 +120,7 @@ void stereo_augment_helper::impl::process() {
     ren_conf.range = right_rect;
     image_ren.render(conf.right_name, ren_conf);
 
-    auto out_img = img_downloader->download_argb(); // TODO: more elegant
+    auto out_img = img_downloader->download_v2(COLOR_ARGB); // TODO: more elegant
     OBJ_SAVE(conf.out_name, out_img);
 
     fbo.unbind();
@@ -146,6 +146,15 @@ void stereo_augment_helper::impl::resize(cv::Size size) {
     fbo.create(fbo_conf);
 }
 
+cv::Size stereo_augment_helper::impl::get_suggest_size() const {
+    if (ui.enable_halve_width) {
+        return fbo_conf.size;
+    } else {
+        return {fbo_conf.size.width >> 1,
+                fbo_conf.size.height};
+    }
+}
+
 stereo_augment_helper::stereo_augment_helper(const create_config &conf)
         : pimpl(std::make_unique<impl>(conf)) {
 }
@@ -156,6 +165,10 @@ void stereo_augment_helper::resize(cv::Size size) {
     pimpl->resize(size);
 }
 
+cv::Size stereo_augment_helper::get_suggest_size() const {
+    return pimpl->get_suggest_size();
+}
+
 void stereo_augment_helper::fix_ui_config(ui_config conf) {
     pimpl->fix_ui_config(conf);
 }

+ 2 - 0
src/module/impl/image_augment_helper_impl.h

@@ -47,6 +47,8 @@ struct stereo_augment_helper::impl {
 
     void resize(cv::Size size);
 
+    cv::Size get_suggest_size() const;
+
     void fix_ui_config(ui_config conf);
 
     void show();

+ 2 - 2
src/module/impl/image_streamer.cpp

@@ -28,7 +28,7 @@ void image_streamer::impl::create_scene_encoder() {
 void image_streamer::impl::create_encoder() {
     switch (chose_encoder_type) {
         case ENCODER_NVENC: {
-            img_size = get_image_size(conf.img_name);
+            img_size = to_image(conf.img_name)->size();
             if (img_size.empty()) break; // lazy create
             int img_freq = conf.frame_rate.value_or(
                     std::round(OBJ_STATS(conf.img_name).save_frequency));
@@ -215,7 +215,7 @@ frame_info image_streamer::impl::encode_image() {
 
     switch (chose_encoder_type) {
         case ENCODER_NVENC: {
-            auto img = OBJ_QUERY(image_u8c4, conf.img_name);
+            auto img = to_image(conf.img_name);
             if (img->size() != img_size) { // recreate encoder
                 enc_nvenc = nullptr;
                 create_encoder();