【双目相机】双目摄像头测距并导出测距数据进入txt【python】2

1.双目测距,通过鼠标点击像素导出像素的距离

代码如下,核心是threeD,图片内所有像素对应的世界坐标都储存在threeD

#从excel里读取数据
#144行fps帧率不准
import cv2
import pandas as pd
import numpy as np
import time
import random
import math
from numpy import *

# -----------------------------------双目相机的基本参数---------------------------------------------------------
#   left_camera_matrix          左相机的内参矩阵
#   right_camera_matrix         右相机的内参矩阵
#
#   left_distortion             左相机的畸变系数    格式(K1,K2,P1,P2,0)
#   right_distortion            右相机的畸变系数
# -------------------------------------------------------------------------------------------------------------
# 左镜头的内参,如焦距
file_path = r'C:\out1.xlsx'   # r对路径进行转义,windows需要
raw_data = pd.read_excel(file_path)  # header=0表示第一行是表头,就自动去除了
#raw_data = pd.read_excel(file_path, header=0)
#print(raw_data)
data = raw_data.values     # 只提取表中信息
#print(data)
np.array([1,2,3,4,5,6,7,8,9],dtype='float32');
left_camera_matrix = np.array((data[4:7, 1:4]),dtype='float64');
right_camera_matrix = np.array((data[9:12, 1:4]),dtype='float64');
# 畸变系数,K1、K2、K3为径向畸变,P1、P2为切向畸变:[K1,K2,P1,P2,K3]
K1left= np.array((data[7:8, 1:2]),dtype='float64');
K2left= np.array((data[7:8, 2:3]),dtype='float64');
K3left= np.array((data[7:8, 3:4]),dtype='float64');
P1left= np.array((data[8:9, 1:2]),dtype='float64');
P2left= np.array((data[8:9, 2:3]),dtype='float64');
K1right= np.array((data[12:13, 1:2]),dtype='float64');
K2right= np.array((data[12:13, 2:3]),dtype='float64');
K3right= np.array((data[12:13, 3:4]),dtype='float64');
P1right= np.array((data[13:14, 1:2]),dtype='float64');
P2right= np.array((data[13:14, 2:3]),dtype='float64');
#畸变系数,K1、K2、K3为径向畸变,P1、P2为切向畸变:[K1,K2,P1,P2,K3]
left_distortion =np.hstack((K1left,K2left,P1left,P2left,K3left))
right_distortion =np.hstack((K1right,K2right,P1right,P2right,K3right))
# 旋转矩阵
R = np.array((data[1:4, 1:4]),dtype='float64');
# 平移矩阵
T = np.array(np.transpose(data[0:1, 1:4]),dtype='float64');
#T = np.array([-55.4164455,-0.307896388,-3.669759334])

size = (320, 180)
R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_camera_matrix, left_distortion,
                                                                  right_camera_matrix, right_distortion, size, R,
                                                                  T)

# 校正查找映射表,将原始图像和校正后的图像上的点一一对应起来
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)
print(Q)

# --------------------------鼠标回调函数---------------------------------------------------------
#   event               鼠标事件
#   param               输入参数
# -----------------------------------------------------------------------------------------------
def onmouse_pick_points(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        threeD = param
        print('\n像素坐标 x = %d, y = %d' % (x, y))
        # print("世界坐标是:", threeD[y][x][0], threeD[y][x][1], threeD[y][x][2], "mm")
        print("世界坐标xyz 是:", threeD[y][x][0] / 1000.0, threeD[y][x][1] / 1000.0, threeD[y][x][2] / 1000.0, "m")
        distance = math.sqrt(threeD[y][x][0] ** 2 + threeD[y][x][1] ** 2 + threeD[y][x][2] ** 2)
        distance = distance / 1000.0  # mm -> m
        print("距离是:", distance, "m")
        #输出图片内每一像素的距离
        a1=mat(threeD[:,:,0])
        a2=mat(threeD[:,:,1])
        a3=mat(threeD[:,:,2])
        aa1=multiply(a1,a1)
        aa2=multiply(a2,a2)
        aa3=multiply(a3,a3)
        aaa=aa1+aa2+aa3
        aaa_d = np.sqrt(aaa) 
        np.savetxt("juli.txt", aaa_d, fmt = '%f', delimiter = ',')
        #b = np.loadtxt('a.txt', delimiter = ',')

# 加载视频文件
capture = cv2.VideoCapture(0)
WIN_NAME = 'Deep disp'
cv2.namedWindow(WIN_NAME, cv2.WINDOW_AUTOSIZE)

# 读取视频
fps = 0.0
ret, frame = capture.read()
while ret:
    # 开始计时
    t1 = time.time()
    # 是否读取到了帧,读取到了则为True
    ret, frame = capture.read()
    # 切割为左右两张图片
    frame1 = frame[150:330, 0:320]
    frame2 = frame[150:330, 320:640]
    # 将BGR格式转换成灰度图片,用于畸变矫正
    imgL = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    imgR = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

    # 重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
    # 依据MATLAB测量数据重建无畸变图片,输入图片要求为灰度图
    img1_rectified = cv2.remap(imgL, left_map1, left_map2, cv2.INTER_LINEAR)
    img2_rectified = cv2.remap(imgR, right_map1, right_map2, cv2.INTER_LINEAR)

    # 转换为opencv的BGR格式
    imageL = cv2.cvtColor(img1_rectified, cv2.COLOR_GRAY2BGR)
    imageR = cv2.cvtColor(img2_rectified, cv2.COLOR_GRAY2BGR)

    # ------------------------------------SGBM算法----------------------------------------------------------
    #   blockSize                   深度图成块,blocksize越低,其深度图就越零碎,0<blockSize<10
    #   img_channels                BGR图像的颜色通道,img_channels=3,不可更改
    #   numDisparities              SGBM感知的范围,越大生成的精度越好,速度越慢,需要被16整除,如numDisparities
    #                               取16、32、48、64等
    #   mode                        sgbm算法选择模式,以速度由快到慢为:STEREO_SGBM_MODE_SGBM_3WAY、
    #                               STEREO_SGBM_MODE_HH4、STEREO_SGBM_MODE_SGBM、STEREO_SGBM_MODE_HH。精度反之
    # ------------------------------------------------------------------------------------------------------
    blockSize = 3
    img_channels = 3
    stereo = cv2.StereoSGBM_create(minDisparity=1,
                                   numDisparities=64,
                                   blockSize=blockSize,
                                   P1=8 * img_channels * blockSize * blockSize,
                                   P2=32 * img_channels * blockSize * blockSize,
                                   disp12MaxDiff=-1,
                                   preFilterCap=1,
                                   uniquenessRatio=10,
                                   speckleWindowSize=100,
                                   speckleRange=100,
                                   mode=cv2.STEREO_SGBM_MODE_HH)
    # 计算视差
    disparity = stereo.compute(img1_rectified, img2_rectified)

    # 归一化函数算法,生成深度图(灰度图)
    disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

    # 生成深度图(颜色图)
    dis_color = disparity
    dis_color = cv2.normalize(dis_color, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    dis_color = cv2.applyColorMap(dis_color, 2)

    # 计算三维坐标数据值
    threeD = cv2.reprojectImageTo3D(disparity, Q, handleMissingValues=True)
    # 计算出的threeD,需要乘以16,才等于现实中的距离
    threeD = threeD * 16

    # 鼠标回调事件
    cv2.setMouseCallback("depth", onmouse_pick_points, threeD)

    #完成计时,计算帧率
    fps = (fps + (1. / (time.time() - t1+0.1))) / 2
    frame = cv2.putText(frame, "fps= %.2f" % (fps), (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    cv2.imshow("depth", dis_color)
    cv2.imshow("left", frame1)
    cv2.imshow(WIN_NAME, disp)  # 显示深度图的双目画面,WIN_NAME = 'Deep disp'
    # 若键盘按下q则退出播放
    if cv2.waitKey(1) & 0xff == ord('q'):
        break

# 释放资源
capture.release()

# 关闭所有窗口
cv2.destroyAllWindows()

测距时需用到matlab导出的相机标定参数,详见【双目相机】基于matlab的参数标定2-使用matlab标定

注意:使用之前必须新建立一个空的txt文件(如代码内的threeDD.txt),新建立的文件必须是空的(即不含任何内容)

使用此代码,在鼠标点击事件发生时即可记录此时刻的threeD内容

2.将txt转化为excel索引数据

参考【双目相机】双目摄像头测距并导出测距数据进入txt【python】
索引序号(X,Y)与像素坐标(x,y)的关系:
(X,Y)=(x+1,y+1)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现效果:http://v.youku.com/v_show/id_XMTU2Mzk0NjU3Ng==.html 如何在你的电脑上运行这个程序? 1,它需要cvblobslib这一个opencv的扩展库来实现检测物体与给物体画框的功能,具体安装信息请见: http://dsynflo.blogspot.com/2010/02/cvblobskib-with-opencv-installation.html,当你配置好cvblobslib之后,你可以用这一的程序进行测试:http://dl.dropbox.com/u/110310945/Blobs%20test.rar 2,视频中两个摄像头之间的距离是6cm,你可以根据你摄像头的型号,来选择合适的距离来达到最好的效果。 3,在进行测距之前,首先需要对摄像头进行标定,那么如何标定呢? 在stdafx.h中把"#define CALIBRATION 0"改成 “#define CALIBRATION 1”表示进行标定,标定之后,你就可以在工程目录下的"CalibFile" 文件夹中得到标定信息的文件。如果标定效果还不错,你就可以吧"#define CALIBRATION " 改成0,以后就不需要再标定,直接使用上一次的标定信息。你还需要把"#define ANALYSIS_MODE 1"这行代码放到stdafx.h中。 4,视频中使用的是10*7的棋牌格,共摄录40帧来计算摄像头的各种参数,如果你像使用其他棋盘格,可以在 "StereoFunctions.cpp"文件中修改相应参数。 5,如果你无法打开摄像头,可以在 "StereoGrabber.cpp"文件中修改代码“cvCaptureFromCAM(index)”中index的值。 6,About computing distance: it interpolates the relationship between depth-value and real-distance to third degree polynomial. So i used excel file "interpolation" for interpolation to find k1 to k4, you should find your own value of these parameters. 7,你可以通过调整控制窗口中各个参数的滑块,从而来得到更好的视差图。 8,在目录下的”distance“文件夹中,有计算距离信息的matlab代码。 9,如果你想了解基本的理论,可以看一下这个文档:http://scholar.lib.vt.edu/theses/available/etd-12232009-222118/unrestricted/Short_NJ_T_2009.pdf 视频中环境:vs2008,opencv2.1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值