Skip to content

videoio: add support for obsensor (Orbbec RGB-D Camera ) #22196

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 4 commits into from
Jul 26, 2022
Merged

Conversation

hzcyf
Copy link
Contributor

@hzcyf hzcyf commented Jul 5, 2022

VideoCapture for OBSensor

OBSensor is Orbbec's new generation RGB-D camera brand, based on UVC protocol. The purpose is to let OpenCV read RGB and depth data from Orbbec RGB-D Camera via UVC protocol, rather than relying on the 3rdparty library (like OpenNI). This will greatly facilitate users to directly read, use and process the depth camera in OpenCV.

Supported Orbbec Device

  • Orbbec Astra+: detail
    • Depth Stream (640x480x30 fps CV_16UC1)
    • RGB Stream (640x480x30fps BGR)
  • Orbbec Femto: detail
    • Depth Stream (640x480x30 fps CV_16UC1)
    • RGB Stream (640x480x30fps BGR)
  • Orbbec future device:
    • ...

Supported OS: Windows and Linux. (MacOX will be supported in near future.)
Supported HW: x86, x64, ARM.

Since the new Orbbec devices rely on UVC, while old devices still rely on OpenNI. This will cause OBSensor doesn't support some old Orbbec cameras, and the following is a list of specific unsupported devices:

  • Orbbec Astra
  • Orbbec Astra Pro

For these unspported devices, we still need the support of OpenNI, please refer to the detailed tutorial of Using Orbbec Astra 3D cameras in OpenCV.

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • The feature is well documented and sample code can be built with the project CMake
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
  • The PR is proposed to the proper branch

@hzcyf hzcyf changed the title videoio: add supported for obsensor (Orbbec RGB-D Camera ) videoio: add support for obsensor (Orbbec RGB-D Camera ) Jul 5, 2022
@zihaomu zihaomu requested review from zihaomu, vpisarev and alalek July 6, 2022 06:51
Copy link
Member

@zihaomu zihaomu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

@zihaomu
Copy link
Member

zihaomu commented Jul 15, 2022

Functional test report

Testing Code: samples\cpp\videocapture_obsensor.cpp
Testing Camera: Orbbec Femto & Orbbec Astra+

Functional Test summary

Testing platform Test Results
Raspberry Pi 3B, ARM32 Pass
Raspberry Pi 4B, ARM64 Pass
Khadas VIM3, ARM64 Pass
Windows10, X64 Pass
Ubuntu 20.04, X64 Pass

Multi-Camera Test

  • One Orbbec Camera -> Pass
  • One Orbbec Camera and Multiple normal RGB cameras -> Pass
  • Multiple Orbbec Cameras -> Not support in this PR.

some results display

  1. Raspberry Pi 3B, ARM32, Device:Orbbec Astra+
    image3B
  2. Raspberry Pi 4B, ARM64, Device:Orbbec Femto
    image4B
  3. Khadas VIM3, ARM64, Device:Orbbec Astra+
    imageVim3
  4. Windows10, X86, Device:Orbbec Femto
    imageWin10
  5. Ubuntu 20.04, X64, Device:Orbbec Astra+
    imageWin10

virtual void stop() override;

private:
virtual bool setXu(uint8_t ctrl, const uint8_t* data, uint32_t len) override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use int ctrl instead of uint8_t ctrl?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the UVC protocol , the range of ctrl is limited on: 0~255


FrameCallback frameCallback_;
StreamProfile currentProfile_;
int8_t currentStreamIndex_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int currentStreamIndex_;?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currentStreamIndex_ is less than 5, and currentStreamIndex_ < 0 mean error!

Mat adjDepthMap;
while (true)
{
// obsensorCapture >> depthMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this piece of code? I see a very similar chunk of code below

Copy link
Contributor Author

@hzcyf hzcyf Jul 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove this and add some comments

@vpisarev
Copy link
Contributor

@hzcyf, thank you for the contribution! Me and @zihaomu have put some minor comments, but overall the patch looks very good. Please, address the comments and then the patch can be merged

Copy link
Member

@zihaomu zihaomu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@vpisarev
Copy link
Contributor

Looks good to me! @alalek, I think, it can be merged

//! OBSENSOR data given from iamge generator
enum {
CAP_OBSENSOR_DEPTH_MAP = 0, //!< Depth values in mm (CV_16UC1)
CAP_OBSENSOR_BGR_IMAGE = 1, //!< Data given from BGR stream generator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BGR image is preserved to default stream 0 (of any VideoCapture backend)

Copy link
Contributor Author

@hzcyf hzcyf Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the existing code, both OpenNI and Intel Realsense use depth as the default stream。For RGB-D cameras, depth as the default stream is more in line with user needs as they may only need the depth data stream.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vpisarev Vadim, could you take a look on this and put a comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alalek, @hzcyf, I can confirm that for OpenNI and Intel RealSense (PerC) cameras depth map is the default stream. From this point of view the new Orbbec API follows this tradition. I think, it should be retained as-is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem is that this support is enabled by default (for many build configurations).
Existed user code may not expect non 8UC3 data and crash (16SC1/16UC1 or 32FC1 are used for depth).
Exception is preferable (and reliable for this case) than silent replacing of 8UC3 result.

If we go in this way, then we must update many sample code / documentation snippets / etc. But this would not resolve problem with existed users code.

BTW, another approach may go through another API, like VideoDepthCapture. Including OpenNI/Realsense "buggy" cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alalek, there is already such situation with OpenNI and PerC and so far it did not cause any major problems. Let me merge this PR

while (true)
{
// Grab depth map like this:
// obsensorCapture >> depthMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"default" grab should be preserved for BGR frames (not depth or whatever)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for depth cameras making the "depth" default is fine, I think.

@vpisarev vpisarev merged commit fc3e393 into opencv:4.x Jul 26, 2022
@alalek alalek mentioned this pull request Jul 26, 2022
@asenyaev
Copy link
Contributor

After merging this PR there is a linking issue when building WinPack:

...
     Creating library C:/GHA-OCV-3/_work/ci-gha-workflow/ci-gha-workflow/build/lib/Release/opencv_world460.lib and object C:/GHA-OCV-3/_work/ci-gha-workflow/ci-gha-workflow/build/lib/Release/opencv_world460.exp
obsensor_stream_channel_msmf.obj : error LNK2019: unresolved external symbol QISearch referenced in function "public: virtual long __cdecl cv::obsensor::MSMFStreamChannel::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@MSMFStreamChannel@obsensor@cv@@UEAAJAEBU_GUID@@PEAPEAX@Z) [C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\modules\world\opencv_world.vcxproj]
C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\bin\Release\opencv_world460.dll : fatal error LNK1120: 1 unresolved externals [C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\modules\world\opencv_world.vcxproj]

Steps to reproduce:

  1. Clone OpenCV 4.x branch:
git clone --branch 4.x git@github.com:opencv/opencv.git
  1. Run CMake:
cmake -B build -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DOPENCV_INSTALL_DATA_DIR_RELATIVE=../../../../sources -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DINSTALL_CREATE_DISTRIB=ON -DBUILD_DOCS=OFF -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DWITH_CUDA=OFF -DBUILD_opencv_java=OFF opencv
  1. Compile OpenCV:
cmake --build build --config release --target install

@hzcyf
Copy link
Contributor Author

hzcyf commented Jul 30, 2022

After merging this PR there is a linking issue when building WinPack:

...
     Creating library C:/GHA-OCV-3/_work/ci-gha-workflow/ci-gha-workflow/build/lib/Release/opencv_world460.lib and object C:/GHA-OCV-3/_work/ci-gha-workflow/ci-gha-workflow/build/lib/Release/opencv_world460.exp
obsensor_stream_channel_msmf.obj : error LNK2019: unresolved external symbol QISearch referenced in function "public: virtual long __cdecl cv::obsensor::MSMFStreamChannel::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@MSMFStreamChannel@obsensor@cv@@UEAAJAEBU_GUID@@PEAPEAX@Z) [C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\modules\world\opencv_world.vcxproj]
C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\bin\Release\opencv_world460.dll : fatal error LNK1120: 1 unresolved externals [C:\GHA-OCV-3\_work\ci-gha-workflow\ci-gha-workflow\build\modules\world\opencv_world.vcxproj]

Steps to reproduce:

  1. Clone OpenCV 4.x branch:
git clone --branch 4.x git@github.com:opencv/opencv.git
  1. Run CMake:
cmake -B build -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DOPENCV_INSTALL_DATA_DIR_RELATIVE=../../../../sources -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DINSTALL_CREATE_DISTRIB=ON -DBUILD_DOCS=OFF -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DWITH_CUDA=OFF -DBUILD_opencv_java=OFF opencv
  1. Compile OpenCV:
cmake --build build --config release --target install

Currently, you could avoid this problem by disable cmake option BUILD_OBSENSOR . And I will fix this soon!

@alalek
Copy link
Member

alalek commented Aug 21, 2022

vpisarev merged commit fc3e393 into opencv:4.x 26 days ago

Rage merge should not happen at all.
Especially without passed CI checks.

modules/videoio/include/opencv2/videoio.hpp:662: trailing whitespace.
+enum VideoCaptureOBSensorDataType{ 
modules/videoio/include/opencv2/videoio.hpp:669: trailing whitespace.
+enum VideoCaptureOBSensorGenerators{ 
modules/videoio/include/opencv2/videoio.hpp:672: trailing whitespace.
+    CAP_OBSENSOR_IR_GENERATOR    = 1 << 27,  
modules/videoio/include/opencv2/videoio.hpp:676: trailing whitespace.
+//!OBSENSOR properties 
modules/videoio/src/cap_obsensor/obsensor_stream_channel_msmf.hpp:45: trailing whitespace.
+#include <ksmedia.h> 
modules/videoio/src/cap_obsensor/obsensor_uvc_stream_channel.cpp:64: trailing whitespace.
+        uvcDevName[i] = (char)tolower(uvcDevName[i]); 
samples/cpp/videocapture_obsensor.cpp:20: trailing whitespace.
+   

@alalek alalek mentioned this pull request Aug 21, 2022
@zihaomu zihaomu mentioned this pull request Aug 22, 2022
6 tasks
@asmorkalov asmorkalov added this to the 4.7.0 milestone Jan 23, 2023
a-sajjad72 pushed a commit to a-sajjad72/opencv that referenced this pull request Mar 30, 2023
* videoio: add support for obsensor (Orbbec RGB-D Camera )

* obsensor: code format issues fixed and some code optimized

* obsensor: fix typo and format issues

* obsensor: fix crosses initialization error
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants