2019年2月22日13:52:37

https://zhuanlan.zhihu.com/p/29968267

这里有个tensorlfow代码的阅读博客:

https://zhuanlan.zhihu.com/p/29664269

跑的是这个版本: https://github.com/ClubAI/MonoDepth-PyTorch

对比了下 tf 和 pt 版本的代码,比较简单,就不分析了。

输入的图片先resize到 256x512 大小

model部分生成了4个不同尺度的视差图:

print("self disp1 size:", self.disp1.size() )  # torch.Size([1, 2, 256, 512])
print("self disp2 size:", self.disp2.size() ) # torch.Size([1, 2, 128, 256])
print("self disp3 size:", self.disp3.size() ) # torch.Size([1, 2, 64, 128])
print("self disp4 size:", self.disp4.size() ) # torch.Size([1, 2, 32, 64])
return self.disp1, self.disp2, self.disp3, self.disp4 # 输出各个尺度的左右视差图

然后  loss 部分 loss = loss_function(disps, [left, right])

因为双目相机视差公式 x_left = x_right + disparity 是假设两个相机的光轴平行,

然后代码中真的就是直接加。

所以输入到网络中的 左-右图像对都要先做 立体校正 !

参考  cv2.stereoRectify 的相关知识。

https://www.cnblogs.com/zyly/p/9373991.html

 # -*- coding: utf-8 -*-
"""
Created on Wed Feb 27 13:43:29 2019 @author: x 这个用opencv的函数完成了深度估计 https://github.com/aaliomer/Home-Drone/blob/
a22f9d78644996d7876716ee961e29a9f4e8a705/python/depth%20map/calibrationExample.py https://blog.csdn.net/xiao__run/article/details/78887362 """ import numpy as np
import cv2 numBoards = 30 #how many boards would you like to find criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) w = 9
h = 6 # Arrays to store object points and image points from all the images.
object_points = [] # 3d point in real world space
imagePoints1 = [] # 2d points in image plane.
imagePoints2 = [] # 2d points in image plane. corners1 = []
corners2 = [] obj = np.zeros((9*6, 3), np.float32)
obj[:,:2] = np.mgrid[0:9, 0:6].T.reshape(-1,2)
obj = obj*25 # 25 mm 18.1 cap = cv2.VideoCapture("./calibration.avi") success = 0
k = 0
found1 = False
found2 = False i = 0
while True:
i += 1
ret, frame = cap.read()
if ret is False:
break img1 = frame[:, 640:] # left
img2 = frame[:, 0:640] # right # retL, img1 = vidStreamL.read()
# retR, img2 = vidStreamR.read() # height, width, depth = img1.shape gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) found1, corners1 = cv2.findChessboardCorners(img1, (w,h), None)
found2, corners2 = cv2.findChessboardCorners(img2, (w,h), None) if (found1):
cv2.cornerSubPix(gray1, corners1, (11, 11), (-1, -1),criteria)
cv2.drawChessboardCorners(gray1, (w,h), corners1, found1) if (found2):
cv2.cornerSubPix(gray2, corners2, (11, 11), (-1, -1), criteria)
cv2.drawChessboardCorners(gray2, (w,h), corners2, found2) cv2.imshow('image1 left', gray1)
cv2.imshow('image2 right', gray2) k = cv2.waitKey(1) if (found1 != 0 and found2 != 0): if i%20 == 0:
imagePoints1.append(corners1);
imagePoints2.append(corners2);
object_points.append(obj); print("Corners stored\n") success+=1 if (success >= numBoards):
break cap.release()
cv2.destroyAllWindows()
#%%
# 下面是matlab标定的结果,应该比opencv的更准一点
mtx_left = np.array([
[767.49, 1.927, 314.49],
[ 0. ,766.64, 237.19],
[ 0. ,0. ,1.],
]) dist_left = np.array([0.0047, 0.0793, 1.39e-04, 0.0030, -0.6080]) mtx_right = np.array([
[767.72, 1.3963, 330.26],
[ 0. ,765.37, 160.09],
[ 0. ,0. ,1. ],
]) dist_right = np.array([ 0.0411,-0.3073,-3.037e-04,0.0041,0.9156])
#%%
print("Starting Calibration\n") width = 640
height = 480 retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F \
= cv2.stereoCalibrate(object_points, imagePoints1, imagePoints2,
mtx_left, dist_left, mtx_right, dist_right,
(width, height) ) print("Done Calibration\n")
#%%
size = (640, 480) # 图像尺寸 # 进行立体更正
R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = \
cv2.stereoRectify(mtx_left, dist_left,
mtx_right, dist_right, size, R, T) # 计算更正map
left_map1, left_map2 = \
cv2.initUndistortRectifyMap(mtx_left, dist_left, R1, P1, size, cv2.CV_16SC2) right_map1, right_map2 = \
cv2.initUndistortRectifyMap(mtx_right, dist_right, R2, P2, size, cv2.CV_16SC2)
#%%
#cv2.namedWindow("left")
#cv2.namedWindow("right")
cv2.namedWindow("depth") #cv2.moveWindow("left", 0, 0)
#cv2.moveWindow("right", 600, 0) cv2.createTrackbar("num", "depth", 0, 10, lambda x: None)
cv2.createTrackbar("blockSize", "depth", 5, 255, lambda x: None) # 添加点击事件,打印当前点的距离
def callbackFunc(e, x, y, f, p):
if e == cv2.EVENT_LBUTTONDOWN:
print(threeD[y][x]) cv2.setMouseCallback("depth", callbackFunc, None) cap = cv2.VideoCapture("./outdoor_cam_1547865993.avi")
#cap = cv2.VideoCapture("./calibration.avi") while True:
ret, frame = cap.read()
if ret is False:
break frame1 = frame[:, 640:] # left
frame2 = frame[:, 0:640] # right if ret is False:
break # 根据更正map对图片进行重构
img1_rectified = cv2.remap(frame1, left_map1, left_map2, cv2.INTER_LINEAR)
img2_rectified = cv2.remap(frame2, right_map1, 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) disp = cv2.applyColorMap(disp, cv2.COLORMAP_HOT) # 将图片扩展至3d空间中,其z方向的值则为当前的距离
threeD = cv2.reprojectImageTo3D(disparity.astype(np.float32)/16., Q) # cv2.imshow("left", img1_rectified)
# cv2.imshow("right", img2_rectified) lr = np.hstack((img1_rectified, img2_rectified)) cv2.imshow("left_right", lr) cv2.imshow("depth", disp) key = cv2.waitKey(1)
if key == ord("q"):
break # elif key == ord("s"):
# cv2.imwrite("./snapshot/BM_left.jpg", imgL)
# cv2.imwrite("./snapshot/BM_right.jpg", imgR)
# cv2.imwrite("./snapshot/BM_depth.jpg", disp) cap.release()
cv2.destroyAllWindows()

另外,kitti的左右图像重叠率在90%以上,如果自己用双目相机拍视频,

想要尽量复现出一个较好的结果的话,应该尽量贴近kitti数据集的状态。

等玩熟了再尝试做点改变。

训练过程 不需要 具体的参数 焦距 f 和 基线长b,这就说明了最后训练出来的网络权重只

对这个相机有效,只对这个相机拍出来的图片能做深度估计。

换个相机拍的图片,深度预测效果可能就没那么好了。

2019年3月8日14:15:57

用vscode的对比功能,可以轻松的比较 tf 和 pt 版本的代码的异同

后续可以把其他较新的tensorflow的库改写成pytorch版了。

2019年3月14日16:54:45

在 pytorch 下写了一个 saver,保存了 模型权重 以及 optimizer 状态。

emmm,以后可以把耗时的训练分成好几个晚上来做了。。。都是被渣1050逼的。。。

其实最好做一个 非常小的数据集 以方便调试,做一个 train、valid 之外的很小的数据集。

2019年3月15日08:59:57

用于train的图片3225张,用于valid的图片645张,

跑了81个epoch,平均每个epoch大概 630 s,到第60个epoch的时候valid loss就不怎么往下走了,

在valid数据集上,部分图片的测试结果已经可以看了。后续还要再调整下 lr 继续训练。

公司的双目相机很劣质,数据集也很小,拍摄的场景也不理想,训练的epoch也不多,

这个结果已经可以接受了。

2019年3月16日09:27:36

又继续训练了一个晚上,epoch跑到了差不多160,train_loss从0.66掉到0.61,valid_loss

还是大概0.68左右,没怎么往下降。但是看valid_dataset的效果,比昨天略好。

对于玻璃、镜面的效果比昨天的预测结果略好,下面的结果是disparities_pp

1

2

对于大片的天空还是预测错误。

2019年4月22日10:27:31

前两天发现opencv对于我手边这个非常渣的双目相机的标定结果并不是非常精确。。。

校正完了,再拿校正完的棋盘图片算内参,结果两个相机的内参差距有减少,但并

不是一模一样的。。。准备再拿matlab校正一次做对比。

monodepth效果不太好可能是opencv和相机校正的锅。。。

monodepth 训练记录的更多相关文章

  1. 台州学院maximum cow训练记录

    前队名太过晦气,故启用最大牛 我们的组队大概就是18年初,组队阵容是17级生詹志龙.陶源和16级的黄睿博. 三人大学前均无接触过此类竞赛,队伍十分年轻.我可能是我们队最菜的,我只是知道的内容最多,靠我 ...

  2. 【学习笔记&训练记录】数位DP

    数位DP,即对数位进行拆分,利用数位来转移的一种DP,一般采用记忆化搜索,或者是先预处理再进行转移 一个比较大略的思想就是可以对于给定的大数,进行按数位进行固定来转移记录答案 区间类型的,可以考虑前缀 ...

  3. MIT jos 6.828 Fall 2014 训练记录(lab 6)

    源代码参见我的github: https://github.com/YaoZengzeng/jos 在这个实验中将实现一个基于Intel 82540M(又称E1000)的网卡驱动.不过,一个网卡驱动还 ...

  4. MIT jos 6.828 Fall 2014 训练记录(lab 4)

    源代码参见我的github: https://github.com/YaoZengzeng/jos Part A: Multiprocessor Support and Cooperative Mul ...

  5. MIT jos 6.828 Fall 2014 训练记录(lab 2)

    注: 源代码参见我的github:https://github.com/YaoZengzeng/jos Part1 : Physical Page Management mem_init函数: /*该 ...

  6. MIT jos 6.828 Fall 2014 训练记录(lab 1)

    注: 源代码参见我的github:https://github.com/YaoZengzeng/jos Part 1: PC Bootstrap +------------------+ <- ...

  7. dp暑假专题 训练记录

    A 回文串的最小划分 题意:给出长度不超过1000的字符串,把它分割成若干个回文字串,求能分成的最少字串数. #include <iostream> #include <cstdio ...

  8. 2019年5月训练记录(更新ing)

    前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...

  9. 2019年5~6月训练记录(更新ing)

    前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...

随机推荐

  1. json&pickle模块

    序列化:我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化 反序列化:把变量内容从序列化的对象重新读到内存中,这一过程称为反序列化 为什么要序列化? 1.持久保存状态 一个软件的执行就是在处 ...

  2. zabbix AGENTS 在WINDOWS的安装

    1.下载 https://assets.zabbix.com/downloads/3.4.0/zabbix_agents_3.4.0.win.zip 解压 zabbix_agents_3.4.0.wi ...

  3. django_视图层_编写url

    URL的配置 django中,url也称urlconf,默认的django项目设定两个url地址,分别是admin站点管理和首页地址.from diango.urls import path,incl ...

  4. 前段时间碰到的一些问题(免费WiFi设置+fiddler对手机进行抓包+fiddler抓不到https的请求)

    这段时间转入移动端测试,对这块比较陌生,工作开展起来比较困难,所以好多东西都只是以解决问题为第一目标,没有去细细推敲其中原理,可能会有些语无伦次之感,但还是记一下当时解决问题的大致思路,供以后参考. ...

  5. python基础(九)

    一.私有 class DB: port = 3306 #类变量 def __init__(self): self.host = '127.0.0.1' self.__user = 'root' #实例 ...

  6. 小妖精的完美游戏教室——人工智能,A*算法,实现篇

    //================================================================//// Copyright (C) 2017 Team Saluk ...

  7. Java面试3

    反射的定义: 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取它所有的成员变量和方法并且显示出来. 反射机制的 ...

  8. HQL包含中文查询失败

    jdbc:mysql://172.16.9.6:3306/school?useUnicode=true&characterEncoding=UTF-8配置文件中的url加上编码,一般mysql ...

  9. DataGrip for Mac破解步骤详解 亲测好用

    https://blog.csdn.net/le945926/article/details/81912085

  10. Git 概念

    Git 概念 一.Git 工作流程 ~ Workspace:工作区 ~ Index/ Stage:暂存区 ~ Repository:仓库区(或本地仓库) ~ Remote:远程仓库 工作区 进行开发改 ...