OpenCV下的无标定校正(stereoRectifyUncalibrated)

2024-09-04 07:44

本文主要是介绍OpenCV下的无标定校正(stereoRectifyUncalibrated),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

OpenCV下的无标定校正(stereoRectifyUncalibrated)

文章目录

  • 1. 杂话
  • 2. 无标定校正
    • 2.1 先看代码
    • 2.2 一点解释
    • 2.3 findFundamentalMat参数
    • 2.4 stereoRectifyUncalibrated参数
  • 3. 矫正结果

1. 杂话

 咱们在之前的帖子里面讲了一些比较常规的标定和校正OpenCV下的单目标定,双目标定与立体校正(calibrateCamera, stereoCalibrate and stereoRectify),但是,如果说两个相机之间的转角比较大,那么可能并不适合用双目标定+立体校正的步骤来做,参考这个贴子立体校正失效的情况,所以为了解决这个问题,今天咱们就来说说如何使用非标定的校正函数:

 对了,我使用的数据和完整的代码在这里:Repo : Calibrate-and-Rectify

2. 无标定校正

2.1 先看代码

import cv2
import numpy as np
import glob
import matplotlib.pyplot as plt
from PIL import Imagec1_images_names = sorted(glob.glob('demo/left*.jpg'))
c2_images_names = sorted(glob.glob('demo/right*.jpg'))c1_images = []
c2_images = []
for im1, im2 in zip(c1_images_names, c2_images_names):_im = cv2.imread(im1, 1)c1_images.append(_im)_im = cv2.imread(im2, 1)c2_images.append(_im)def find_corners(image_names):images = []for imname in image_names:im = cv2.imread(imname, 1)images.append(im)criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)rows = 6 #number of checkerboard rows.columns = 9 #number of checkerboard columns.#coordinates of squares in the checkerboard world spaceobjp = np.zeros((rows*columns,3), np.float32)objp[:,:2] = np.mgrid[0:rows,0:columns].T.reshape(-1,2)#frame dimensions. Frames should be the same size.width = images[0].shape[1]height = images[0].shape[0]#Pixel coordinates of checkerboardsimgpoints = [] # 2d points in image plane.for frame in images:gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)gray = cv2.rotate(gray, cv2.ROTATE_90_CLOCKWISE)#find the checkerboardret, corners = cv2.findChessboardCorners(gray, (rows, columns), None)if ret == True:#Convolution size used to improve corner detection. Don't make this too large.conv_size = (11, 11)#opencv can attempt to improve the checkerboard coordinatescorners = cv2.cornerSubPix(gray, corners, conv_size, (-1, -1), criteria)imgpoints.append(corners)return imgpointsimgpoints1 = find_corners(c1_images_names)
imgpoints2 = find_corners(c2_images_names)# 将角点坐标转换为float32格式
points1all = np.array([pt.ravel() for pts in imgpoints1 for pt in pts], dtype=np.float32)
points2all = np.array([pt.ravel() for pts in imgpoints2 for pt in pts], dtype=np.float32)# 计算基础矩阵
F, mask = cv2.findFundamentalMat(points1all, points2all, cv2.FM_RANSAC)# 图像大小
img_size = (640, 480)img1 = cv2.imread('demo/left03.jpg', 1)
img2 = cv2.imread('demo/right03.jpg', 1)img1 = cv2.rotate(img1, cv2.ROTATE_90_CLOCKWISE)
img2 = cv2.rotate(img2, cv2.ROTATE_90_CLOCKWISE)gray_left = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# 找到棋盘格角点
ret_left, corners_left = cv2.findChessboardCorners(gray_left, (6, 9), None)
ret_right, corners_right = cv2.findChessboardCorners(gray_right, (6, 9), None)criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)print(ret_left, ret_right)if ret_left and ret_right:# 提高角点的精度corners_left = cv2.cornerSubPix(gray_left, corners_left, (11, 11), (-1, -1), criteria)corners_right = cv2.cornerSubPix(gray_right, corners_right, (11, 11), (-1, -1), criteria)# 将角点坐标转换为float32格式
points1 = np.array([pt[0] for pt in corners_left], dtype=np.float32).reshape(-1, 2)
points2 = np.array([pt[0] for pt in corners_right], dtype=np.float32).reshape(-1, 2)# 进行立体校正
retval, H1, H2 = cv2.stereoRectifyUncalibrated(points1, points2, F, img_size)# 裁剪图像去除黑边
def crop_image(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)x, y, w, h = cv2.boundingRect(contours[0])cropped_image = image[y:y+h, x:x+w]return cropped_imageif retval:# 计算校正映射img1_rectified = cv2.warpPerspective(img1, H1, img_size)img2_rectified = cv2.warpPerspective(img2, H2, img_size)# 显示校正后的图像cv2.imwrite('Rectified Image 1.png', img1_rectified)cv2.imwrite('Rectified Image 2.png', img2_rectified)
else:print("立体校正失败")plt.figure(figsize=(20, 20))for i in range(0,1):  # 以第一对图片为例im_L=Image.fromarray(img1_rectified) # numpy 转 image类im_R=Image.fromarray(img2_rectified) # numpy 转 image 类width = im_L.size[0]*2height = 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):len=480/20plt.axhline(y=i*len, color='r', linestyle='-')plt.imshow(img_compare)plt.savefig('epipolar_lines_ro.png', bbox_inches='tight', pad_inches=0)plt.show()

2.2 一点解释

 其实也没啥好解释的吧,一些基础的参数都在上面说的另外一篇帖子里面写好了。主要就是说一下思路,因为是标定图片,所以还是用角点做关键点,之后通过匹配的关键点和findFundamentalMat去计算基础矩阵,描述两个图片的映射关系。然后针对示例图片,应用这个映射,也就是stereoRectifyUncalibrated函数。

2.3 findFundamentalMat参数

 findFundamentalMat 是 OpenCV 中用于计算基础矩阵的函数。基础矩阵描述了两个图像之间的点对应关系,是立体视觉计算中的一个重要概念。以下是该函数的详细解释:

cv2.findFundamentalMat(points1, points2[, method[, ransacReprojThreshold[, confidence[, maxIters]]]]) -> fundamentalMatrix, mask输入参数
points1:
描述:在第一幅图像中检测到的特征点列表或数组。应该是 Nx2 的二维点坐标列表,其中 N 是特征点的数量。points2:
描述:在第二幅图像中检测到的特征点列表或数组。应该与 points1 中的点一一对应,且格式相同。method (可选):
描述:用于估算基础矩阵的方法。可以是以下之一:
cv2.FM_7POINT: 七点算法。要求点数量为 7。
cv2.FM_8POINT: 八点算法。要求点数量大于或等于 8。
cv2.FM_RANSAC: 使用 RANSAC 方法。推荐用于处理带有噪声的点。
cv2.FM_LMEDS: 使用最小中值平方算法。也用于处理带有噪声的点。ransacReprojThreshold (可选):
描述:RANSAC 算法中的最大重投影误差阈值,仅在使用 RANSAC 方法时有效。默认值为 3。confidence (可选):
描述:RANSAC 算法中的置信度,仅在使用 RANSAC 方法时有效。默认值为 0.99。maxIters (可选):
描述:RANSAC 算法的最大迭代次数,仅在使用 RANSAC 方法时有效。默认值为 1000。输出参数
fundamentalMatrix:
描述:计算得到的基础矩阵,大小为 3x3。mask:
描述:输出参数,用于标识内点(inliers)。大小为 Nx1 的二值数组,其中 N 是输入特征点的数量。值为 1 的元素表示对应的特征点是内点,值为 0 的元素表示对应的特征点是外点(outliers)。

2.4 stereoRectifyUncalibrated参数

cv2.stereoRectifyUncalibrated(points1, points2, F, imgSize[, H1[, H2[, threshold]]]) -> retval, H1, H2
输入参数points1:
描述:在左图中检测到的特征点列表或数组。应该是 Nx2 的二维点坐标列表,其中 N 是特征点的数量。points2:
描述:在右图中检测到的特征点列表或数组。应该与 points1 中的点一一对应,且格式相同。F:
描述:基础矩阵(3x3),它是在立体图像对之间通过特征点匹配估算得到的。imgSize:
描述:图像的尺寸,格式为 (width, height),即图像的宽度和高度。H1 (可选):
描述:输出参数,用于存储左图的 3x3 变换矩阵。如果提供了此参数,函数会将结果写入其中。H2 (可选):
描述:输出参数,用于存储右图的 3x3 变换矩阵。如果提供了此参数,函数会将结果写入其中。threshold (可选):
描述:用于 RANSAC 算法的阈值。RANSAC 算法用于估算变换矩阵时的容错范围。如果不提供,则使用默认值。输出参数
retval:
描述:函数执行成功与否的标志。返回 True 表示成功,返回 False 表示失败。H1:
描述:左图的 3x3 变换矩阵。只有在调用时提供了相应的参数,且函数执行成功时才会返回。H2:
描述:右图的 3x3 变换矩阵。只有在调用时提供了相应的参数,且函数执行成功时才会返回。

3. 矫正结果

在这里插入图片描述
 OK,基本符合预期哦~

这篇关于OpenCV下的无标定校正(stereoRectifyUncalibrated)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135413

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

树莓派5_opencv笔记27:Opencv录制视频(无声音)

今日继续学习树莓派5 8G:(Raspberry Pi,简称RPi或RasPi)  本人所用树莓派5 装载的系统与版本如下:  版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下: 今天就水一篇文章,用树莓派摄像头,Opencv录制一段视频保存在指定目录... 文章提供测试代码讲解,整体代码贴出、测试效果图 目录 阶段一:录制一段

Verybot之OpenCV应用三:色标跟踪

下面的这个应用主要完成的是Verybot跟踪色标的功能,识别部分还是居于OpenCV编写,色标跟踪一般需要将图像的颜色模式进行转换,将RGB转换为HSV,因为对HSV格式下的图像进行识别时受光线的影响比较小,但是也有采用RGB模式来进行识别的情况,这种情况一般光线条件比较固定,背景跟识别物在颜色上很容易区分出来。         下面这个程序的流程大致是这样的:

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

虚拟机ubuntu配置opencv和opencv_contrib

前期准备  1.下载opencv和opencv_contrib源码 opencv-4.6.0:https://opencv.org/releases/ opencv_contrib-4.6.0:https://github.com/opencv/opencv_contrib 在ubuntu直接下载或者在window上下好传到虚拟机里都可以 自己找个地方把他们解压,个人习惯在home下新建一

解析apollo纵向控制标定表程序

百度apollo采用标定表描述车辆速度、加速度与油门/刹车之间的关系。该表可使无人车根据当前车速与期望加速度得到合适的油门/刹车开合度。除了文献《Baidu Apollo Auto-Calibration System - An Industry-Level Data-Driven and Learning based Vehicle Longitude Dynamic Calibrating