【发布时间】:2019-07-24 17:35:51
【问题描述】:
我一直在尝试使用 opencv 将立体图像转换为深度图,但无论我做什么,它似乎都无法读取。
我能够获得 opencv 教程中提供的示例图像的准确深度图像,但在任何其他图像上都没有。即使我尝试从网上下载其他预制的、校准过的立体图像,我也得到了既不准确也不接近示例图像质量的糟糕结果。
这是我用来制作深度图的主要 Python 脚本:
import numpy as np
import cv2
from matplotlib import pyplot as plt
imgL = cv2.imread('calimg_L.png',0)
imgR = cv2.imread('calimg_R.png',0)
# imgL = cv2.imread('./images/example_L.png',0)
# imgR = cv2.imread('./images/example_R.png',0)
stereo = cv2.StereoSGBM_create(numDisparities=16, blockSize=15)
disparity = stereo.compute(imgR,imgL)
norm_image = cv2.normalize(disparity, None, alpha = 0, beta = 1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
cv2.imwrite("disparityImage.jpg", norm_image)
plt.imshow(norm_image)
plt.show()
其中 calimg_L.png 是原始图像的校准版本。
这是我用来校准图像的代码:
import numpy as np
import cv2
import glob
from matplotlib import pyplot as plt
def createCalibratedImage(inputImage, outputName):
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((3*3,3), np.float32)
objp[:,:2] = np.mgrid[0:3,0:3].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
# org = cv2.imread('./chess.jpg')
# orig_cal_img = cv2.resize(org, (384, 288))
# cv2.imwrite("cal_chess.jpg", orig_cal_img)
images = glob.glob('./chess_webcam/*.jpg')
for fname in images:
print('file in use: ' + fname)
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (3,3),None)
# print("doing the thing");
print('status: ' + str(ret));
# If found, add object points, image points (after refining them)
if ret == True:
# print("found something");
objpoints.append(objp)
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (3,3), corners,ret)
cv2.imshow('img',img)
cv2.waitKey(500)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
img = inputImage
h, w = img.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# undistort
print('undistorting...')
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(inputImage ,mapx,mapy,cv2.INTER_LINEAR)
# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
# cv2.imwrite('calibresult.png',dst)
cv2.imwrite(outputName + '.png',dst)
cv2.destroyAllWindows()
original_L = cv2.imread('capture_L.jpg')
original_R = cv2.imread('capture_R.jpg')
createCalibratedImage(original_R, "calimg_R")
createCalibratedImage(original_L, "calimg_L")
print("images calibrated and outputed")
此代码取自 opencv tutorial on how to calibrate images 并提供了至少 16 个棋盘图像,但只能识别其中大约 4 - 5 个棋盘。我使用相对较小的 3x3 网格搜索的原因是,由于无法找到棋盘,任何更高的东西都让我没有任何图像可用于校准。
这是我从示例图片中得到的(抱歉,奇怪的链接,找不到如何上传): https://ibb.co/DYMcdZc
这是原文: https://ibb.co/gMkqyXD https://ibb.co/YQZY40C
这是应该的,但是当我将它与任何其他图像一起使用时,它会让我一团糟,例如:
看起来只是一堆像素,公平地说,当您在 imshow 上将其设置为“灰色”时,它看起来更具可读性,但它并不能很好地代表图像的深度,以下是原件: https://ibb.co/vqDKGS0 https://ibb.co/f0X1gMB
更糟糕的是,当我自己拍摄图像并通过棋盘代码校准它们时,它会显示为白色和黑色像素的随机混乱,一些像素的值变成负数,而一些像素的值高得不可思议。
tl;dr 即使示例图像工作正常,我也无法将任何立体图像制作成深度图,这是为什么呢?
【问题讨论】:
标签: python opencv stereoscopy