|
|
@@ -61,6 +61,29 @@ namespace orb_camera_impl {
|
|
|
return create_image(f32_info);
|
|
|
}
|
|
|
|
|
|
+ pc_ptr pc_frame_to_pc(const frame_type &frame) {
|
|
|
+ assert(frame->format() == OB_FORMAT_RGB_POINT);
|
|
|
+ auto size = frame->dataSize() / sizeof(OBColorPoint);
|
|
|
+ auto pc = create_pc(size, PC_XYZ_RGB);
|
|
|
+ auto pc_mem = pc->memory(MEM_HOST);
|
|
|
+ auto start_ptr = (pc_xyz_rgb_type *) pc_mem.start_ptr();
|
|
|
+ auto ptr = start_ptr;
|
|
|
+ for (auto k = 0; k < size; ++k) { // TODO: do conversion in CUDA
|
|
|
+ auto ob_ptr = (OBColorPoint *) frame->data() + k;
|
|
|
+ if (ob_ptr->z == 0) continue;
|
|
|
+ ptr->x = ob_ptr->x;
|
|
|
+ ptr->y = ob_ptr->y;
|
|
|
+ ptr->z = ob_ptr->z;
|
|
|
+ ptr->r = ob_ptr->r;
|
|
|
+ ptr->g = ob_ptr->g;
|
|
|
+ ptr->b = ob_ptr->b;
|
|
|
+ ++ptr;
|
|
|
+ }
|
|
|
+ pc->shrink(ptr - start_ptr);
|
|
|
+ pc_mem.modified();
|
|
|
+ return pc;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<ob::Device> orb_camera::impl::get_device(const char *sn) {
|
|
|
@@ -74,6 +97,11 @@ orb_camera::impl *orb_camera::impl::create(orb_camera::create_config conf) {
|
|
|
ret->pipe = std::make_shared<ob::Pipeline>(dev);
|
|
|
ret->ctx = conf.ctx;
|
|
|
ret->stream = conf.stream;
|
|
|
+
|
|
|
+ // load profiles
|
|
|
+ ret->c_pf_list = ret->pipe->getStreamProfileList(OB_SENSOR_COLOR);
|
|
|
+ ret->d_pf_list = ret->pipe->getStreamProfileList(OB_SENSOR_DEPTH);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
@@ -83,9 +111,9 @@ orb_camera::impl::~impl() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void orb_camera::impl::create_video_info_list(
|
|
|
- const pf_list_type &pf_list, v_info_list_type *v_info) {
|
|
|
- v_info->reserve(pf_list->count());
|
|
|
+orb_camera::vi_list_ptr orb_camera::impl::create_video_info_list(const pf_list_type &pf_list) {
|
|
|
+ auto ret = std::make_shared<vi_list_ptr::element_type>();
|
|
|
+ ret->reserve(pf_list->count());
|
|
|
for (uint32_t k = 0; k < pf_list->count(); ++k) {
|
|
|
auto pf = pf_list->getProfile(k)->as<ob::VideoStreamProfile>();
|
|
|
assert(pf != nullptr);
|
|
|
@@ -95,56 +123,79 @@ void orb_camera::impl::create_video_info_list(
|
|
|
info.fps = pf->fps();
|
|
|
info.width = pf->width();
|
|
|
info.height = pf->height();
|
|
|
- v_info->push_back(info);
|
|
|
+ ret->push_back(info);
|
|
|
}
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
-orb_camera::impl::v_info_list_type *
|
|
|
-orb_camera::impl::query_video_info(OBSensorType s_type) {
|
|
|
+orb_camera::vi_list_ptr orb_camera::impl::query_video_info(OBSensorType s_type) {
|
|
|
switch (s_type) {
|
|
|
case OB_SENSOR_COLOR: {
|
|
|
- if (c_pf_list == nullptr) [[unlikely]] {
|
|
|
- c_pf_list = pipe->getStreamProfileList(s_type);
|
|
|
- c_info = std::make_unique<v_info_list_type>();
|
|
|
- create_video_info_list(c_pf_list, c_info.get());
|
|
|
+ if (c_info == nullptr) [[unlikely]] {
|
|
|
+ c_info = create_video_info_list(c_pf_list);
|
|
|
}
|
|
|
- return c_info.get();
|
|
|
+ return c_info;
|
|
|
}
|
|
|
case OB_SENSOR_DEPTH: {
|
|
|
- if (d_pf_list == nullptr) [[unlikely]] {
|
|
|
- d_pf_list = pipe->getStreamProfileList(s_type);
|
|
|
- d_info = std::make_unique<v_info_list_type>();
|
|
|
- create_video_info_list(d_pf_list, d_info.get());
|
|
|
+ if (d_info == nullptr) [[unlikely]] {
|
|
|
+ d_info = create_video_info_list(d_pf_list);
|
|
|
}
|
|
|
- return d_info.get();
|
|
|
+ return d_info;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ RET_ERROR_E;
|
|
|
}
|
|
|
}
|
|
|
- RET_ERROR_P;
|
|
|
+}
|
|
|
+
|
|
|
+orb_camera::vi_list_ptr orb_camera::impl::query_d2c_info(uint32_t c_conf_index) {
|
|
|
+ auto c_pf = c_pf_list->getProfile(c_conf_index);
|
|
|
+ auto d_pf = pipe->getD2CDepthProfileList(c_pf, align_mode);
|
|
|
+ assert(d_pf->count() > 0);
|
|
|
+ return create_video_info_list(d_pf);
|
|
|
}
|
|
|
|
|
|
bool orb_camera::impl::start(start_config conf) {
|
|
|
assert(!is_capturing);
|
|
|
auto ob_conf = std::make_shared<ob::Config>();
|
|
|
|
|
|
+ auto c_prof = std::shared_ptr<ob::StreamProfile>();
|
|
|
if (conf.color.enable) {
|
|
|
assert(c_pf_list != nullptr);
|
|
|
- ob_conf->enableStream(c_pf_list->getProfile(conf.color.config_index));
|
|
|
+ c_prof = c_pf_list->getProfile(conf.color.config_index);
|
|
|
+ ob_conf->enableStream(c_prof);
|
|
|
c_name = conf.color.name;
|
|
|
}
|
|
|
+
|
|
|
+ auto d_prof = std::shared_ptr<ob::StreamProfile>();
|
|
|
if (conf.depth.enable) {
|
|
|
assert(d_pf_list != nullptr);
|
|
|
- ob_conf->enableStream(d_pf_list->getProfile(conf.depth.config_index));
|
|
|
+ if (conf.pc.enable) { // TODO: better determine method
|
|
|
+ assert(c_prof != nullptr);
|
|
|
+ d_prof = pipe->getD2CDepthProfileList(c_prof, align_mode)->getProfile(conf.depth.config_index);
|
|
|
+ } else {
|
|
|
+ d_prof = d_pf_list->getProfile(conf.depth.config_index);
|
|
|
+ }
|
|
|
+ ob_conf->enableStream(d_prof);
|
|
|
d_name = conf.depth.name;
|
|
|
}
|
|
|
|
|
|
if (conf.color.enable && conf.depth.enable) {
|
|
|
- ob_conf->setAlignMode(ALIGN_D2C_HW_MODE);
|
|
|
+ ob_conf->setAlignMode(align_mode);
|
|
|
}
|
|
|
|
|
|
- pipe->start(ob_conf, [this](auto frames) {
|
|
|
- frames_callback(std::move(frames));
|
|
|
- });
|
|
|
+ pipe->start(ob_conf, [this](auto frames) { frames_callback(frames); });
|
|
|
is_capturing = true;
|
|
|
+
|
|
|
+ // Example says that the filter depends on the started pipeline.
|
|
|
+ if (conf.pc.enable) {
|
|
|
+ pc_filter = std::make_shared<ob::PointCloudFilter>();
|
|
|
+ pc_filter->setCameraParam(pipe->getCameraParam());
|
|
|
+ pc_filter->setCreatePointFormat(OB_FORMAT_RGB_POINT);
|
|
|
+ pc_filter->setCallBack([this](auto frame) { pc_callback(frame); });
|
|
|
+ pc_name = conf.pc.name;
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -169,16 +220,28 @@ void orb_camera::impl::frames_callback(const frames_type &frames) {
|
|
|
d_img = depth_y16_to_mm(y16_img, d_frame->getValueScale());
|
|
|
}
|
|
|
|
|
|
+ if (pc_filter != nullptr &&
|
|
|
+ c_img != nullptr && d_img != nullptr) { // depth images may not be ready
|
|
|
+ pc_filter->setPositionDataScaled(frames->depthFrame()->getValueScale());
|
|
|
+ pc_filter->pushFrame(frames);
|
|
|
+ }
|
|
|
+
|
|
|
post(*ctx, [=, _c_name = c_name, _d_name = d_name] {
|
|
|
if (c_img != nullptr) { OBJ_SAVE(_c_name, c_img); }
|
|
|
if (d_img != nullptr) { OBJ_SAVE(_d_name, d_img); }
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+void orb_camera::impl::pc_callback(const frame_type &frame) {
|
|
|
+ auto pc = pc_frame_to_pc(frame);
|
|
|
+ OBJ_SAVE(pc_name, pc);
|
|
|
+}
|
|
|
+
|
|
|
void orb_camera::impl::stop() {
|
|
|
assert(is_capturing);
|
|
|
pipe->stop();
|
|
|
is_capturing = false;
|
|
|
+ pc_filter = nullptr;
|
|
|
}
|
|
|
|
|
|
orb_camera::pointer orb_camera::create(create_config conf) {
|
|
|
@@ -202,8 +265,7 @@ orb_camera::query_device_info() {
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-std::vector<orb_camera::video_info> *
|
|
|
-orb_camera::query_video_info(video_type type) {
|
|
|
+orb_camera::vi_list_ptr orb_camera::query_video_info(video_type type) {
|
|
|
switch (type) {
|
|
|
case V_COLOR:
|
|
|
return pimpl->query_video_info(OB_SENSOR_COLOR);
|
|
|
@@ -213,6 +275,10 @@ orb_camera::query_video_info(video_type type) {
|
|
|
RET_ERROR_P;
|
|
|
}
|
|
|
|
|
|
+orb_camera::vi_list_ptr orb_camera::query_d2c_info(uint32_t c_conf_index) {
|
|
|
+ return pimpl->query_d2c_info(c_conf_index);
|
|
|
+}
|
|
|
+
|
|
|
bool orb_camera::start(orb_camera::start_config conf) {
|
|
|
return pimpl->start(conf);
|
|
|
}
|