- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我使用 cv::StereoBM 已经有一段时间了,我正在尝试切换到 cuda::StereoBM(使用 GPU),但遇到了一个问题,即使使用相同的设置和输入图像,它们看起来也完全不同.我读过 this发布 cuda 的输入需要以不同于 cv::StereoBM 的方式进行纠正。具体来说,视差必须在 [0,256] 范围内。我花了一段时间寻找其他有关如何为 cuda 纠正图像的示例,但没有结果。带有 cv::StereoBM 的输出看起来不错,因此我的图像已为此进行了适当的校正。有没有办法将一种整流类型转换为另一种?
如果有人有兴趣,这里是我用来校正立体声的代码(注意:在我通过这个程序运行它们之前,我正在校正每个图像以摆脱和“镜头效果”):
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
int numBoards = 20;
int board_w = 9;
int board_h = 14;
Size board_sz = Size(board_w, board_h);
int board_n = board_w*board_h;
vector<vector<Point3f> > object_points;
vector<vector<Point2f> > imagePoints1, imagePoints2;
vector<Point2f> corners1, corners2;
vector<Point3f> obj;
for (int j=0; j<board_n; j++)
{
obj.push_back(Point3f(j/board_w, j%board_w, 0.0f));
}
Mat img1, img2, gray1, gray2, image1, image2;
const char* right_cam_gst = "nvcamerasrc sensor-id=0 ! video/x-raw(memory:NVMM), format=UYVY, width=1280, height=720, framerate=30/1 ! nvvidconv flip-method=2 ! video/x-raw, format=GRAY8, width=1280, height=720 ! appsink";
const char* Left_cam_gst = "nvcamerasrc sensor-id=1 ! video/x-raw(memory:NVMM), format=UYVY, width=1280, height=720, framerate=30/1 ! nvvidconv flip-method=2 ! video/x-raw, format=GRAY8, width=1280, height=720 ! appsink";
VideoCapture cap1 = VideoCapture(right_cam_gst);
VideoCapture cap2 = VideoCapture(Left_cam_gst);
int success = 0, k = 0;
bool found1 = false, found2 = false;
Mat distCoeffs0;
Mat intrinsic0;
cv::FileStorage storage0("CamData0.yml", cv::FileStorage::READ);
storage0["distCoeffs"] >> distCoeffs0;
storage0["intrinsic"] >> intrinsic0;
storage0.release();
Mat distCoeffs1;
Mat intrinsic1;
cv::FileStorage storage1("CamData1.yml", cv::FileStorage::READ);
storage1["distCoeffs"] >> distCoeffs1;
storage1["intrinsic"] >> intrinsic1;
storage1.release();
while (success < numBoards)
{
cap1 >> image1;
cap2 >> image2;
//resize(img1, img1, Size(320, 280));
//resize(img2, img2, Size(320, 280));
undistort(image1, img1, intrinsic0, distCoeffs0);
undistort(image2, img2, intrinsic1, distCoeffs1);
// cvtColor(img1, gray1, CV_BGR2GRAY);
// cvtColor(img2, gray2, CV_BGR2GRAY);
found1 = findChessboardCorners(img1, board_sz, corners1, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
found2 = findChessboardCorners(img2, board_sz, corners2, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
if (found1)
{
cornerSubPix(img1, corners1, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img1, board_sz, corners1, found1);
}
if (found2)
{
cornerSubPix(img2, corners2, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img2, board_sz, corners2, found2);
}
imshow("image1", img1);
imshow("image2", img2);
k = waitKey(10);
// if (found1 && found2)
// {
// k = waitKey(0);
// }
if (k == 27)
{
break;
}
if (k == ' ' && found1 !=0 && found2 != 0)
{
imagePoints1.push_back(corners1);
imagePoints2.push_back(corners2);
object_points.push_back(obj);
printf ("Corners stored\n");
success++;
if (success >= numBoards)
{
break;
}
}
}
destroyAllWindows();
printf("Starting Calibration\n");
Mat CM1 = Mat(3, 3, CV_64FC1);
Mat CM2 = Mat(3, 3, CV_64FC1);
Mat D1, D2;
Mat R, T, E, F;
stereoCalibrate(object_points, imagePoints1, imagePoints2,
CM1, D1, CM2, D2, img1.size(), R, T, E, F,
CV_CALIB_SAME_FOCAL_LENGTH | CV_CALIB_ZERO_TANGENT_DIST,
cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5));
FileStorage fs1("mystereocalib.yml", FileStorage::WRITE);
fs1 << "CM1" << CM1;
fs1 << "CM2" << CM2;
fs1 << "D1" << D1;
fs1 << "D2" << D2;
fs1 << "R" << R;
fs1 << "T" << T;
fs1 << "E" << E;
fs1 << "F" << F;
printf("Done Calibration\n");
printf("Starting Rectification\n");
Mat R1, R2, P1, P2, Q;
stereoRectify(CM1, D1, CM2, D2, img1.size(), R, T, R1, R2, P1, P2, Q);
fs1 << "R1" << R1;
fs1 << "R2" << R2;
fs1 << "P1" << P1;
fs1 << "P2" << P2;
fs1 << "Q" << Q;
fs1.release();
printf("Done Rectification\n");
printf("Applying Undistort\n");
Mat map1x, map1y, map2x, map2y;
Mat imgU1, imgU2, disp, disp8 , o1, o2;
initUndistortRectifyMap(CM1, Mat(), R1, P1, img1.size(), CV_32FC1, map1x, map1y);
initUndistortRectifyMap(CM2, Mat(), R2, P2, img2.size(), CV_32FC1, map2x, map2y);
printf("Undistort complete\n");
while(1)
{
cap1 >> image1;
cap2 >> image2;
undistort(image1, img1, intrinsic0, distCoeffs0);
undistort(image2, img2, intrinsic1, distCoeffs1);
remap(img1, imgU1, map1x, map1y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
remap(img2, imgU2, map2x, map2y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
imshow("image1", imgU1);
imshow("image2", imgU2);
k = waitKey(5);
if(k==27)
{
break;
}
}
cap1.release();
cap2.release();
return(0);
}
显示不同方法输出的图像:
最佳答案
搞定了!看起来 CPU 和 GPU 之间的最大区别在于输入图像的归一化。整改可以保持不变。我从 opencv 中找到了一些示例代码,并将其简化为基本步骤,以查看所有步骤。令人惊讶的是,在视差计算之前或之后都没有进行归一化。这是 GPU 的工作代码:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <stdexcept>
#include <opencv2/core/utility.hpp>
#include "opencv2/cudastereo.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
bool running;
Mat left_src, right_src;
Mat left, right;
cuda::GpuMat d_left, d_right;
int ndisp = 88;
Ptr<cuda::StereoBM> bm;
bm = cuda::createStereoBM(ndisp);
// Load images
left_src = imread("s1.png");
right_src = imread("s2.png");
cvtColor(left_src, left, COLOR_BGR2GRAY);
cvtColor(right_src, right, COLOR_BGR2GRAY);
d_left.upload(left);
d_right.upload(right);
imshow("left", left);
imshow("right", right);
// Prepare disparity map of specified type
Mat disp(left.size(), CV_8U);
cuda::GpuMat d_disp(left.size(), CV_8U);
cout << endl;
running = true;
while (running)
{
bm->compute(d_left, d_right, d_disp);
// Show results
d_disp.download(disp);
imshow("disparity", (Mat_<uchar>)disp);
waitKey(1);
}
return 0;
}
关于c++ - 正确校正 GPU 的立体图像(opencv),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47337346/
我正在尝试从我的系统中完全删除 opencv。我试图学习 ROS,而在教程中我遇到了一个问题。创建空工作区后,我调用catkin_make 它给出了一个常见错误,我在 answers.ros 中搜索并
我在尝试逐步转移对warpAffine的调用时遇到崩溃(不是异常): void rotateImage( const Mat& source, double degree, Mat& output )
如何处理opencv gpu异常?是否有用于opencvgpu异常处理的特定错误代码集api? 我尝试了很多搜索,但只有1个错误代码,即CV_GpuNotSupported。 请帮帮我。 最佳答案 虽
笔记 我是 OpenCV(或计算机视觉)的新手,所以告诉我搜索查询会很有帮助! 我想问什么 我想编写一个从图片中提取名片的程序。 我能够提取粗略的轮廓,但反射光会变成噪点,我无法提取准确的轮廓。请告诉
我想根据像素的某个阈值将Mono16类型的Mat转换为二进制图像。我尝试使用以下内容: 阈值(img,ret,0.1,1,CV_THRESH_BINARY); 尝试编译时,出现make错误,提示: 错
我对使用GPU加速的OpenCV中的卷积函数有疑问。 使用GPU的卷积速度大约快3.5 运行时: convolve(src_32F, kernel, cresult, false, cbuffer);
我正在尝试使用非对称圆圈网格执行相机校准。 我通常找不到适合CirclesGridFinder的文档,尤其是findHoles()函数的文档。 如果您有关于此功能如何工作以及其参数含义的信息,将不胜感
在计算机上绘图和在 OpenCV 的投影仪上投影之间有什么区别吗? 一种选择是投影显示所有内容的计算机屏幕。但也许也有这样的选择,即在投影仪上精确地绘制和投影图像,仅使用计算机作为计算机器。如果我能做
我将Processing(processing.org)用于需要人脸跟踪的项目。现在的问题是由于for循环,程序将耗尽内存。我想停止循环或至少解决内存不足的问题。这是代码。 import hyperm
我有下面的代码: // Image Processing.cpp : Defines the entry point for the console application. // //Save
我正在为某些项目使用opencv。并有应解决的任务。 任务很简单。我有一张主图片,并且有一个模板,而不是将主图片与模板进行比较。我使用matchTemplate()函数。我只是好奇一下。 在文档中,我
我正在尝试使用以下命令创建级联分类器: haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20 -n
我试图使用OpenCV检测黑色图像中一组形状的颜色,为此我使用了Canny检测。但是,颜色输出总是返回为黑色。 std::vector > Asteroids::DetectPoints(const
我正在尝试使用OpenCv 2.4.5从边缘查找渐变方向,但是我在使用cvSobel()时遇到问题,以下是错误消息和我的代码。我在某处读到它可能是由于浮点(??)之间的转换,但我不知道如何解决它。有帮
我正在尝试构建循环关闭算法,但是在开始开发之前,我想测试哪种功能描述符在真实数据集上效果更好。 我有两个在两个方向拍摄的走廊图像,一个进入房间,另一个离开同一个房间。因此它们代表相同的场景,但具有2个
有没有一种方法可以比较直方图,但例如要排除白色,因此白色不会影响比较。 最佳答案 白色像素有 饱和度 , S = 0 .因此,在创建直方图时很容易从计数中删除白色像素。请执行下列操作: 从 BGR 转
就像本主题的标题一样,如何在OpenCV中确定图像的特定像素(灰度或彩色)是否饱和(例如,亮度过高)? 先感谢您。 最佳答案 根据定义,饱和像素是指与强度(即灰度值或颜色分量之一)等于255相关联的像
我是OpenCV的新用户,正在从事大学项目。程序会获取输入图像,对其进行综合模糊处理,然后对其进行模糊处理。当对合成模糊图像进行反卷积时,会生成边界伪像,因为...好吧,到目前为止,我还没有实现边界条
我想知道OpenCV是haar特征还是lbp是在多尺度搜索过程中缩放图像还是像论文中提到的那样缩放特征本身? 编辑:事实证明,检测器可以缩放图像,而不是功能。有人知道为什么吗?通过缩放功能可以更快。
我在openCv中使用SVM.train命令(已定义了适当的参数)。接下来,我要使用我的算法进行分类,而不是使用svm.predict。 可能吗?我可以访问训练时生成的支持 vector 吗?如果是这
我是一名优秀的程序员,十分优秀!