问题描述
我正在尝试执行 cv::cuda::StereoBM 匹配,以使用 OpenCV 从几个立体帧中获取视差图。
然而它只适用于一些特定的参数,而它与其他常见的锥体一样。
我还注意到工作参数随图像分辨率而变化。 例如,在默认分辨率为 640x480 的情况下,少数几个确实有效的参数之一是 (numdisparities = 64,blockSize = 33)。
我不知道为什么其他参数让它失败。
这是我要重现的代码(请注意,我使用了 2 个 CSI 摄像头,所以我需要那个 gstreamer 管道)。
#include <iostream>
#include <opencv2/cudastereo.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
std::string gstreamer_pipeline (int capture_width,int capture_height,int display_width,int display_height,int framerate,int flip_method,int device)
{
return "nvarguscamerasrc sensor-id=" + std::to_string(device) +" ! video/x-raw(memory:NVMM),width=(int)" + std::to_string(capture_width) + ",height=(int)" +
std::to_string(capture_height) + ",format=(string)NV12,framerate=(fraction)" + std::to_string(framerate) +
"/1 ! nvvidconv flip-method=" + std::to_string(flip_method) + " ! video/x-raw,width=(int)" + std::to_string(display_width) + ",height=(int)" +
std::to_string(display_height) + ",format=(string)BGRx ! videoconvert ! video/x-raw,format=(string)BGR ! appsink max-buffers=1 drop=true";
}
int main(int argc,char const *argv[])
{
/*Stereo matching parameters from command line*/
int numdisparities = atoi(argv[1]);
int blockSize = atoi(argv[2]);
/*cpu Mat*/
Mat frameL,frameR;
Mat rectL,rectR;
Mat disp;
/*GPU Mat*/
cuda::GpuMat CUDArectL;
cuda::GpuMat CUDArectR;
cuda::GpuMat CUDAdisp;
/*OpenCV windows*/
String windowNamedisp = "disp";
/*Load calibration parameters*/
string calib_file = "cpp/stereo_calib_csi";
FileStorage fs(calib_file,FileStorage::READ);
Mat K1,K2;
Mat D1,D2;
Mat P1,P2;
Mat R1,R2;
Mat Q;
fs["K1"] >> K1;
fs["K2"] >> K2;
fs["D1"] >> D1;
fs["D2"] >> D2;
fs["P1"] >> P1;
fs["P2"] >> P2;
fs["R1"] >> R1;
fs["R2"] >> R2;
fs["Q"] >> Q;
fs.release();
/*Rectification parameters*/
Mat mapx_L,mapy_L;
Mat mapx_R,mapy_R;
Size size(640,480);
initUndistortRectifyMap(K1,D1,R1,P1,size,CV_32FC1,mapx_L,mapy_L);
initUndistortRectifyMap(K2,D2,R2,P2,mapx_R,mapy_R);
/*CSI camera settings with gstreamer*/
int capture_width = 640 ;
int capture_height = 480 ;
int display_width = 640 ;
int display_height = 480 ;
int framerate = 60 ;
int flip_method = 0 ;
string left_pipeline = gstreamer_pipeline(capture_width,capture_height,display_width,display_height,framerate,flip_method,0);
string right_pipeline = gstreamer_pipeline(capture_width,1);
cout << "Using left pipeline: \n\t" << left_pipeline << endl;
VideoCapture left(left_pipeline,cv::CAP_GSTREAMER);
cout << "Using left pipeline: \n\t" << left_pipeline << endl;
VideoCapture right(right_pipeline,cv::CAP_GSTREAMER);
if(left.isOpened() == false)
{
cout << "Left cam not working" << endl;
cin.get();
return -1;
}
if(right.isOpened() == false)
{
cout << "Right cam not working" << endl;
cin.get();
return -1;
}
/*CUDA StereoBM setting*/
Ptr<cuda::StereoBM> BM = cuda::createStereoBM();
BM->setNumdisparities(numdisparities);
BM->setBlockSize(blockSize);
/*MAIN LOOP*/
while(1)
{
/*ACQUIRE AND RECTIFY FRAMES*/
bool bSuccessL = left.read(frameL);
bool bSuccessR = right.read(frameR);
undistort(frameL,rectL,K1,K1);
undistort(frameR,rectR,K2,K2);
remap(frameL,mapy_L,CV_INTER_AREA);
remap(frameR,mapy_R,CV_INTER_AREA);
cvtColor(rectL,COLOR_BGR2GRAY);
cvtColor(rectR,COLOR_BGR2GRAY);
CUDArectL.upload(rectL);
CUDArectR.upload(rectR);
/*HERE IS THE ISSUE*/
cout << "Computing..."<< endl;
BM->compute(CUDArectL,CUDArectR,CUDAdisp);
cout << "Computed!" << endl;
CUDAdisp.download(disp);
disp.convertTo(disp,CV_8U,numdisparities/16.);
imshow(windowNamedisp,disp);
int k = waitKey(1);
if (k == 113) break;
}
return 0;
}
使用 g++ cudatest.cpp -o cudatest $(pkg-config --cflags --libs opencv)
编译并使用 ./cudatest numdisparities blockSize
启动
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)