python目标检测入门基础,目标检测 pytorch
墨初 知识笔记 139阅读
双目目标定
3D重建和测距通过双目目标定您可以确定两个摄像头之间的相对位置和朝向从而能够根据视差信息计算物体的深度进行三维重建和测距。姿态估计双目摄像头可以用于估计物体或相机的姿态这对于虚拟现实、增强现实和机器人导航等应用非常重要。畸变矫正

立体矫正
立体视觉立体矫正是用于双目或多目视觉系统的关键步骤可使两个摄像头的像素对应点在同一水平线上从而简化了立体视觉中的视差计算。深度感知立体矫正后您可以使用视差图来估计物体的深度这对于实现深度感知和3D重建非常重要。 二双目拍照代码#coding:utf-8import cv2import timeimport timeleft_camera cv2.VideoCapture(0)left_camera.set(cv2.CAP_PROP_FRAME_WIDTH,640)left_camera.set(cv2.CAP_PROP_FRAME_HEIGHT,480)right_camera cv2.VideoCapture(1)right_camera.set(cv2.CAP_PROP_FRAME_WIDTH,640)right_camera.set(cv2.CAP_PROP_FRAME_HEIGHT,480)path/home/song/pic/ #图片存储路径AUTO False # True自动拍照False则手动按s键拍照INTERVAL 0.0000005 # 调整自动拍照间隔cv2.namedWindow(left)cv2.namedWindow(right)cv2.moveWindow(left, 0, 0)counter 0utc time.time()folder /home/song/pic/ # 照片存储路径def shot(pos, frame): global counter timestr datetime.datetime.now() path folder pos _ str(counter) .jpg cv2.imwrite(path, frame) print(snapshot saved into: path)while True: ret, left_frame left_camera.read() ret, right_frame right_camera.read() 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 left_camera.release()right_camera.release()cv2.destroyWindow(left)cv2.destroyWindow(right)
三分别对左右目进行标定 在进行双目相机的标定之前需要先对左右目的单目摄像头进行单目标定。这是因为双目摄像头的标定需要知道每个摄像头的内部参数如相机矩阵、畸变系数以及相机之间的外部参数相对位置和朝向。这些参数是通过单目标定来获得的。

单目标定通常包括以下步骤
相机内参标定通过拍摄一个包含已知尺寸的标定板的图像然后使用相机标定算法来估计相机内参如焦距、主点坐标和畸变系数。
相机外参标定通过将相机放置在不同位置或拍摄不同方向的图像使用外参标定算法来估计相机的位置和朝向。这一步通常需要多幅图像以确定相机在三维空间中的位置和姿态。
畸变矫正使用内参标定得到的畸变系数来矫正图像以去除镜头畸变。
生成标定文件将内外参和畸变系数保存在标定文件中以便后续的双目标定使用。
一旦单目摄像头的内部参数、外部参数和畸变系数都已知就可以进行双目标定以确定双目摄像头之间的相对位置和朝向以及立体视觉中的标定参数。
#-*- coding:utf-8 -*-import numpy as npimport cv2import glob# 设置迭代终止条件criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)# 设置 object points, 形式为 (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)objp np.zeros((6*7,3), np.float32) #我用的是6×7的棋盘格可根据自己棋盘格自行修改相关参数objp[:,:2] np.mgrid[0:7,0:6].T.reshape(-1,2)# 用arrays存储所有图片的object points 和 image pointsobjpoints [] # 3d point in real world spaceimgpoints [] # 2d points in image plane.#用glob匹配文件夹/home/song/pic_1/right/下所有文件名含有“.jpg的图片images glob.glob(r/home/song/pic/right/*.jpg)for fname in images: img cv2.imread(fname) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 查找棋盘格角点 ret, corners cv2.findChessboardCorners(gray, (7,6), None) # 如果找到了就添加 object points, image points if ret True: objpoints.append(objp) corners2cv2.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria) imgpoints.append(corners) # 对角点连接画线加以展示 cv2.drawChessboardCorners(img, (7,6), corners2, ret) cv2.imshow(img, img) cv2.waitKey(500)cv2.destroyAllWindows()# 标定ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)print(mtx, dist)#对所有图片进行去畸变有两种方法实现分别为 undistort()和remap()images glob.glob(r/home/song/pic/right/*.jpg)for fname in images: prefixfname.split(/)[5] img cv2.imread(fname) h, w img.shape[:2] newcameramtx, roicv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h)) # # 使用 cv.undistort()进行畸变校正 # dst cv2.undistort(img, mtx, dist, None, newcameramtx) # # 对图片有效区域进行剪裁 # # x, y, w, h roi # # dst dst[y:yh, x:xw] # cv2.imwrite(/home/song/pic_1/undistort/prefix, dst) # 使用 remap() 函数进行校正 mapx, mapy cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w, h), 5) dst cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR) # 对图片有效区域进行剪裁 x, y, w, h roi dst dst[y:y h, x:x w] cv2.imwrite(/home/song/pic/undistort/prefix, dst)#重投影误差计算mean_error 0for i in range(len(objpoints)): imgpoints2, _ cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist) error cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2) mean_error errorprint(total error: , mean_error/len(objpoints))
四双目标定及其立体校正 #coding:utf-8import numpy as npimport cv2import matplotlib.pyplot as pltfrom PIL import Image# 设置迭代终止条件criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)criteria_stereo (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)# 设置 object points, 形式为 (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)objp np.zeros((6 * 7, 3), np.float32) #我用的是6×7的棋盘格可根据自己棋盘格自行修改相关参数objp[:, :2] np.mgrid[0:7, 0:6].T.reshape(-1, 2)# 用arrays存储所有图片的object points 和 image pointsobjpoints [] # 3d points in real world spaceimgpointsR [] # 2d points in image planeimgpointsL []# 本次实验采集里共计30组待标定图片依次读入进行以下操作for i in range(0,30): t str(i) ChessImaR cv2.imread(/home/song/pic/right_ t .jpg, 0) # 右视图 ChessImaL cv2.imread(/home/song/pic/left_ t .jpg, 0) # 左视图 retR, cornersR cv2.findChessboardCorners(ChessImaR,(7, 6), None) # 提取右图每一张图片的角点 retL, cornersL cv2.findChessboardCorners(ChessImaL,(7, 6), None) # # 提取左图每一张图片的角点 if (True retR) & (True retL): objpoints.append(objp) cv2.cornerSubPix(ChessImaR, cornersR, (11, 11), (-1, -1), criteria) # 亚像素精确化对粗提取的角点进行精确化 cv2.cornerSubPix(ChessImaL, cornersL, (11, 11), (-1, -1), criteria) # 亚像素精确化对粗提取的角点进行精确化 imgpointsR.append(cornersR) imgpointsL.append(cornersL)# 相机的单双目标定、及校正# 右侧相机单独标定retR, mtxR, distR, rvecsR, tvecsR cv2.calibrateCamera(objpoints,imgpointsR,ChessImaR.shape[::-1], None, None)# 获取新的相机矩阵后续传递给initUndistortRectifyMap以用remap生成映射关系hR, wR ChessImaR.shape[:2]OmtxR, roiR cv2.getOptimalNewCameraMatrix(mtxR, distR,(wR, hR), 1, (wR, hR))# 左侧相机单独标定retL, mtxL, distL, rvecsL, tvecsL cv2.calibrateCamera(objpoints,imgpointsL,ChessImaL.shape[::-1], None, None)# 获取新的相机矩阵后续传递给initUndistortRectifyMap以用remap生成映射关系hL, wL ChessImaL.shape[:2]OmtxL, roiL cv2.getOptimalNewCameraMatrix(mtxL, distL, (wL, hL), 1, (wL, hL))# 双目相机的标定# 设置标志位为cv2.CALIB_FIX_INTRINSIC这样就会固定输入的cameraMatrix和distCoeffs不变只求解,,,flags 0flags | cv2.CALIB_FIX_INTRINSICretS, MLS, dLS, MRS, dRS, R, T, E, F cv2.stereoCalibrate(objpoints,imgpointsL,imgpointsR,OmtxL,distL,OmtxR,distR, ChessImaR.shape[::-1], criteria_stereo,flags)# 利用stereoRectify()计算立体校正的映射矩阵rectify_scale 1 # 设置为0的话对图片进行剪裁设置为1则保留所有原图像像素RL, RR, PL, PR, Q, roiL, roiR cv2.stereoRectify(MLS, dLS, MRS, dRS, ChessImaR.shape[::-1], R, T, rectify_scale,(0,0)) # 利用initUndistortRectifyMap函数计算畸变矫正和立体校正的映射变换实现极线对齐。Left_Stereo_Map cv2.initUndistortRectifyMap(MLS, dLS, RL, PL, ChessImaR.shape[::-1], cv2.CV_16SC2) Right_Stereo_Map cv2.initUndistortRectifyMap(MRS, dRS, RR, PR, ChessImaR.shape[::-1], cv2.CV_16SC2)#立体校正效果显示for i in range(0,1): # 以第一对图片为例 t str(i) frameR cv2.imread(/home/song/pic/right_ t .jpg, 0) frameL cv2.imread(/home/song/pic/left_ t .jpg, 0) Left_rectified cv2.remap(frameL,Left_Stereo_Map[0],Left_Stereo_Map[1], cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0) # 使用remap函数完成映射 im_LImage.fromarray(Left_rectified) # numpy 转 image类 Right_rectified cv2.remap(frameR,Right_Stereo_Map[0],Right_Stereo_Map[1], cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0) im_RImage.fromarray(Right_rectified) # numpy 转 image 类#创建一个能同时并排放下两张图片的区域后把两张图片依次粘贴进去 width im_L.size[0]*2 height im_L.size[1] img_compare Image.new(RGBA,(width, height)) img_compare.paste(im_L,box(0,0)) img_compare.paste(im_R,box(640,0)) #在已经极线对齐的图片上均匀画线 for i in range(1,20): len480/20 plt.axhline(yi*len, colorr, linestyle-) plt.imshow(img_compare) plt.show()
五双目的具体应用 双目视觉是指通过两个摄像头或相机捕获的图像来模拟人类双眼视觉系统。它可以提供更多的深度信息和立体感因此在许多领域都有具体的应用。
以下是一些双目视觉的具体应用
三维重建通过双目摄像头捕获的图像可以使用立体视觉算法来重建场景的三维结构。这对于计算机辅助设计、虚拟现实、增强现实等领域非常有用。
物体检测与跟踪双目视觉可以提供更多的深度信息从而使得物体检测和跟踪更加准确和稳定。例如在自动驾驶中双目视觉可以用于检测和跟踪其他车辆、行人等。
深度感知通过双目视觉可以获取场景中物体的深度信息从而可以进行深度感知和距离测量。这在机器人导航、室内定位、无人机避障等领域非常有用。
姿态估计双目视觉可以用于估计物体或人体的姿态和运动。例如在人机交互中双目视觉可以用于手势识别和追踪。
立体匹配通过双目视觉可以进行立体匹配即将两个图像中对应的像素点进行匹配。这在计算机视觉中是一个重要的问题可以用于图像配准、目标识别等。
视觉SLAM双目视觉可以与同步定位与地图构建SLAM算法结合使用实现同时定位和地图构建。这在无人车、无人机等领域中非常重要。