Merge pull request #27629 from asmorkalov:as/added_orbbec_sdk_init_params

Added options to initialize Orbbec cameras with custom fps and resolution
This commit is contained in:
Alexander Smorkalov 2025-08-06 11:29:48 +03:00 committed by GitHub
commit a265947356
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 177 additions and 37 deletions

View File

@ -716,6 +716,9 @@ enum VideoCaptureOBSensorProperties{
CAP_PROP_OBSENSOR_INTRINSIC_CY=26004, CAP_PROP_OBSENSOR_INTRINSIC_CY=26004,
CAP_PROP_OBSENSOR_RGB_POS_MSEC=26005, CAP_PROP_OBSENSOR_RGB_POS_MSEC=26005,
CAP_PROP_OBSENSOR_DEPTH_POS_MSEC=26006, CAP_PROP_OBSENSOR_DEPTH_POS_MSEC=26006,
CAP_PROP_OBSENSOR_DEPTH_WIDTH=26007,
CAP_PROP_OBSENSOR_DEPTH_HEIGHT=26008,
CAP_PROP_OBSENSOR_DEPTH_FPS=26009
}; };
//! @} OBSENSOR //! @} OBSENSOR

View File

@ -400,7 +400,7 @@ Ptr<IVideoWriter> createAndroidVideoWriter(const std::string& filename, int four
double fps, const Size& frameSize, double fps, const Size& frameSize,
const VideoWriterParameters& params); const VideoWriterParameters& params);
Ptr<IVideoCapture> create_obsensor_capture(int index); Ptr<IVideoCapture> create_obsensor_capture(int index, const cv::VideoCaptureParameters& params);
bool VideoCapture_V4L_waitAny( bool VideoCapture_V4L_waitAny(
const std::vector<VideoCapture>& streams, const std::vector<VideoCapture>& streams,

View File

@ -23,15 +23,20 @@
#include "cap_obsensor_capture.hpp" #include "cap_obsensor_capture.hpp"
#include "cap_obsensor/obsensor_stream_channel_interface.hpp" #include "cap_obsensor/obsensor_stream_channel_interface.hpp"
#include <cstdint>
#define OB_WIDTH_ANY 0
#define OB_HEIGHT_ANY 0
#define OB_FPS_ANY 0
#if defined(HAVE_OBSENSOR) && !defined(HAVE_OBSENSOR_ORBBEC_SDK) #if defined(HAVE_OBSENSOR) && !defined(HAVE_OBSENSOR_ORBBEC_SDK)
namespace cv { namespace cv {
Ptr<IVideoCapture> create_obsensor_capture(int index) Ptr<IVideoCapture> create_obsensor_capture(int index, const cv::VideoCaptureParameters& params)
{ {
return makePtr<VideoCapture_obsensor>(index); return makePtr<VideoCapture_obsensor>(index, params);
} }
VideoCapture_obsensor::VideoCapture_obsensor(int index) : isOpened_(false) VideoCapture_obsensor::VideoCapture_obsensor(int index, const cv::VideoCaptureParameters& params) : isOpened_(false)
{ {
static const obsensor::StreamProfile colorProfile = { 640, 480, 30, obsensor::FRAME_FORMAT_MJPG }; static const obsensor::StreamProfile colorProfile = { 640, 480, 30, obsensor::FRAME_FORMAT_MJPG };
static const obsensor::StreamProfile depthProfile = { 640, 480, 30, obsensor::FRAME_FORMAT_Y16 }; static const obsensor::StreamProfile depthProfile = { 640, 480, 30, obsensor::FRAME_FORMAT_Y16 };
@ -55,15 +60,23 @@ VideoCapture_obsensor::VideoCapture_obsensor(int index) : isOpened_(false)
{ {
case obsensor::OBSENSOR_STREAM_COLOR: case obsensor::OBSENSOR_STREAM_COLOR:
{ {
auto profile = colorProfile; uint32_t color_width = params.get<uint32_t>(CAP_PROP_FRAME_WIDTH, OB_WIDTH_ANY);
if(OBSENSOR_FEMTO_MEGA_PID == channel->getPid()){ uint32_t color_height = params.get<uint32_t>(CAP_PROP_FRAME_HEIGHT, OB_HEIGHT_ANY);
profile = megaColorProfile; uint32_t color_fps = params.get<uint32_t>(CAP_PROP_FPS, OB_FPS_ANY);
}else if(OBSENSOR_GEMINI2L_PID == channel->getPid()){
profile = gemini2lColorProfile; obsensor::StreamProfile profile = colorProfile;
}else if(OBSENSOR_ASTRA2_PID == channel->getPid()){ if (color_width != OB_WIDTH_ANY || color_height != OB_HEIGHT_ANY || color_fps != OB_FPS_ANY) {
profile = astra2ColorProfile; profile = { color_width, color_height, color_fps, obsensor::FRAME_FORMAT_MJPG };
}else if(OBSENSOR_GEMINI2XL_PID == channel->getPid()){ } else {
profile = gemini2XlColorProfile; if(OBSENSOR_FEMTO_MEGA_PID == channel->getPid()){
profile = megaColorProfile;
}else if(OBSENSOR_GEMINI2L_PID == channel->getPid()){
profile = gemini2lColorProfile;
}else if(OBSENSOR_ASTRA2_PID == channel->getPid()){
profile = astra2ColorProfile;
}else if(OBSENSOR_GEMINI2XL_PID == channel->getPid()){
profile = gemini2XlColorProfile;
}
} }
channel->start(profile, [&](obsensor::Frame* frame) { channel->start(profile, [&](obsensor::Frame* frame) {
std::unique_lock<std::mutex> lk(frameMutex_); std::unique_lock<std::mutex> lk(frameMutex_);
@ -77,17 +90,25 @@ VideoCapture_obsensor::VideoCapture_obsensor(int index) : isOpened_(false)
uint8_t data = 1; uint8_t data = 1;
channel->setProperty(obsensor::DEPTH_TO_COLOR_ALIGN, &data, 1); channel->setProperty(obsensor::DEPTH_TO_COLOR_ALIGN, &data, 1);
uint32_t depth_width = params.get<uint32_t>(CAP_PROP_OBSENSOR_DEPTH_WIDTH, OB_WIDTH_ANY);
uint32_t depth_height = params.get<uint32_t>(CAP_PROP_OBSENSOR_DEPTH_HEIGHT, OB_HEIGHT_ANY);
uint32_t depth_fps = params.get<uint32_t>(CAP_PROP_OBSENSOR_DEPTH_FPS, OB_FPS_ANY);
obsensor::StreamProfile profile = depthProfile; obsensor::StreamProfile profile = depthProfile;
if(OBSENSOR_GEMINI2_PID == channel->getPid()){ if (depth_width != OB_WIDTH_ANY || depth_height != OB_HEIGHT_ANY || depth_fps != OB_FPS_ANY) {
profile = gemini2DepthProfile; profile = { depth_width, depth_height, depth_fps, obsensor::FRAME_FORMAT_Y16 };
}else if(OBSENSOR_ASTRA2_PID == channel->getPid()){ } else {
profile = astra2DepthProfile; if(OBSENSOR_GEMINI2_PID == channel->getPid()){
}else if(OBSENSOR_FEMTO_MEGA_PID == channel->getPid()){ profile = gemini2DepthProfile;
profile = megaDepthProfile; }else if(OBSENSOR_ASTRA2_PID == channel->getPid()){
}else if(OBSENSOR_GEMINI2L_PID == channel->getPid()){ profile = astra2DepthProfile;
profile = gemini2lDepthProfile; }else if(OBSENSOR_FEMTO_MEGA_PID == channel->getPid()){
}else if(OBSENSOR_GEMINI2XL_PID == channel->getPid()){ profile = megaDepthProfile;
profile = gemini2XlDepthProfile; }else if(OBSENSOR_GEMINI2L_PID == channel->getPid()){
profile = gemini2lDepthProfile;
}else if(OBSENSOR_GEMINI2XL_PID == channel->getPid()){
profile = gemini2XlDepthProfile;
}
} }
channel->start(profile, [&](obsensor::Frame* frame) { channel->start(profile, [&](obsensor::Frame* frame) {
std::unique_lock<std::mutex> lk(frameMutex_); std::unique_lock<std::mutex> lk(frameMutex_);
@ -218,7 +239,22 @@ double VideoCapture_obsensor::getProperty(int propIdx) const {
bool VideoCapture_obsensor::setProperty(int propIdx, double /*propVal*/) bool VideoCapture_obsensor::setProperty(int propIdx, double /*propVal*/)
{ {
CV_LOG_WARNING(NULL, "Unsupported or read only property, id=" << propIdx); switch(propIdx)
{
case CAP_PROP_OBSENSOR_DEPTH_WIDTH:
case CAP_PROP_OBSENSOR_DEPTH_HEIGHT:
case CAP_PROP_OBSENSOR_DEPTH_FPS:
CV_LOG_WARNING(NULL, "CAP_PROP_OBSENSOR_DEPTH_WIDTH, CAP_PROP_OBSENSOR_DEPTH_HEIGHT, CAP_PROP_OBSENSOR_DEPTH_FPS options are supported during camera initialization only");
break;
case CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FPS:
CV_LOG_WARNING(NULL, "CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT, CAP_PROP_FPS options are supported during camera initialization only");
break;
default:
CV_LOG_WARNING(NULL, "Unsupported or read only property, id=" << propIdx);
}
return false; return false;
} }

View File

@ -34,7 +34,7 @@ namespace cv {
class VideoCapture_obsensor : public IVideoCapture class VideoCapture_obsensor : public IVideoCapture
{ {
public: public:
VideoCapture_obsensor(int index); VideoCapture_obsensor(int index, const cv::VideoCaptureParameters& params);
virtual ~VideoCapture_obsensor(); virtual ~VideoCapture_obsensor();
virtual double getProperty(int propIdx) const CV_OVERRIDE; virtual double getProperty(int propIdx) const CV_OVERRIDE;

View File

@ -28,23 +28,52 @@
namespace cv namespace cv
{ {
Ptr<IVideoCapture> create_obsensor_capture(int index) Ptr<IVideoCapture> create_obsensor_capture(int index, const cv::VideoCaptureParameters& params)
{ {
return makePtr<VideoCapture_obsensor>(index); return makePtr<VideoCapture_obsensor>(index, params);
} }
VideoCapture_obsensor::VideoCapture_obsensor(int) VideoCapture_obsensor::VideoCapture_obsensor(int, const cv::VideoCaptureParameters& params)
{ {
ob::Context::setLoggerToFile(OB_LOG_SEVERITY_OFF, ""); ob::Context::setLoggerToFile(OB_LOG_SEVERITY_OFF, "");
config = std::make_shared<ob::Config>(); config = std::make_shared<ob::Config>();
pipe = std::make_shared<ob::Pipeline>(); pipe = std::make_shared<ob::Pipeline>();
int color_width = params.get<double>(CAP_PROP_FRAME_WIDTH, OB_WIDTH_ANY);
int color_height = params.get<double>(CAP_PROP_FRAME_HEIGHT, OB_HEIGHT_ANY);
int color_fps = params.get<double>(CAP_PROP_FPS, OB_FPS_ANY);
auto colorProfiles = pipe->getStreamProfileList(OB_SENSOR_COLOR); auto colorProfiles = pipe->getStreamProfileList(OB_SENSOR_COLOR);
auto colorProfile = colorProfiles->getProfile(OB_PROFILE_DEFAULT); if (color_width == OB_WIDTH_ANY && color_height == OB_HEIGHT_ANY && color_fps == OB_FPS_ANY)
config->enableStream(colorProfile->as<ob::VideoStreamProfile>()); {
CV_LOG_INFO(NULL, "Use default color stream profile");
auto colorProfile = colorProfiles->getProfile(OB_PROFILE_DEFAULT);
config->enableStream(colorProfile->as<ob::VideoStreamProfile>());
}
else
{
CV_LOG_INFO(NULL, "Looking for custom color profile " << color_width << "x" << color_height << "@" << color_fps << " fps");
auto colorProfile = colorProfiles->getVideoStreamProfile(color_width, color_height, OB_FORMAT_MJPG, color_fps);
config->enableStream(colorProfile->as<ob::VideoStreamProfile>());
}
int depth_width = params.get<double>(CAP_PROP_OBSENSOR_DEPTH_WIDTH, OB_WIDTH_ANY);
int depth_height = params.get<double>(CAP_PROP_OBSENSOR_DEPTH_HEIGHT, OB_HEIGHT_ANY);
int depth_fps = params.get<double>(CAP_PROP_OBSENSOR_DEPTH_FPS, OB_FPS_ANY);
auto depthProfiles = pipe->getStreamProfileList(OB_SENSOR_DEPTH); auto depthProfiles = pipe->getStreamProfileList(OB_SENSOR_DEPTH);
auto depthProfile = depthProfiles->getProfile(OB_PROFILE_DEFAULT); if (depth_width == OB_WIDTH_ANY && depth_height == OB_HEIGHT_ANY && depth_fps == OB_FPS_ANY)
config->enableStream(depthProfile->as<ob::VideoStreamProfile>()); {
CV_LOG_INFO(NULL, "Use default depth stream profile");
auto depthProfile = depthProfiles->getProfile(OB_PROFILE_DEFAULT);
config->enableStream(depthProfile->as<ob::VideoStreamProfile>());
}
else
{
CV_LOG_INFO(NULL, "Looking for custom color profile " << depth_width << "x" << depth_height << "@" << depth_fps << " fps");
auto depthProfile = depthProfiles->getVideoStreamProfile(depth_width, depth_height, OB_FORMAT_Y14, depth_fps);
config->enableStream(depthProfile->as<ob::VideoStreamProfile>());
}
config->setAlignMode(ALIGN_D2C_SW_MODE); config->setAlignMode(ALIGN_D2C_SW_MODE);
@ -111,8 +140,22 @@ double VideoCapture_obsensor::getProperty(int propIdx) const
return rst; return rst;
} }
bool VideoCapture_obsensor::setProperty(int, double) bool VideoCapture_obsensor::setProperty(int prop, double)
{ {
switch(prop)
{
case CAP_PROP_OBSENSOR_DEPTH_WIDTH:
case CAP_PROP_OBSENSOR_DEPTH_HEIGHT:
case CAP_PROP_OBSENSOR_DEPTH_FPS:
CV_LOG_WARNING(NULL, "CAP_PROP_OBSENSOR_DEPTH_WIDTH, CAP_PROP_OBSENSOR_DEPTH_HEIGHT, CAP_PROP_OBSENSOR_DEPTH_FPS options are supported during camera initialization only");
break;
case CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FPS:
CV_LOG_WARNING(NULL, "CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT, CAP_PROP_FPS options are supported during camera initialization only");
break;
}
return false; return false;
} }

View File

@ -46,7 +46,7 @@ struct CameraParam
class VideoCapture_obsensor : public IVideoCapture class VideoCapture_obsensor : public IVideoCapture
{ {
public: public:
VideoCapture_obsensor(int index); VideoCapture_obsensor(int index, const cv::VideoCaptureParameters& params);
virtual ~VideoCapture_obsensor(); virtual ~VideoCapture_obsensor();
virtual double getProperty(int propIdx) const CV_OVERRIDE; virtual double getProperty(int propIdx) const CV_OVERRIDE;

View File

@ -8,10 +8,68 @@
#include <iostream> #include <iostream>
using namespace cv; using namespace cv;
int main() int main(int argc, char** argv)
{ {
VideoCapture obsensorCapture(0, CAP_OBSENSOR); cv::CommandLineParser parser(argc, argv,
if(!obsensorCapture.isOpened()){ "{help h ? | | help message}"
"{dw | | depth width }"
"{dh | | depth height }"
"{df | | depth fps }"
"{cw | | color width }"
"{ch | | color height }"
"{cf | | depth fps }"
);
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
std::vector<int> params;
if (parser.has("dw"))
{
params.push_back(CAP_PROP_OBSENSOR_DEPTH_WIDTH);
params.push_back(parser.get<int>("dw"));
}
if (parser.has("dh"))
{
params.push_back(CAP_PROP_OBSENSOR_DEPTH_HEIGHT);
params.push_back(parser.get<int>("dh"));
}
if (parser.has("df"))
{
params.push_back(CAP_PROP_OBSENSOR_DEPTH_FPS);
params.push_back(parser.get<int>("df"));
}
if (parser.has("cw"))
{
params.push_back(CAP_PROP_FRAME_WIDTH);
params.push_back(parser.get<int>("cw"));
}
if (parser.has("ch"))
{
params.push_back(CAP_PROP_FRAME_HEIGHT);
params.push_back(parser.get<int>("ch"));
}
if (parser.has("cf"))
{
params.push_back(CAP_PROP_FPS);
params.push_back(parser.get<int>("cf"));
}
VideoCapture obsensorCapture;
if (params.empty())
obsensorCapture.open(0, CAP_OBSENSOR);
else
obsensorCapture.open(0, CAP_OBSENSOR, params);
if(!obsensorCapture.isOpened()) {
std::cerr << "Failed to open obsensor capture! Index out of range or no response from device"; std::cerr << "Failed to open obsensor capture! Index out of range or no response from device";
return -1; return -1;
} }