我的数据,彩色和灰度是翻转的,所以filp
手动选四个点:
# coding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
def showimg(dst, name):
plt.figure()
plt.title(name)
plt.imshow(dst)
plt.show()
depImg = cv2.imread("./OtherSampleFrame_IMG_DepthMap.tif", -1)
grayImg = cv2.imread("./OtherSampleFrame_IMG_Texture_8Bit.png", -1)
rgbImg = cv2.imread("./Rgb.jpg", -1)
rgbImgNew=np.flip(rgbImg).copy()
showimg(depImg, "depImg")
showimg(grayImg, "grayImg")
showimg(rgbImg, "rgbImg")
showimg(rgbImgNew, "rgbImgNew")
depH, depW = depImg.shape[:2]
grayH, grayW = grayImg.shape[:2]
rgbH, rgbW = rgbImg.shape[:2]
#彩图
p1 = [[709.1, 205.8], [709.4, 224.4], [635.7, 205.9], [635.5, 224.5]]
#灰度图
p2 = [[841.0, 546.1], [841.5, 567.1], [771.4, 546.4], [771.4, 566.9]]
rgbImgNewVis = rgbImgNew.copy()
point_size = 1
point_color = (0, 0, 255)
thickness = 2
for point in p1:
cv2.circle(rgbImgNewVis, (int(point[0]), int(point[1])), point_size, point_color, thickness)
showimg(rgbImgNewVis, "rgbImgNewVis")
grayImgVis = grayImg.copy()
for point in p2:
cv2.circle(grayImgVis, (int(point[0]), int(point[1])), point_size, point_color, thickness)
showimg(grayImgVis, "grayImgVis")
h1, w1 = rgbImgNew.shape[:2]
h2, w2 = grayImg.shape[:2]
vis = np.zeros((max(h1, h2), w1 + w2, 3), np.uint8)
vis[:h1, :w1] = rgbImgNew
vis[:h2, w1:w1 + w2] = grayImg
green = (0, 255, 0)
for (x1, y1), (x2, y2) in zip(p1, p2):
col = green
r = 1
thickness = 2
cv2.line(vis, (int(x1), int(y1)), (int(x2+w2), int(y2)), col, thickness)
showimg(vis, "vis")
p1_array = np.array(p1)
p2_array = np.array(p2)
H, status = cv2.findHomography(p1_array, p2_array, cv2.RANSAC)
H_inv = np.linalg.inv(H)
result = cv2.warpPerspective(rgbImgNew, H, (grayW, grayH))
showimg(result, "result")
cv2.imwrite("result.png", result)
vresultImg = np.vstack((grayImg, result))
hresultImg = np.hstack((grayImg, result))
cv2.imwrite("vresultImg.png", vresultImg)
cv2.imwrite("hresultImg.png", hresultImg)
通过棋盘格对齐:
gray和rgb都采集到了棋盘格
我的棋盘格是8*11的
这种方法不求内参,不需要棋盘格的真实长度
# coding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
def showimg(dst, name):
plt.figure()
plt.title(name)
plt.imshow(dst)
plt.show()
#H W C 彩色图像
LeftImg = cv2.imread("./R1/ex2/OtherSampleFrame_IMG_Rgb.jpg", -1)
#H W C 三通道的灰度图
RightImg = cv2.imread("./R1/ex2/OtherSampleFrame_IMG_Texture_8Bit.png", -1)
LeftImgNew=np.flip(LeftImg).copy()
#flip 会把读入的bgr图像,转换乘rgb图像,那么等会儿的cvtColor,其实是rgb去做这个函数了,为了统一,我们把他弄回BGR
LeftImgNew = cv2.cvtColor(LeftImgNew,cv2.COLOR_RGB2BGR)
showimg(RightImg, "grayImg")
showimg(LeftImgNew, "rgbImgNew")
LeftImgNewgray = cv2.cvtColor(LeftImgNew,cv2.COLOR_BGR2GRAY)
RightImggray = cv2.cvtColor(RightImg,cv2.COLOR_BGR2GRAY)
LeftH, LeftW = LeftImg.shape[:2]
RightH, RightW = RightImg.shape[:2]
LeftImgNewH, LeftImgNewW = LeftImgNew.shape[:2]
patternSize = (9,9)
cornersLeft = None
cornersRight = None
#flag
#CALIB_CB_ADAPTIVE_THRESH 使用自适应阈值处理将图像转换为黑白图像,而不是固定的阈值水平(根据平均图像亮度计算)
#CALIB_CB_NORMALIZE_IMAGE 在应用固定或自适应阈值设置之前,使用equalizeHist对图像伽玛进行归一化。
#CALIB_CB_FILTER_QUADS 使用其他条件(如轮廓区域,周长,正方形)来过滤在轮廓检索阶段提取的假四边形。
#CALIB_CB_FAST_CHECK 对查找棋盘角的图像进行快速检查,如果未找到,则将调用快捷。当未观察到棋盘时,这可以大大降低退化状态下的通话速度。
test = 0
if test == 0:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH)
else:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
if (retLeft and retRight):
SubPix = 1
if SubPix:
img1 = cv2.drawChessboardCorners(LeftImgNew.copy(), patternSize, cornersLeft, retLeft)
cv2.imwrite("./R1/LeftResult.png", img1)
cornersSubPix1 = cv2.cornerSubPix(LeftImgNewgray, cornersLeft, (11, 11), (-1, -1), criteria)
img1_ = cv2.drawChessboardCorners(LeftImgNew.copy(), patternSize, cornersSubPix1, retLeft)
cv2.imwrite("./R1/LeftSubPixResult.png", img1_)
img2 = cv2.drawChessboardCorners(RightImg.copy(), patternSize, cornersRight, retLeft)
cv2.imwrite("./R1/RightResult.png", img2)
cornersSubPix2 = cv2.cornerSubPix(RightImggray, cornersRight, (11, 11), (-1, -1), criteria)
img2_ = cv2.drawChessboardCorners(RightImg.copy(), patternSize, cornersSubPix2, retRight)
cv2.imwrite("./R1/RightSubPixResult.png", img2_)
else:
cornersSubPix1 = cornersLeft
cornersSubPix2 = cornersRight
img1 = cv2.drawChessboardCorners(LeftImgNew, patternSize, cornersSubPix1, retLeft)
img2 = cv2.drawChessboardCorners(RightImg, patternSize, cornersSubPix2, retRight)
cv2.imwrite("./R1/LeftResult.png", img1)
cv2.imwrite("./R1/RightResult.png", img2)
#method为None,那么就使用全部的点
H, status = cv2.findHomography(cornersSubPix1, cornersSubPix2)
result = cv2.warpPerspective(LeftImgNew, H, (RightW, RightH))
showimg(result, "result")
cv2.imwrite("./R1/result.png", result)
#
vresultImg = np.vstack((RightImg, result))
hresultImg = np.hstack((RightImg, result))
cv2.imwrite("./R1/vresultImg.png", vresultImg)
cv2.imwrite("./R1/hresultImg.png", hresultImg)
#计算对齐误差
grayResult = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY).copy()
cornersLeftAlign = None
retLeftAlign, cornersLeftAlign = cv2.findChessboardCorners(grayResult, patternSize, cornersLeftAlign,
cv2.CALIB_CB_ADAPTIVE_THRESH)
if retLeftAlign:
cornersSubPix1Align = cv2.cornerSubPix(grayResult, cornersLeftAlign, (11, 11), (-1, -1), criteria)
devs = len(cornersSubPix1Align)
deviationX = 0
deviationY = 0
deviationXY = 0
for dev in range(devs):
coordinate1 = cornersSubPix1Align[dev][0]
coordinate2 = cornersSubPix2[dev][0]
deviationX += abs(coordinate2[0] - coordinate1[0])
deviationY += abs(coordinate2[1] - coordinate1[1])
deviationXY += (abs(coordinate2[0] - coordinate1[0]) + abs(coordinate2[1] - coordinate1[1]))
print("deviationX", deviationX)
print("deviationY", deviationY)
print("deviationXY", deviationXY)
else:
print("棋盘格检测有问题")
多个棋盘格图像。合并生成H:
# coding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
import json
def showimg(dst, name):
plt.figure()
plt.title(name)
plt.imshow(dst)
plt.show()
def mkdir(path):
import os
isExists = os.path.exists(path)
if not isExists:
os.makedirs(path)
import os
def searchCheckerboardDirFile(rootDir, garyimglist, rgbimglist, namelist, bboxflag):
for dir_or_file in os.listdir(rootDir):
filePath = os.path.join(rootDir, dir_or_file)
# 判断是否为文件
if os.path.isfile(filePath):
# 如果是文件再判断是否以.jpg结尾,不是则跳过本次循环
if bboxflag in filePath:
if os.path.basename(filePath).endswith('.png'):
if os.path.exists(filePath.replace("_IMG_Texture_8Bit.png", "_IMG_DepthMap.tif")):
nameTemp = filePath.split('/')[-1]
tempPath = filePath.split(nameTemp)[0]
tempName = tempPath.split('/')[-2]
garyimglist.append(os.path.join(tempPath, "OtherSampleFrame_IMG_Texture_8Bit.png"))
rgbimglist.append(os.path.join(tempPath, "OtherSampleFrame_IMG_Rgb.jpg"))
namelist.append(tempName)
else:
continue
# 如果是个dir,则再次调用此函数,传入当前目录,递归处理。
elif os.path.isdir(filePath):
searchCheckerboardDirFile(filePath, garyimglist, rgbimglist, namelist, bboxflag)
else:
print('not file and dir '+os.path.basename(filePath))
return garyimglist,rgbimglist, namelist
R1path = "/home/spple/paddle/vis-project/mmdetection/mmdetection/save_ply/N0001/标定板/R1"
R1garyimglist = []
R1rgbimglist = []
R1namelist = []
R1garyimglist, rgbimglist, R1namelist = searchCheckerboardDirFile(R1path, R1garyimglist, R1rgbimglist, R1namelist, "-R1-")
cornersSubPix1 = []
cornersSubPix2 = []
for exR1 in range(len(R1garyimglist)):
print(exR1, "/", len(R1garyimglist), "\n")
grayTemp = cv2.imread(R1garyimglist[exR1], -1)
GRAYH, GRAYW = grayTemp.shape[:2]
rgb = cv2.imread(rgbimglist[exR1], -1)
fliprgb = np.flip(rgb).copy()
# flip 会把读入的bgr图像,转换乘rgb图像,那么等会儿的cvtColor,其实是rgb去做这个函数了,为了统一,我们把他弄回BGR
fliprgb = cv2.cvtColor(fliprgb, cv2.COLOR_RGB2BGR)
LeftImgNewgray = cv2.cvtColor(fliprgb, cv2.COLOR_BGR2GRAY)
RightImggray = cv2.cvtColor(grayTemp, cv2.COLOR_BGR2GRAY)
patternSize = (9, 9)
cornersLeft = None
cornersRight = None
test = 0
if test == 0:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH)
else:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
if (retLeft and retRight):
SubPix = 1
if SubPix:
img1 = cv2.drawChessboardCorners(LeftImgNewgray.copy(), patternSize, cornersLeft, retLeft)
cv2.imwrite("./R1/"+R1namelist[exR1]+"LeftResult.png", img1)
cornersSubPix1 = cv2.cornerSubPix(LeftImgNewgray, cornersLeft, (11, 11), (-1, -1), criteria)
img1_ = cv2.drawChessboardCorners(LeftImgNewgray.copy(), patternSize, cornersSubPix1, retLeft)
cv2.imwrite("./R1/"+R1namelist[exR1]+"LeftSubPixResult.png", img1_)
img2 = cv2.drawChessboardCorners(RightImggray.copy(), patternSize, cornersRight, retLeft)
cv2.imwrite("./R1/"+R1namelist[exR1]+"RightResult.png", img2)
cornersSubPix2 = cv2.cornerSubPix(RightImggray, cornersRight, (11, 11), (-1, -1), criteria)
img2_ = cv2.drawChessboardCorners(RightImggray.copy(), patternSize, cornersSubPix2, retRight)
cv2.imwrite("./R1/"+R1namelist[exR1]+"RightSubPixResult.png", img2_)
else:
cornersSubPix1.extend(cornersLeft)
cornersSubPix2.extend(cornersRight)
else:
print("棋盘格检测有问题")
print(R1namelist[exR1])
continue
#N0405-R1-P003-C003-I003HSRhresultImg.png
H, status = cv2.findHomography(np.asarray(cornersSubPix1), np.asarray(cornersSubPix2))
获得内参和外参进行矫正
# coding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
import json
import os
def showimg(dst, name):
plt.figure()
plt.title(name)
plt.imshow(dst)
plt.show()
def mkdir(path):
import os
isExists = os.path.exists(path)
if not isExists:
os.makedirs(path)
def searchCheckerboardDirFile(rootDir, garyimglist, rgbimglist, namelist, bboxflag):
for dir_or_file in os.listdir(rootDir):
filePath = os.path.join(rootDir, dir_or_file)
# 判断是否为文件
if os.path.isfile(filePath):
# 如果是文件再判断是否以.jpg结尾,不是则跳过本次循环
if bboxflag in filePath:
if os.path.basename(filePath).endswith('.png'):
if os.path.exists(filePath.replace("_IMG_Texture_8Bit.png", "_IMG_DepthMap.tif")):
nameTemp = filePath.split('/')[-1]
tempPath = filePath.split(nameTemp)[0]
tempName = tempPath.split('/')[-2]
garyimglist.append(os.path.join(tempPath, "OtherSampleFrame_IMG_Texture_8Bit.png"))
rgbimglist.append(os.path.join(tempPath, "OtherSampleFrame_IMG_Rgb.jpg"))
namelist.append(tempName)
else:
continue
# 如果是个dir,则再次调用此函数,传入当前目录,递归处理。
elif os.path.isdir(filePath):
searchCheckerboardDirFile(filePath, garyimglist, rgbimglist, namelist, bboxflag)
else:
print('not file and dir '+os.path.basename(filePath))
return garyimglist,rgbimglist, namelist
#遍历拿到所有的棋盘格图像
R1path = "/home/spple/paddle/vis-project/mmdetection/mmdetection/save_ply/N0001/标定板/R1"
R1garyimglist = []
R1rgbimglist = []
R1namelist = []
R1garyimglist, rgbimglist, R1namelist = searchCheckerboardDirFile(R1path, R1garyimglist, R1rgbimglist, R1namelist, "-R1-")
patternSize = (9, 9)
patternH = 9
patternW = 9
# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵,认为在棋盘格这个平面上Z=0
objp = np.zeros((patternW*patternH,3), np.float32) #构造0矩阵,81行3列,用于存放角点的世界坐标
objp[:,:2] = np.mgrid[0:patternW,0:patternH].T.reshape(-1,2)# 三维网格坐标划
#棋盘格在真实世界的大小 20mm
patternDistance = 30
objp = objp * patternDistance
# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点
#内参-外参-畸变系数
#我的设备中,只有RGB需要矫正,gray已经被设备矫正了
for exR1 in range(len(R1garyimglist)):
rgb = cv2.imread(rgbimglist[exR1], -1)
fliprgb = np.flip(rgb).copy()
# flip 会把读入的bgr图像,转换乘rgb图像,那么等会儿的cvtColor,其实是rgb去做这个函数了,为了统一,我们把他弄回BGR
fliprgb = cv2.cvtColor(fliprgb, cv2.COLOR_RGB2BGR)
rgb2grayImg = cv2.cvtColor(fliprgb, cv2.COLOR_BGR2GRAY)
patternSize = (9, 9)
cornersLeft = None
retLeft, cornersLeft = cv2.findChessboardCorners(rgb2grayImg, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
if retLeft == True:
cornersLeft = cv2.cornerSubPix(rgb2grayImg, cornersLeft, (11, 11), (-1, -1), criteria)
objpoints.append(objp)
imgpoints.append(cornersLeft)
#dist 摄像机的5个畸变系数:k1,k2,p1,p2,k3
#https://stackoverflow.com/questions/57477747/how-to-fix-typeerror-function-takes-exactly-2-arguments-3-given-in-cv2-cali
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, rgb2grayImg.shape[::-1], None, None)
class LensDistortion(object):
def __init__(self, coeffs={}):
self._coeffs = coeffs
self.mapx, self.mapy = None, None
self.newCameraMatrix = None
def setCameraParams(self, fx, fy, cx, cy, k1, k2, p1, p2, k3):
c = self._coeffs['cameraMatrix'] = np.zeros(shape=(3, 3))
c[0, 0] = fx
c[1, 1] = fy
c[0, 2] = cx
c[1, 2] = cy
c[2, 2] = 1
self._coeffs['distortionCoeffs'] = np.array([[k1, k2, p1, p2, k3]])
def getUndistortRectifyMap(self, imgWidth, imgHeight):
if self.mapx is not None and self.mapx.shape == (imgHeight, imgWidth):
return self.mapx, self.mapy
cam = self._coeffs['cameraMatrix']
d = self._coeffs['distortionCoeffs']
#网上有人使用 cv2.undistort
#Opencv文档里说undistort()函数就是initundistortrectifymap()函数和remap()函数的简单组合。
(newCameraMatrix, self.roi) = cv2.getOptimalNewCameraMatrix(cam,
d, (imgWidth,
imgHeight), 1,
(imgWidth, imgHeight))
self.newCameraMatrix = newCameraMatrix
self.mapx, self.mapy = cv2.initUndistortRectifyMap(cam,
d, None, newCameraMatrix,
(imgWidth, imgHeight), cv2.CV_32FC1)
return self.mapx, self.mapy
def getDistortRectifyMap(self, sizex, sizey):
posy, posx = np.mgrid[0:sizey, 0:sizex].astype(np.float32)
mapx, mapy = self.getUndistortRectifyMap(sizex, sizey)
dx = posx - mapx
dy = posy - mapy
posx += dx
posy += dy
return posx, posy
def distortImage(self, image):
(imgHeight, imgWidth) = image.shape[:2]
mapx, mapy = self.getDistortRectifyMap(imgWidth, imgHeight)
return cv2.remap(image, mapx, mapy, cv2.INTER_LINEAR,
borderValue=(0, 0, 0))
#畸变矫正,计算H矩阵
LD = LensDistortion()
#fx, fy, cx, cy, k1, k2, k3, p1, p2
LD.setCameraParams(mtx[0,0], mtx[1,1], mtx[0,2], mtx[1,2], dist[0,0], dist[0,1], dist[0,2], dist[0,3], dist[0,4])
cornersSubPix1 = []
cornersSubPix2 = []
for exR1 in range(len(R1garyimglist)):
print(exR1, "/", len(R1garyimglist), "\n")
grayTemp = cv2.imread(R1garyimglist[exR1], -1)
GRAYH, GRAYW = grayTemp.shape[:2]
rgb = cv2.imread(rgbimglist[exR1], -1)
fliprgb = np.flip(rgb).copy()
# flip 会把读入的bgr图像,转换乘rgb图像,那么等会儿的cvtColor,其实是rgb去做这个函数了,为了统一,我们把他弄回BGR
fliprgb = cv2.cvtColor(fliprgb, cv2.COLOR_RGB2BGR)
#图像矫正
rgbNew = LD.distortImage(fliprgb).copy()
LeftImgNewgray = cv2.cvtColor(rgbNew, cv2.COLOR_BGR2GRAY)
RightImggray = cv2.cvtColor(grayTemp, cv2.COLOR_BGR2GRAY)
patternSize = (9, 9)
cornersLeft = None
cornersRight = None
test = 0
if test == 0:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH)
else:
retLeft, cornersLeft = cv2.findChessboardCorners(LeftImgNewgray, patternSize, cornersLeft,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
retRight, cornersRight = cv2.findChessboardCorners(RightImggray, patternSize, cornersRight,
cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
if (retLeft and retRight):
SubPix = 1
if SubPix:
img1 = cv2.drawChessboardCorners(LeftImgNewgray.copy(), patternSize, cornersLeft, retLeft)
cv2.imwrite("./R1/" + R1namelist[exR1] + "LeftResult.png", img1)
cornersSubPix1 = cv2.cornerSubPix(LeftImgNewgray, cornersLeft, (11, 11), (-1, -1), criteria)
img1_ = cv2.drawChessboardCorners(LeftImgNewgray.copy(), patternSize, cornersSubPix1, retLeft)
cv2.imwrite("./R1/" + R1namelist[exR1] + "LeftSubPixResult.png", img1_)
img2 = cv2.drawChessboardCorners(RightImggray.copy(), patternSize, cornersRight, retLeft)
cv2.imwrite("./R1/" + R1namelist[exR1] + "RightResult.png", img2)
cornersSubPix2 = cv2.cornerSubPix(RightImggray, cornersRight, (11, 11), (-1, -1), criteria)
img2_ = cv2.drawChessboardCorners(RightImggray.copy(), patternSize, cornersSubPix2, retRight)
cv2.imwrite("./R1/" + R1namelist[exR1] + "RightSubPixResult.png", img2_)
else:
cornersSubPix1.extend(cornersLeft)
cornersSubPix2.extend(cornersRight)
else:
print("棋盘格检测有问题")
print(R1namelist[exR1])
continue
# N0405-R1-P003-C003-I003HSRhresultImg.png
H, status = cv2.findHomography(np.asarray(cornersSubPix1), np.asarray(cornersSubPix2))
参考:
https://blog.csdn.net/wi162yyxq/article/details/69390006
对齐的原理:
深度图上的2D点转换到世界坐标的3D点,世界坐标的3D点再投影到彩色图像上