Преглед на файлове

双目测距代码交接

master
nyh преди 5 месеца
ревизия
f27eaf3c28
променени са 37 файла, в които са добавени 317 реда и са изтрити 0 реда
  1. Двоични данни
      Camera matrix left.npy
  2. Двоични данни
      ChessboardCorners_img_l.jpg
  3. Двоични данни
      E.npy
  4. Двоични данни
      F.npy
  5. Двоични данни
      R.npy
  6. +149
    -0
      SGBMBinocularVision.py
  7. Двоични данни
      T.npy
  8. Двоични данни
      __pycache__/stereoconfig.cpython-37.pyc
  9. Двоични данни
      __pycache__/stereoconfig.cpython-38.pyc
  10. Двоични данни
      __pycache__/stereoconfig.cpython-39.pyc
  11. +65
    -0
      calibration.py
  12. Двоични данни
      cameraMatrix right.npy
  13. Двоични данни
      cap/left/cal/left0.jpg
  14. Двоични данни
      cap/left/cal/left1.jpg
  15. Двоични данни
      cap/left/cal/left2.jpg
  16. Двоични данни
      cap/left/cal/left3.jpg
  17. Двоични данни
      cap/left/cal/left4.jpg
  18. Двоични данни
      cap/left/cal/left5.jpg
  19. Двоични данни
      cap/left/cal/left6.jpg
  20. Двоични данни
      cap/left/cal/left7.jpg
  21. Двоични данни
      cap/left/cal/left8.jpg
  22. Двоични данни
      cap/left/cal/left9.jpg
  23. Двоични данни
      cap/right/cal/right0.jpg
  24. Двоични данни
      cap/right/cal/right1.jpg
  25. Двоични данни
      cap/right/cal/right2.jpg
  26. Двоични данни
      cap/right/cal/right3.jpg
  27. Двоични данни
      cap/right/cal/right4.jpg
  28. Двоични данни
      cap/right/cal/right5.jpg
  29. Двоични данни
      cap/right/cal/right6.jpg
  30. Двоични данни
      cap/right/cal/right7.jpg
  31. Двоични данни
      cap/right/cal/right8.jpg
  32. Двоични данни
      cap/right/cal/right9.jpg
  33. Двоични данни
      distCoeffs left.npy
  34. Двоични данни
      distCoeffs right.npy
  35. +38
    -0
      stereoconfig.py
  36. +44
    -0
      takePhotos.py
  37. +21
    -0
      undistortion.py

Двоични данни
Camera matrix left.npy Целия файл


Двоични данни
ChessboardCorners_img_l.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 111KB

Двоични данни
E.npy Целия файл


Двоични данни
F.npy Целия файл


Двоични данни
R.npy Целия файл


+ 149
- 0
SGBMBinocularVision.py Целия файл

@@ -0,0 +1,149 @@
import cv2
import numpy as np
import time
import math

# -----------------------------------双目相机的基本参数---------------------------------------------------------
# left_camera_matrix 左相机的内参矩阵
# right_camera_matrix 右相机的内参矩阵
#
# left_distortion 左相机的畸变系数 格式(K1,K2,P1,P2,0)
# right_distortion 右相机的畸变系数
# -------------------------------------------------------------------------------------------------------------

# 左镜头的内参,如焦距
left_camera_matrix = np.array([[716.44292633, 0., 641.67188624], [0., 712.73240811, 321.80519519], [0., 0., 1.]])
right_camera_matrix = np.array([[714.26431969, 0., 642.69117299], [0., 710.9244224, 329.27392689], [0., 0., 1.]])

# 畸变系数,K1、K2、K3为径向畸变,P1、P2为切向畸变
left_distortion = np.array([[-0.05928891, 0.12398536, -0.00180906, 0.00385613, -0.51151642]])
right_distortion = np.array([[-0.0371133, -0.01211102, 0.00179116, 0.00457662, -0.13804965]])

# 旋转矩阵
R = np.array([[0.99907365, 0.00181788, -0.04299471],
[-0.00210211, 0.99997623, -0.00656642],
[0.04298175, 0.00665072, 0.99905372]])
# 平移矩阵
T = np.array([-59.57562815, -1.61493649, -1.71697302])

size = (1280, 720)

# 通过之前标定的数据计算相关参数,用于畸变矫正
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")


# 加载视频文件
capture = cv2.VideoCapture(1)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 2560)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

WIN_NAME = 'depth'
cv2.namedWindow(WIN_NAME, cv2.WINDOW_AUTOSIZE)

# 读取视频
fps = 0.0
ret, frame = capture.read()
while capture.isOpened():
# 开始计时
t1 = time.time()
# 是否读取到了帧,读取到了则为True
ret, frame = capture.read()
# 切割为左右两张图片
frame1 = frame[0:720, 0:1280]
frame2 = frame[0:720, 1280:2560]
# 将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 = 8
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))) / 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('Deep disp', disp) # 显示深度图的双目画面
# 若键盘按下q则退出播放
if cv2.waitKey(1) & 0xff == ord('q'):
break

# 释放资源
capture.release()

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






Двоични данни
T.npy Целия файл


Двоични данни
__pycache__/stereoconfig.cpython-37.pyc Целия файл


Двоични данни
__pycache__/stereoconfig.cpython-38.pyc Целия файл


Двоични данни
__pycache__/stereoconfig.cpython-39.pyc Целия файл


+ 65
- 0
calibration.py Целия файл

@@ -0,0 +1,65 @@
import cv2
import os
import numpy as np

leftpath = r'.\cap\left\cal'
rightpath = r'.\cap\right\cal'
CHECKERBOARD = (4, 4) # 棋盘格内角点数
square_size = (30, 30) # 棋盘格大小,单位mm

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # termination criteria 结束条件
imgpoints_l = [] # 存放左图像坐标系下角点位置
imgpoints_r = [] # 存放右图像坐标系下角点位置
objpoints = [] # 存放世界坐标系下角点位置
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[0, :, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objp[0, :, 0] *= square_size[0]
objp[0, :, 1] *= square_size[1]


for ii in range(len(os.listdir(leftpath))):
img_l = cv2.imread(os.path.join(leftpath, os.listdir(leftpath)[ii]))
gray_l = cv2.cvtColor(img_l, cv2.COLOR_BGR2GRAY)
img_r = cv2.imread(os.path.join(rightpath, os.listdir(rightpath)[ii]))
gray_r = cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY)
ret_l, corners_l = cv2.findChessboardCorners(gray_l, CHECKERBOARD) # 检测棋盘格内角点。cv2.findChessboardCorners()函数是OpenCV中的一个函数,用于找到棋盘格的所有内角点,返回所有检测到的内角点的2D坐标。
ret_r, corners_r = cv2.findChessboardCorners(gray_r, CHECKERBOARD)
if ret_l and ret_r:
print("计算第"+str(ii)+"对图像")
objpoints.append(objp)
corners2_l = cv2.cornerSubPix(gray_l, corners_l, (11, 11), (-1, -1), criteria)
imgpoints_l.append(corners2_l)
corners2_r = cv2.cornerSubPix(gray_r, corners_r, (11, 11), (-1, -1), criteria)
imgpoints_r.append(corners2_r)
img = cv2.drawChessboardCorners(img_l, CHECKERBOARD, corners2_l, ret_l)
cv2.imwrite('./ChessboardCorners_img_l.jpg', img)

ret, mtx_l, dist_l, rvecs_l, tvecs_l = cv2.calibrateCamera(objpoints, imgpoints_l, gray_l.shape[::-1], None, None) # 先分别做单目标定,利用单目校正函数实现相机内参初始化
ret, mtx_r, dist_r, rvecs_r, tvecs_r = cv2.calibrateCamera(objpoints, imgpoints_r, gray_r.shape[::-1], None, None)
retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = cv2.stereoCalibrate(objpoints, imgpoints_l, imgpoints_r, mtx_l, dist_l, mtx_r, dist_r, gray_l.shape[::-1]) # 再做双目标定

print("stereoCalibrate : \n")
print("Camera matrix left : ") # Camera matrix 相机内参矩阵
print(cameraMatrix1)
print("distCoeffs left : ") # distCoeffs 畸变矩阵
print(distCoeffs1)
print("cameraMatrix right : ")
print(cameraMatrix2)
print("distCoeffs right : ")
print(distCoeffs2)
print("R : ") # 第一和第二个摄像机之间的旋转矩阵
print(R)
print("T : ") # 第一和第二个摄像机之间的平移矩阵
print(T)
print("E : ") # 本质矩阵
print(E)
print("F : ") # 基础矩阵
print(F)
np.save('Camera matrix left.npy', cameraMatrix1)
np.save('distCoeffs left.npy', distCoeffs1)
np.save('cameraMatrix right.npy', cameraMatrix2)
np.save('distCoeffs right.npy', distCoeffs2)
np.save('R.npy', R)
np.save('T.npy', T)
np.save('F.npy', F)
np.save('E.npy', E)

Двоични данни
cameraMatrix right.npy Целия файл


Двоични данни
cap/left/cal/left0.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 88KB

Двоични данни
cap/left/cal/left1.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 94KB

Двоични данни
cap/left/cal/left2.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 79KB

Двоични данни
cap/left/cal/left3.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 93KB

Двоични данни
cap/left/cal/left4.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 94KB

Двоични данни
cap/left/cal/left5.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 109KB

Двоични данни
cap/left/cal/left6.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 97KB

Двоични данни
cap/left/cal/left7.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 109KB

Двоични данни
cap/left/cal/left8.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 121KB

Двоични данни
cap/left/cal/left9.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 105KB

Двоични данни
cap/right/cal/right0.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 92KB

Двоични данни
cap/right/cal/right1.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 97KB

Двоични данни
cap/right/cal/right2.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 78KB

Двоични данни
cap/right/cal/right3.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 98KB

Двоични данни
cap/right/cal/right4.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 101KB

Двоични данни
cap/right/cal/right5.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 115KB

Двоични данни
cap/right/cal/right6.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 101KB

Двоични данни
cap/right/cal/right7.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 113KB

Двоични данни
cap/right/cal/right8.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 128KB

Двоични данни
cap/right/cal/right9.jpg Целия файл

Before After
Width: 1280  |  Height: 720  |  Size: 110KB

Двоични данни
distCoeffs left.npy Целия файл


Двоични данни
distCoeffs right.npy Целия файл


+ 38
- 0
stereoconfig.py Целия файл

@@ -0,0 +1,38 @@
import numpy as np


# 双目相机参数
class stereoCamera(object):
def __init__(self):
# 左相机内参
self.cam_matrix_left = np.load("Camera matrix left.npy")
# 右相机内参
self.cam_matrix_right = np.load('CameraMatrix right.npy')

# 左右相机畸变系数:[k1, k2, p1, p2, k3]
self.distortion_l = np.load('distCoeffs left.npy')
self.distortion_r = np.load('distCoeffs right.npy')

# 旋转矩阵
self.R = np.load('R.npy')

# 平移矩阵
self.T = np.load('T.npy')

# 主点列坐标的差
self.doffs = 0.0

# 指示上述内外参是否为经过立体校正后的结果
self.isRectified = False

def setMiddleBurryParams(self):
self.cam_matrix_left = np.load("Camera matrix left.npy")
self.cam_matrix_right = np.load('CameraMatrix right.npy')

self.distortion_l = np.load('distCoeffs left.npy') # 以下6行代码是添加的
self.distortion_r = np.load('distCoeffs right.npy')
self.R = np.load('R.npy')
self.T = np.load('T.npy')
self.doffs = 21.83546358
self.isRectified = True


+ 44
- 0
takePhotos.py Целия файл

@@ -0,0 +1,44 @@
import cv2
import time
# AUTO = True # 自动拍照,或手动按s键拍照
AUTO = False
INTERVAL = 2 # 自动拍照间隔
camera = cv2.VideoCapture(1) # 设置分辨率左右摄像机同一频率,同一设备ID;左右摄像机总分辨率2560x720;分割为两个1280x720
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 2560)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
counter = 0
utc = time.time()
folder = "./takePhoto/" # 拍照文件目录


def shot(pos, frame):
global counter
path = folder + pos + "_" + str(counter) + ".jpg"
cv2.imwrite(path, frame)
print("snapshot saved into: " + path)


while camera.isOpened():
ret, frame = camera.read()
left_frame = frame[0:720, 0:1280]
right_frame = frame[0:720, 1280:2560]
cv2.imshow("left", left_frame)
cv2.imshow("right", right_frame)

now = time.time()
if AUTO and now - utc >= INTERVAL:
shot("left", left_frame)
shot("right", right_frame)
counter += 1
utc = now
key = cv2.waitKey(1)
if key == ord("q"):
break
elif key == ord("s"):
shot("left", left_frame)
shot("right", right_frame)
counter += 1
camera.release()
cv2.destroyWindow("left")
cv2.destroyWindow("right")


+ 21
- 0
undistortion.py Целия файл

@@ -0,0 +1,21 @@
import cv2
import glob
import numpy as np
a = [0]
a.append(np.load("F.npy"))
# a = np.expand_dims(np.load("Camera matrix left.npy"),axis=1)

# b = np.expand_dims(np.loadtxt("Camera matrix left.npy"),axis=0)
a.append(np.load("Camera matrix left.npy"))

a.append(np.load('Camera matrix right.npy'))
a.append(np.load('distCoeffs left.npy'))

a.append(np.load('distCoeffs right.npy'))
a.append(np.load('R.npy'))
a.append(np.load('T.npy'))
a.append(np.load('F.npy'))
a.append(np.load('E.npy'))
for i in a:
print(i)
print('\n')

Loading…
Отказ
Запис