精华内容
下载资源
问答
  • 二、双目测距步骤1.双目标定2.测距测试结果 前言 最近有项目需要用到摄像测距,于是开始接触opencv机器视觉。学了好几天的摄像机测距相关的知识后就开始动手验证,刚开始是单目测距,搞了个树莓派的开发板,然后...
    
    
    


    前言

    最近有项目需要用到摄像测距,于是开始接触opencv机器视觉。学了好几天的摄像机测距相关的知识后就开始动手验证,刚开始是单目测距,搞了个树莓派的开发板,然后下载网上的一些代码验证,发现单目需要预先知道被测物,因为要实现避障功能,所以后面选了双目测距。目前的进度是能在PC上利用双目进行测距,近距离双目测距精度还行,后续需要将代码移植至树莓派B4板子上,由树莓派来进一步论证项目可行性


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、什么是拍照测距?

    个人了解到拍照测距有两种方式,单目测距和双目测距,单目是只用一个摄像头,测距前提是需要知道被测物体是什么。双目测距需要一个双目的摄像头。

    二、双目测距步骤

    1.双目标定

    原来的双目标定是直接使用的opencv自带的标定功能,但是发现对图片的要求比较高,而且标定的结果在后面的测距上并不准(可能是我标定时候不准确导致的),后面就使用的MATLAB进行标定。

    我是在淘宝上买了个双目摄像头,自己A4纸打印的棋盘格。用厂家提供的图像采集方式进行了拍照。取了15张照片(左目和右目各15张),后用matlab标定时候有几张图片的误差有点大就给删了,最后取了12张照片进行标定。标定过程就不说了,可以通过以下链接进行了解
    https://blog.csdn.net/u013451663/article/details/89954646

    重点说一下用matlab得出来的参数的对应关系:
    在这里插入图片描述

    在这里插入图片描述
    先看一下畸变参数,得到的值就是K1,K2,K3,和P1,P2,代码赋值的时候应该是K1,K2,P1,P2,K3

    Mat distCoeffL = (Mat_<double>(5, 1) << 0.310458259610102, -2.26297309194147, -0.00764246381079933, 0.00634878271949189, 6.11556840747635);
    

    具体说一下内参,内参是一个3x3的矩阵,双击matlab里面的值,得到的表格是这样的
    在这里插入图片描述
    这个表格里面和代码需要的数据要置换一下

    fx 0 cx
    0 fy cy
    0  0  1
    

    在这里插入图片描述
    代码赋值如下:

    Mat cameraMatrixL = (Mat_<double>(3, 3) << 337.709436280709, 0.741962718557881, 150.799143051710,
    	0, 337.863855604370, 123.314225146904,
    	0, 0, 1);
    

    旋转矩阵也是3x3,所以也和内参一样,置换一下。
    平移矩阵是可以直接使用的
    在这里插入图片描述
    附上赋值代码如下

    Mat rec = (Mat_<double>(3, 3) << 0.999989526750612, 0.00232022184998904, 0.00394499171785794,
    	-0.00228582974058393, 0.999959540028791, -0.00870018895234802,
    	-0.00396501847211287, 0.00869108025370437, 0.999954370835259); 
    	  
    Mat T = (Mat_<double>(3, 1) << -41.5775139873461, 0.241065317743041, 0.408815384344912);
    

    至此,标定就结束了。

    2.测距

    测距是使用的该大神的代码,我把它拷贝过来了。
    https://guo-pu.blog.csdn.net/article/details/86744936?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai

    #include <opencv2/opencv.hpp>  
    #include <iostream>  
    #include <math.h> 
    
    using namespace std;
    using namespace cv;
    
    const int imageWidth = 320;                             //图片大小  
    const int imageHeight = 240;
    Vec3f  point3;
    float d;
    Size imageSize = Size(imageWidth, imageHeight);
    
    Mat rgbImageL, grayImageL;
    Mat rgbImageR, grayImageR;
    Mat rectifyImageL, rectifyImageR;
    
    Rect validROIL;//图像校正之后,会对图像进行裁剪,这里的validROI就是指裁剪之后的区域  
    Rect validROIR;
    
    Mat mapLx, mapLy, mapRx, mapRy;     //映射表  
    Mat Rl, Rr, Pl, Pr, Q;              //校正旋转矩阵R,投影矩阵P 重投影矩阵Q
    Mat xyz;              //三维坐标
    
    Point origin;         //鼠标按下的起始点
    Rect selection;      //定义矩形选框
    bool selectObject = false;    //是否选择对象
    
    int blockSize = 0, uniquenessRatio = 0, numDisparities = 0;
    Ptr<StereoBM> bm = StereoBM::create(16, 9);
    
    Mat cameraMatrixL = (Mat_<double>(3, 3) << 337.709436280709, 0.741962718557881, 150.799143051710,
    	0, 337.863855604370, 123.314225146904,
    	0, 0, 1);
    
    Mat distCoeffL = (Mat_<double>(5, 1) << 0.310458259610102, -2.26297309194147, -0.00764246381079933, 0.00634878271949189, 6.11556840747635);
    
    Mat cameraMatrixR = (Mat_<double>(3, 3) << 337.093687218177, 0.587984682766586, 152.848985873868,
    	0, 336.971855005274, 117.527331021388,
    	0, 0, 1);
    
    Mat distCoeffR = (Mat_<double>(5, 1) << 0.439757633387106, -5.17644381384173, -0.0103643563681475, 0.00184932125612765, 23.4806041578594);
    
    Mat T = (Mat_<double>(3, 1) << -41.5775139873461, 0.241065317743041, 0.408815384344912);//T平移向量
    
    Mat rec = (Mat_<double>(3, 3) << 0.999989526750612, 0.00232022184998904, 0.00394499171785794,
    	-0.00228582974058393, 0.999959540028791, -0.00870018895234802,
    	-0.00396501847211287, 0.00869108025370437, 0.999954370835259);                //rec旋转向量
    
    Mat R;//R 旋转矩阵
    
    /*****立体匹配*****/
    void stereo_match(int, void*)
    {
    	bm->setBlockSize(2 * blockSize + 5);     //SAD窗口大小,5~21之间为宜
    	bm->setROI1(validROIL);
    	bm->setROI2(validROIR);
    	bm->setPreFilterCap(31);
    	bm->setMinDisparity(0);  //最小视差,默认值为0, 可以是负值,int型
    	bm->setNumDisparities(numDisparities * 16 + 16);//视差窗口,即最大视差值与最小视差值之差,窗口大小必须是16的整数倍,int型
    	bm->setTextureThreshold(10);
    	bm->setUniquenessRatio(uniquenessRatio);//uniquenessRatio主要可以防止误匹配
    	bm->setSpeckleWindowSize(100);
    	bm->setSpeckleRange(32);
    	bm->setDisp12MaxDiff(-1);
    	Mat disp, disp8;
    	bm->compute(rectifyImageL, rectifyImageR, disp);//输入图像必须为灰度图
    	disp.convertTo(disp8, CV_8U, 255 / ((numDisparities * 16 + 16) * 16.));//计算出的视差是CV_16S格式
    	reprojectImageTo3D(disp, xyz, Q, true); //在实际求距离时,ReprojectTo3D出来的X / W, Y / W, Z / W都要乘以16(也就是W除以16),才能得到正确的三维坐标信息。
    	xyz = xyz * 16;
    	imshow("disparity", disp8);
    }
    
    /*****描述:鼠标操作回调*****/
    static void onMouse(int event, int x, int y, int, void*)
    {
    	if (selectObject)
    	{
    		selection.x = MIN(x, origin.x);
    		selection.y = MIN(y, origin.y);
    		selection.width = std::abs(x - origin.x);
    		selection.height = std::abs(y - origin.y);
    	}
    
    	switch (event)
    	{
    	case EVENT_LBUTTONDOWN:   //鼠标左按钮按下的事件
    		origin = Point(x, y);
    		selection = Rect(x, y, 0, 0);
    		selectObject = true;
    		//cout << origin << "in world coordinate is: " << xyz.at<Vec3f>(origin) << endl;
    		point3 = xyz.at<Vec3f>(origin);
    		point3[0];
    		cout << "世界坐标:" << endl;
    		cout << "x: " << point3[0] << "  y: " << point3[1] << "  z: " << point3[2] << endl;
    		d = point3[0] * point3[0] + point3[1] * point3[1] + point3[2] * point3[2];
    		d = sqrt(d);   //mm
    		d = d / 10.0;   //cm
    		cout << "距离是:" << d << "cm" << endl;
    		break;
    	case EVENT_LBUTTONUP:    //鼠标左按钮释放的事件
    		selectObject = false;
    		if (selection.width > 0 && selection.height > 0)
    			break;
    	}
    }
    
    
    /*****主函数*****/
    int main()
    {
    	/*
    	立体校正
    	*/
    	Rodrigues(rec, R); //Rodrigues变换
    	stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY,
    		0, imageSize, &validROIL, &validROIR);
    	initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);
    	initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);
    
    	/*
    	读取图片
    	*/
    	rgbImageL = imread("C:\\Users\\DELL\\picture\\left_33.png", CV_LOAD_IMAGE_COLOR);
    	cvtColor(rgbImageL, grayImageL, CV_BGR2GRAY);
    	rgbImageR = imread("C:\\Users\\DELL\\picture\\right_33.png", CV_LOAD_IMAGE_COLOR);
    	cvtColor(rgbImageR, grayImageR, CV_BGR2GRAY);
    
    	imshow("ImageL Before Rectify", grayImageL);
    	imshow("ImageR Before Rectify", grayImageR);
    
    	/*
    	经过remap之后,左右相机的图像已经共面并且行对准了
    	*/
    	remap(grayImageL, rectifyImageL, mapLx, mapLy, INTER_LINEAR);
    	remap(grayImageR, rectifyImageR, mapRx, mapRy, INTER_LINEAR);
    
    	/*
    	把校正结果显示出来
    	*/
    	Mat rgbRectifyImageL, rgbRectifyImageR;
    	cvtColor(rectifyImageL, rgbRectifyImageL, CV_GRAY2BGR);  //伪彩色图
    	cvtColor(rectifyImageR, rgbRectifyImageR, CV_GRAY2BGR);
    
    	//单独显示
    	imshow("ImageL After Rectify", rgbRectifyImageL);
    	imshow("ImageR After Rectify", rgbRectifyImageR);
    
    	//显示在同一张图上
    	Mat canvas;
    	double sf;
    	int w, h;
    	sf = 600. / MAX(imageSize.width, imageSize.height);
    	w = cvRound(imageSize.width * sf);
    	h = cvRound(imageSize.height * sf);
    	canvas.create(h, w * 2, CV_8UC3);   //注意通道
    
    										//左图像画到画布上
    	Mat canvasPart = canvas(Rect(w * 0, 0, w, h));                                //得到画布的一部分  
    	resize(rgbRectifyImageL, canvasPart, canvasPart.size(), 0, 0, INTER_AREA);     //把图像缩放到跟canvasPart一样大小  
    	Rect vroiL(cvRound(validROIL.x * sf), cvRound(validROIL.y * sf),                //获得被截取的区域    
    		cvRound(validROIL.width * sf), cvRound(validROIL.height * sf));
    	cout << "Painted ImageL" << endl;
    
    	//右图像画到画布上
    	canvasPart = canvas(Rect(w, 0, w, h));                                      //获得画布的另一部分  
    	resize(rgbRectifyImageR, canvasPart, canvasPart.size(), 0, 0, INTER_LINEAR);
    	Rect vroiR(cvRound(validROIR.x * sf), cvRound(validROIR.y * sf),
    		cvRound(validROIR.width * sf), cvRound(validROIR.height * sf));
    	cout << "Painted ImageR" << endl;
    
    	//画上对应的线条
    	for (int i = 0; i < canvas.rows; i += 16)
    		line(canvas, Point(0, i), Point(canvas.cols, i), Scalar(0, 255, 0), 1, 8);
    	imshow("rectified", canvas);
    
    	/*
    	立体匹配
    	*/
    	namedWindow("disparity", CV_WINDOW_AUTOSIZE);
    	// 创建SAD窗口 Trackbar
    	createTrackbar("BlockSize:\n", "disparity", &blockSize, 8, stereo_match);
    	// 创建视差唯一性百分比窗口 Trackbar
    	createTrackbar("UniquenessRatio:\n", "disparity", &uniquenessRatio, 50, stereo_match);
    	// 创建视差窗口 Trackbar
    	createTrackbar("NumDisparities:\n", "disparity", &numDisparities, 16, stereo_match);
    	//鼠标响应函数setMouseCallback(窗口名称, 鼠标回调函数, 传给回调函数的参数,一般取0)
    	setMouseCallback("disparity", onMouse, 0);
    	stereo_match(0, 0);
    
    	waitKey(0);
    	return 0;
    }
    

    测试结果

    测出来的结果还可以,精度挺高,最后附上测试的结果图。先记录这么多,后续还要移植到树莓派。

    在这里插入图片描述

    展开全文
  • opencv双目测距

    2017-04-19 20:23:58
    opencv运用matlab标定数据进行双目测距
  • 近几天由于论文的关系,需要用到双目测距,历经千辛万苦,终于得到想要的效果。我把最近一段时间踩到的坑总结一下,希望对各位有所帮助! 环境: Matlab对双目获拍摄的图片进行标定,opencv使用标定好的参数进行...

    近几天由于论文的关系,需要用到双目测距,历经千辛万苦,终于得到想要的效果。我把最近一段时间踩到的坑总结一下,希望对各位有所帮助!

    环境:

    Matlab对双目获拍摄的图片进行标定,opencv使用标定好的参数进行立体校正及立体匹配

    使用Matlab标定时,会获取各相机的内参、外参、畸变参数以及两个相机间的平移及旋转矩阵

    1.opencv使用这些参数时,内参矩阵IntrinsicMatrix旋转矩阵RotationOfCamera2需要转置后再使用。这点非常重要,否则你立体校正的结果都是错的,何况立体匹配。

    2.在更改相机分辨率进行测距时,需要使用相应分辨率的图片进行重新标定,否则得到的距离结果是错误的。

    3.标定时选择各参数的意义

    相机的畸变参数有径向畸变K1,K2,K3,切向畸变P1,P2

    • 选择2Coefficients选项代表默认将K3视为0(K3通常在鱼眼镜头中使用,普通镜头一般不考虑),那么标定得到的径向畸变只有K1和K2两个值。如果选择3Coefficients则标定后也会得到K3值。

    • Skew值和我们得到的内参矩阵有关,如果未选中Skew,得到的内参就是下面式1,选中得到的内参便是式2,两者的区别就是有没有考虑到Skew偏斜系数

    式1

    式2

    • Tangential Distortion就是问你考不考虑切向畸变,不选中则切向畸变P1=P2=0;

    • 在Opencv中,畸变系数使用时顺序为K1、K2、P1、P2、K3

    展开全文
  • 双目测距

    热门讨论 2018-11-21 14:04:13
    环境配置。visual Studio2013。Python3.5。OpenCV4.0、numpy1.16。相机标定。MATLAB的Camera Calibration Toolbox工具箱。张正友相机标定算法。左右相机的标定。立体标定。...双目测距。结果演示。

    环境配置


    Visual Studio 2013


    在这里插入图片描述

    Python


    在这里插入图片描述

    相机标定


    双目测距,当然要准备两个摄像头了,可以直接在淘宝上购买,也可以根据自己的需求进行定制。将两个摄像头的相对位置固定好,本模型采用前向平行的双目立体视觉模型。即两相机的光轴相互平行。左右两个成像平面也处于同一水平面上。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    因为摄像头的位置是由我们手动进行定位的,所以需要进行相机标定,即通过目标点在图像坐标系和世界坐标系中的位置来推导相机内外参数矩阵的过程。
    相机标定采用张正友相机标定算法。张正友相机标定算法指的是1998年提出的单平面棋盘格的相机标定算法。这种相机标定算法介于传统标定法和自标定法之间,克服了传统标定法需要的高精度标定物的缺点,仅需使用一个打印出来的棋盘格就可以。我们只需对标定板的不同方向进行拍摄,然后对拍摄所得的图像进行处理。
    本次相机标定使用MATLAB的Camera Calibration Toolbox工具箱进行标定。

    图片采集


    import cv2
    
    cv2.namedWindow("left", 0)
    cv2.namedWindow("right", 0)
    cv2.moveWindow("left", 0, 0)
    cv2.moveWindow("right", 801, 0)
    cv2.resizeWindow("left", 800, 600)
    cv2.resizeWindow("right", 800, 600)
    left_camera = cv2.VideoCapture(0)
    right_camera = cv2.VideoCapture(1)
    
    # 设置左右摄像头的分辨率
    left_camera.set(3, 800)
    left_camera.set(4, 600)
    right_camera.set(3, 800)
    right_camera.set(4, 600)
    
    counter = 0
    
    # 棋盘格尺寸
    pattern = (7, 5) 
    
    # 拍照文件目录
    folder = 'D:/img/img_q/' 
    
    def shot(pos, frame):
        global counter
        path = folder + pos + "_" + str(counter) + ".bmp"
    
        cv2.imwrite(path, frame)
        print("snapshot saved into: " + path)
    
    while True:
        ret, left_frame = left_camera.read()
        ret, right_frame = right_camera.read()
    
        cv2.imshow("left", left_frame)
        cv2.imshow("right", right_frame)
    
        key = cv2.waitKey(1)
        if key == ord('q'):
            break
        elif key == ord('s'):
            shot("left", left_frame)
            shot("right", right_frame)
            counter += 1
    
    left_camera.release()
    right_camera.release()
    cv2.destroyWindow("left")
    cv2.destroyWindow("right")
    

    按s来采集左右相机的图片,采集到的图片如下:
    left
    在这里插入图片描述
    right
    在这里插入图片描述
    左右相机各采集20~30张图片即可。
    注意:图片采集时,要求棋盘完整出现在左右视野。不能有部分未出现情况。

    左右相机标定


    先将MATLAB标定工具箱下载下来。
    MATLAB相机标定工具箱
    提取码:jnme
    将下载下来的工具箱解压。
    将采集到的图片拷贝到下面文件夹(注意图片名要对应)。
    在这里插入图片描述
    然后将上述文件夹拷贝到MATLAB安装路径下的toolbox文件夹下
    在这里插入图片描述
    打开MATLAB,并将工作路径修改为刚才拷贝过去的文件夹。
    在这里插入图片描述
    在命令行窗口输入calib_gui会出现下面窗口。
    在这里插入图片描述
    单击Standard出现如下窗口。
    在这里插入图片描述
    我们先对左相机的图片进行标定,点击Image names,命令行窗口会提示你输入图片的basename(一组图片的公共前缀)以及图片的格式
    在这里插入图片描述
    在这里插入图片描述
    点击Extract grid corners
    在这里插入图片描述
    开始角点提取。
    在这里插入图片描述
    此处全部回车使用默认值。开始提取第一张图片。
    在这里插入图片描述
    提取完第一张后不要立即回车,在命令行输入棋盘格的实际尺寸。这里使用的棋盘格为58mm x 58mm。
    在这里插入图片描述
    第一张提取效果。
    在这里插入图片描述
    在这里插入图片描述
    回车继续下一张。后序数据全部使用默认即可,直到left_图像全部提取完毕。
    在这里插入图片描述
    点击Calibration开始标定。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    点击Save
    在这里插入图片描述
    将保存的文件的名字进行修改。左相机结果改为Calib_Result_left.mat右相机结果改为Calib_Result_right.mat
    在这里插入图片描述
    同左相机的标定流程,对右相机进行标定。
    在这里插入图片描述
    在这里插入图片描述

    立体标定


    左右相机都标定完成后开始立体标定。
    命令中输入stereo_gui启动立体标定面板。
    在这里插入图片描述
    点击Load left and right calibration files,加载左右相机的标定结果。
    在这里插入图片描述
    在这里插入图片描述
    点击Run stereo calibration
    在这里插入图片描述
    在这里插入图片描述
    保存上述结果
    在这里插入图片描述
    在这里插入图片描述
    可以看到,两摄像头位置基本是前向平行的

    测距


    相机标定数据的使用


    camera_configs.py

    import cv2
    import numpy as np
    
    left_camera_matrix = np.array([[406.37454, 0., 326.69505],
                                   [0., 407.55708, 245.46379],
                                   [0., 0., 1.]])
    left_distortion = np.array([[0.02645, -0.05332, -0.00019, 0.00152, 0.00000]])
    
    right_camera_matrix = np.array([[406.44618, 0., 340.65160],
                                    [0., 407.38844, 258.01597],
                                    [0., 0., 1.]])
    right_distortion = np.array([[0.01690, -0.03804, 0.00077, 0.00119, 0.00000]])
    
    # 旋转矩阵。
    om = np.array([0.00733, -0.00336, -0.00375]) 
    # 使用Rodrigues变换将om变换为R。
    R = cv2.Rodrigues(om)[0]  
    # 平移矩阵。
    T = np.array([-120.25274, 0.70313, -1.53635]) 
    
    # 图像尺寸。
    size = (800, 600) 
    
    # 进行立体矫正。
    R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_camera_matrix, left_distortion,
                                                                      right_camera_matrix, right_distortion, size, R,                                                                  T)
    # 计算矫正map。
    left_map1, left_map2 = cv2.initUndistortRectifyMap(left_camera_matrix, left_distortion, R1, P1, size, cv2.CV_16SC2)
    right_map1, right_map2 = cv2.initUndistortRectifyMap(right_camera_matrix, right_distortion, R2, P2, size, cv2.CV_16SC2)
    

    代码演示


    import numpy as np
    import cv2
    import camera_configs
    
    cv2.namedWindow("left", 0)
    cv2.namedWindow("right", 0)
    cv2.namedWindow("depth")
    cv2.moveWindow("left", 0, 0)
    cv2.moveWindow("right", 404, 0)
    cv2.resizeWindow("left", 400, 300)
    cv2.resizeWindow("right", 400, 300)
    cv2.createTrackbar("num", "depth", 0, 10, lambda x: None)
    cv2.createTrackbar("blockSize", "depth", 15, 255, lambda x: None)
    
    camera1 = cv2.VideoCapture(0)
    camera2 = cv2.VideoCapture(1)
    
    camera1.set(3, 800)
    camera1.set(4, 600)
    camera2.set(3, 800)
    camera2.set(4, 600)
    
    # 添加点击事件,打印当前点的距离。
    def callbackFunc(e, x, y, f, p):
        if e == cv2.EVENT_LBUTTONDOWN:        
            print (threeD[y][x])
    
    cv2.setMouseCallback("depth", callbackFunc, None)
    
    while True:
        ret1, frame1 = camera1.read()
        ret2, frame2 = camera2.read()
    
        if not ret1 or not ret2:
            break
    
    	# 根据更正map对图片进行重构。
        img1_rectified = cv2.remap(frame1, camera_configs.left_map1, 
                    camera_configs.left_map2, cv2.INTER_LINEAR)
        img2_rectified = cv2.remap(frame2, camera_configs.right_map1, 
                    camera_configs.right_map2, cv2.INTER_LINEAR)
    
    	# 将图片转为灰度图,为StereoBM做准备。
        imgL = cv2.cvtColor(img1_rectified, cv2.COLOR_BGR2GRAY)
        imgR = cv2.cvtColor(img2_rectified, cv2.COLOR_BGR2GRAY)
    
    	# 两个trackbar用来调节不同的参数查看效果。
        num = cv2.getTrackbarPos("num", "depth")
        blockSize = cv2.getTrackbarPos("blockSize", "depth")
        if blockSize % 2 == 0:
            blockSize += 1
        if blockSize < 5:
            blockSize = 5
    
    	# 根据Block Maching方法生成差异图(opencv里也提供了SGBM/Semi-Global Block Matching算法,有兴趣可以试试)。
        stereo = cv2.StereoBM_create(numDisparities=16*num, blockSize=blockSize)
        disparity = stereo.compute(imgL, imgR)
    
        disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
        # 将图片扩展至3d空间中,其z方向的值则为当前的距离
        threeD = cv2.reprojectImageTo3D(disparity.astype(np.float32)/16., camera_configs.Q)
    
        cv2.imshow("left", img1_rectified)
        cv2.imshow("right", img2_rectified)
        cv2.imshow("depth", disp)
    
    camera1.release()
    camera2.release()
    cv2.destroyAllWindows()
    

    运行结果


    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 一款摄像头的双目测距程序,包含了标定用图以及标定数据,使用Matlab标定工具箱标定 包含两种像素的不同代码及标定图片与结果 运行 当想使用摄像头拍照时,请使用 python cap.py 当拍照完成后,使用MATLAB工具箱标定...
  • 双目测距、重构 楼主之前用的SFM来进行重构,但是得到的是视差图,点云和实物存在比例关系,单目的还是不能解决scale这个问题的。所以今天用双目的来进行重构,期间遇到了很多坑,实属难受。 双目测距过程大致可以...

    双目测距、重构

    楼主之前用的SFM来进行重构,但是得到的是视差图,点云和实物存在比例关系,单目的还是不能解决scale这个问题的。所以今天用双目的来进行重构,期间遇到了很多坑,实属难受。

    楼主自己版本的代码:Github的代码

    双目测距过程大致可以分为,标定,图像校正,计算视差,测距,知道这个流程,目标就很明确了

    标定

    opencv和matlab都有标定的代码,但是老师说还是matlab的标定更加准确,自己试验下来也的确感受到matlab标定更加稳定和精准。matlab立体标定的流程网上很多,就不多赘述了,这里只说下matlab得到的标定数据怎么转换为opencv可用的数据,两个数据存放的形式是不一样的,要是这里不避雷后面等于白做。

    先上代码:opencv-python部分测距代码 参考源码
    但是这里他没有说到这个数据关系,这不是坑人吗?

    • IntrinsicMatrix 内参,matlab和opencv的两个矩阵是转置的关系
    • RadialDistortion 为 径向畸变,摄像头由于光学透镜的特性使得成像存在着径向畸变,可由K1,K2,K3确定。
      TangentialDistortion 为 切向畸变,由于装配方面的误差,传感器与光学镜头之间并非完全平行,因此成像存在切向畸变,可由两个参数P1,P2确定。
      opencv这个的参数的排放顺序,即K1,K2,P1,P2,K3
      附上matlab官网关于这两个系数的描述 https://ww2.mathworks.cn/help/vision/ref/cameraintrinsics.html?searchHighlight=RadialDistortion&s_tid=doc_srchtitle
    • RotationOfCamera2 相机二相对于相机一的转换矩阵,相对 opencv ,也是需要转置转化的

    明确opencv和matlab系数的转换关系之后就可以进行下一步的工作了

    校正和测距

    前面花了这么大的功夫就是为了先将图片进行校正处理,其实这一步也可以交给matlab先左处理,得到校正后的图片再进行视差图的测距,然而其实matlab也有完整双目测距的代码,但是不知道底层的代码算法写的有什么问题,做出来的效果真的是不好。
    原图和视差图效果:

    在这里插入图片描述
    在这里插入图片描述
    但是最后使用cv2.reprojectImageTo3D出来的效果不太行,很明显,我没有两个一样的相机

    关于参数:
    cv2.stereoRectify() 参数详解
    cv2.StereoBM_create() 参数详解
    cv2.reprojectImageTo3D() 参数详解

    参考汇总:(非常感激!)
    https://blog.csdn.net/qq_32951799/article/details/83090855

    展开全文
  • 双目测距代码 python opencv 利用双目摄像头拍照,测距

    万次阅读 热门讨论 2018-03-19 22:33:03
    最近一直在研究工控机,水下机器人等,好不容易闲下来,没办法呀,继续前行吧,前面一直说双目测距,但没有高速大家如何获得这个双目标注得图像,我在这把这代码贴一下吧,获得这些双目拍摄的图片就可以利用matlab和...
  • 双目测距--Matlab标定及深度图

    千次阅读 2017-10-20 17:41:38
    上一次用的opencv官方的程序进行的双目标定,效果比较差,最后输出的映射图畸变比较严重 后来请教学长后改用matlab标定,解决了映射畸变问题 具体的matlab标定方法可以看下面三个大佬的博文,亲测可以 ...
  • 今天完成双目测距项目的第二部分,实现Matlab算法仿真,主要包括图像二值化、计算目标坐标、目标框选以及将图片转为txt用于后面的FPGA算法仿真。Matlab代码工程关注我的公众号:芯王国,后台回复 双目测距算法仿真 ...
  • 基于opencv双目校正、匹配以及双目测距 在完成双目标定后,使用matlab的双目标定结果,通过本文代码实现双目匹配以及测距功能。 一共有6个参数供opencv调用, camera1的内参stereoParams.CameraParameters1....
  • 本文采用MATLAB标定工具箱和OpenCV3.10来实现双目测距,设备为两个CMOS工业相机和相应的双目云台。 首先感谢CSDN上两位大神前辈邹宇华和scyscyao,虽然是六年前的博客,OpenCV也从1.0的版本更新到了3.1版本,但...
  • 双目测距步骤二:单/双目标定

    千次阅读 2018-09-09 16:38:10
    标定很重要,后面的双目测距,三维重构等都必须要用,所以必须要学会使用Matlab进行双目标定。 首先要下载一个工具包放在D:\MATLAB\R2016a\toolbox\matlab这个路径(具体看自己的安装路径),工具包可以在matlab官网...
  • conda install opencv 在jupyter notebook中嵌入新建环境opencv windows10 下安装Matlab 单usb双目摄像头:本人使用的是lenaCV 3D Camera 棋盘格:可以下载打印 1 双目相机标定 1.1 获取标定图片并分割左右图片 ...
  • 基于OpenCV3.2+VS2013双目测距 1、 摄像头标定 1.1、通查询资料和博客大概有两种方式:  (1) 利用OpenCV自带的校正程序 (2) 利用MATLAB工具来标定 1.2该工程是利用MATLAB工具来标定: (1)固定好摄像头,尽量保证...
  • Opencv-Python 笔记——双目测距(一)

    千次阅读 2019-10-08 20:05:35
    Opencv-Python 笔记——双目测距 在假期着手的双目视觉的项目,笔记记在我的印象笔记里。现因为项目需要我把它放在CSDN上,有几张图片无法从印象笔记里导出来所以把链接放在这里,做的时候参考了不少前辈的工作,...
  • 如果你已经看完了:一起做双目测距-USB_CAMERA检测人脸距离系列(1)–OpenCV打开双目摄像头,那么你的摄像头将可以像电脑摄像头那样读取到图片数据了,接下来我们关注了解你所拥有的这对摄像头,进行双目相机的标定...
  • OpenCV012:双目测距

    2018-01-25 20:24:17
    一.摄像头标定  1. 打印一张棋盘图,网上自己随便找,或者自己用CAD画一个...使用matlab工具箱标定:TOOLBOX_calib,标定方法百度一下,就有很多介绍  3.编写一个摄像头参数文件,并命名为:camera_configs.py,我
  • 需求:使用双目摄像头得出物体3D坐标,本质就是利用双目来得到深度信息。 github代码 0 知识扫盲 相机模型 四大坐标关系及其关系 1 相机标定 Q1:用MATLAB标定还是opencv标定? A1:两种我都试了。总结来说,直接...
  • opencv实现双目视觉测距

    万次阅读 多人点赞 2017-12-26 11:47:21
    最近一直在研究双目视觉测距,资料真的特别多网上,有matlab 的,python的,C++的,但个人感觉都不详细,对于小白,特别不容易上手,在这里我提供一个傻瓜式教程吧,利用matlab来进行标注,图形界面,无须任何代码,...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

matlab双目测距

matlab 订阅