python-opencv对极几何 StereoRectify
OpenCV如何正确使用stereoRectify函数
函数介绍
用于双目相机的立体校正环节中,这里只谈谈这个函数怎么使用,参数具体指哪些
函数参数
随便去网上一搜或者看官方手册就能得到参数信息,但是!!相对关系非常容易出错!!这里详细解释一下这些参数究竟怎么用
void stereoRectify(InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2,InputArray distCoeffs2, Size imageSize, InputArray R, InputArray T,OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags=CALIB_ZERO_DISPARITY, double alpha=-1, Size newImageSize=Size(), Rect* validPixROI1=0, Rect* validPixROI2=0 )
cameraMatrix1-第一个摄像机的摄像机矩阵,即左相机相机内参矩阵,矩阵第三行格式应该为 0 0 1
distCoeffs1-第一个摄像机的畸变向量
cameraMatrix2-第一个摄像机的摄像机矩阵,即右相机相机内参矩阵,矩阵第三行格式应该为 0 0 1
distCoeffs2-第二个摄像机的畸变向量
imageSize-图像大小
R- 相机之间的旋转矩阵,这里R的意义是:相机1通过变换R到达相机2的位姿
T- 左相机到右相机的平移矩阵
R1-输出矩阵,第一个摄像机的校正变换矩阵(旋转变换)
R2-输出矩阵,第二个摄像机的校正变换矩阵(旋转矩阵)
P1-输出矩阵,第一个摄像机在新坐标系下的投影矩阵
P2-输出矩阵,第二个摄像机在想坐标系下的投影矩阵
Q-4*4的深度差异映射矩阵
flags-可选的标志有两种零或者 CV_CALIB_ZERO_DISPARITY ,如果设置 CV_CALIB_ZERO_DISPARITY 的话,该函数会让两幅校正后的图像的主点有相同的像素坐标。否则该函数会水平或垂直的移动图像,以使得其有用的范围最大
alpha-拉伸参数。如果设置为负或忽略,将不进行拉伸。如果设置为0,那么校正后图像只有有效的部分会被显示(没有黑色的部分),如果设置为1,那么就会显示整个图像。设置为0~1之间的某个值,其效果也居于两者之间。
newImageSize-校正后的图像分辨率,默认为原分辨率大小。
validPixROI1-可选的输出参数,Rect型数据。其内部的所有像素都有效
validPixROI2-可选的输出参数,Rect型数据。其内部的所有像素都有效
opencv进行双目标定以及极线校正 python代码
双目标定
参考博客 OpenCV相机标定全过程
[OpenCV实战]38 基于OpenCV的相机标定
opencv立体标定函数 stereoCalibrate()
主要使用的函数
findChessboardCorners() #棋盘格角点检测
cornerSubPix() #亚像素检测
calibrateCamera() #单目标定 求解摄像机的内在参数和外在参数
stereoCalibrate() #双目标定 求解两个摄像头的内外参数矩阵,以及两个摄像头的位置关系R,T
代码
import cv2
import os
import numpy as npleftpath = 'images/left'
rightpath = 'images/right'
CHECKERBOARD = (11,12) #棋盘格内角点数
square_size = (30,30) #棋盘格大小,单位mm
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
imgpoints_l = [] #存放左图像坐标系下角点位置
imgpoints_r = [] #存放左图像坐标系下角点位置
objpoints = [] #存放世界坐标系下角点位置
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objp[0,:,0] *= square_size[0]
objp[0,:,1] *= square_size[1]for ii in os.listdir(leftpath):img_l = cv2.imread(os.path.join(leftpath,ii))gray_l = cv2.cvtColor(img_l,cv2.COLOR_BGR2GRAY)img_r = cv2.imread(os.path.join(rightpath,ii))gray_r = cv2.cvtColor(img_r,cv2.COLOR_BGR2GRAY)ret_l, corners_l = cv2.findChessboardCorners(gray_l, CHECKERBOARD) #检测棋盘格内角点ret_r, corners_r = cv2.findChessboardCorners(gray_r, CHECKERBOARD)if ret_l and ret_r:objpoints.append(objp)corners2_l = cv2.cornerSubPix(gray_l,corners_l,(11,11),(-1,-1),criteria) imgpoints_l.append(corners2_l)corners2_r = cv2.cornerSubPix(gray_r,corners_r,(11,11),(-1,-1),criteria)imgpoints_r.append(corners2_r)#img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2,ret)#cv2.imwrite('./ChessboardCornersimg.jpg', img)
ret, mtx_l, dist_l, rvecs_l, tvecs_l = cv2.calibrateCamera(objpoints, imgpoints_l, gray_l.shape[::-1],None,None) #先分别做单目标定
ret, mtx_r, dist_r, rvecs_r, tvecs_r = cv2.calibrateCamera(objpoints, imgpoints_r, gray_r.shape[::-1],None,None)retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = \cv2.stereoCalibrate(objpoints, imgpoints_l, imgpoints_r, mtx_l, dist_l, mtx_r, dist_r, gray_l.shape[::-1]) #再做双目标定print("stereoCalibrate : \n")
print("Camera matrix left : \n")
print(cameraMatrix1)
print("distCoeffs left : \n")
print(distCoeffs1)
print("cameraMatrix left : \n")
print(cameraMatrix2)
print("distCoeffs left : \n")
print(distCoeffs2)
print("R : \n")
print(R)
print("T : \n")
print(T)
print("E : \n")
print(E)
print("F : \n")
print(F)
将打印的结果保存到标定文件中即可
极线校正
参考博客 机器视觉学习笔记(8)——基于OpenCV的Bouguet立体校正
小白视角之Bouguet双目立体校正原理
主要使用的函数
stereoRectify() #计算旋转矩阵和投影矩阵
initUndistortRectifyMap() #计算校正查找映射表
remap() #重映射
代码
import cv2
import numpy as npdef cat2images(limg, rimg):HEIGHT = limg.shape[0]WIDTH = limg.shape[1]imgcat = np.zeros((HEIGHT, WIDTH*2+20,3))imgcat[:,:WIDTH,:] = limgimgcat[:,-WIDTH:,:] = rimgfor i in range(int(HEIGHT / 32)):imgcat[i*32,:,:] = 255 return imgcatleft_image = cv2.imread("images/left/268.jpg")
right_image = cv2.imread("images/right/268.jpg")imgcat_source = cat2images(left_image,right_image)
HEIGHT = left_image.shape[0]
WIDTH = left_image.shape[1]
cv2.imwrite('imgcat_source.jpg', imgcat_source )camera_matrix0 = np.array([[1.30991855e+03, 0.00000000e+00, 5.90463086e+02],[0.00000000e+00, 1.31136722e+03, 3.33464608e+02],[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) .reshape((3,3)) #即上文标定得到的 cameraMatrix1distortion0 = np.array([-4.88890701e-01, 3.27964225e-01, -2.72130825e-04, 1.28030208e-03, -1.85964828e-01]) #即上文标定得到的 distCoeffs1camera_matrix1 = np.array([[1.30057467e+03, 0.00000000e+00, 6.28445749e+02],[0.00000000e+00, 1.30026325e+03, 3.90475091e+02],[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) .reshape((3,3)) #即上文标定得到的 cameraMatrix2
distortion1 = np.array([-4.95938411e-01, 2.70207629e-01, 1.81014753e-04, -4.58891345e-04, 4.41327829e-01]) #即上文标定得到的 distCoeffs2R = np.array([[ 0.99989348, 0.01340678, -0.00576869], [-0.01338004, 0.99989967, 0.00465071], [ 0.00583046, -0.00457303, 0.99997255]]) #即上文标定得到的 R
T = np.array([-244.28272039, 3.84124178, 2.0963191]) #即上文标定得到的T(R_l, R_r, P_l, P_r, Q, validPixROI1, validPixROI2) = \cv2.stereoRectify(camera_matrix0, distortion0, camera_matrix1, distortion1, np.array([WIDTH,HEIGHT]), R, T) #计算旋转矩阵和投影矩阵(map1, map2) = \cv2.initUndistortRectifyMap(camera_matrix0, distortion0, R_l, P_l, np.array([WIDTH,HEIGHT]), cv2.CV_32FC1) #计算校正查找映射表rect_left_image = cv2.remap(left_image, map1, map2, cv2.INTER_CUBIC) #重映射#左右图需要分别计算校正查找映射表以及重映射
(map1, map2) = \cv2.initUndistortRectifyMap(camera_matrix1, distortion1, R_r, P_r, np.array([WIDTH,HEIGHT]), cv2.CV_32FC1)rect_right_image = cv2.remap(right_image, map1, map2, cv2.INTER_CUBIC)imgcat_out = cat2images(rect_left_image,rect_right_image)
cv2.imwrite('imgcat_out.jpg', imgcat_out)
效果图
校正前
左图
右图
校正后
相关文章:

python-opencv对极几何 StereoRectify
OpenCV如何正确使用stereoRectify函数 函数介绍 用于双目相机的立体校正环节中,这里只谈谈这个函数怎么使用,参数具体指哪些函数参数 随便去网上一搜或者看官方手册就能得到参数信息,但是!!相对关系非常容易出错&…...

pom文件---maven
027-Maven 命令行-实验四-生成 Web 工程-执行生成_ev_哔哩哔哩_bilibili 27节.后续补充 一.maven下载安装及配置 1)maven下载 2) settings文件配置本地仓库 3)settings配置远程仓库地址 4)配置maven工程的基础JDK版本 5)确认JDK环境变量配置没问题,配置maven的环境变量 验证…...
界面控件DevExpress.Drawing图形库早期增强功能分享
众所周知,DevExpress在v22.2发布周期中引入了全新的DevExpress.Drawing图形库(并且已经在随后的小更新中引入了一系列增强功能)。 在这篇博文中,我们将总结在DevExpress v23.1中解决的一些问题,以及在EAP构建中为以下…...

Semantic Kernel 入门系列:Connector连接器
当我们使用Native Function的时候,除了处理一些基本的逻辑操作之外,更多的还是需要进行外部数据源和服务的对接,要么是获取相关的数据,要么是保存输出结果。这一过程在Semantic Kernel中可以被归类为Connector。 Connector更像是…...

Maven介绍-下载-安装-使用-基础知识
Maven介绍-下载-安装-使用-基础知识 Maven的进阶高级用法可查看这篇文章: Maven分模块-继承-聚合-私服的高级用法 文章目录 Maven介绍-下载-安装-使用-基础知识01. Maven1.1 初识Maven1.1.1 什么是Maven1.1.2 Maven的作用 02. Maven概述2.1 Maven介绍2.2 Maven模型…...

Ansible环境搭建,CentOS 系列操作系统搭建Ansible集群环境
Ansible是一种自动化工具,基于Python写的,原理什么的就不过多再说了,详情参考:https://www.itwk.cc/post/403.html https://blog.csdn.net/qq_34185638/article/details/131079320?spm1001.2014.3001.5502 环境准备 HOSTNAMEIP…...

Django基础
1.Django基础 路由系统视图模板静态文件和媒体文件中间件ORM(时间) 2.路由系统 本质上:URL和函数的对应关系。 2.1 传统的路由 from django.contrib import admin from django.urls import path from apps.web import viewsurlpatterns …...

HTML,url,unicode编码
目录标题 HTML实体编码urlcode编码unicode编码小结基础例题高级例题 HTML实体编码 实体表示: 以&符号开始,后面跟着一个预定义的实体的名称,或是一个#符号以及字符的十进制数字。 例: <p>hello</p> <!-- 等同…...
Hbase-热点问题(数据存储倾斜问题)
1. 危害 某一台regionserver消耗过多,承受过多的并发量,时间长机器性能下降,甚至宕机 2. 解决 可以通过设计rowkey预分区的方法解决 比如可以预分区120个,1月的数据存到1-10分区,每个月的数据存到10个分区ÿ…...

一个基于Java线程池管理的开源框架Hippo4j实践
线程池痛点 线程池是一种基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。线程池常见痛点: 线程池随便定义&…...
源码解析Flink源节点数据读取是如何与checkpoint串行执行
文章目录 源码解析Flink源节点数据读取是如何与checkpoint串行执行Checkpoint阶段StreamTask类变量actionExecutor的实现和初始化小结 数据读取阶段小结 总结 源码解析Flink源节点数据读取是如何与checkpoint串行执行 Flink版本:1.13.6 前置知识:源节点…...

进阶:Docker容器管理工具——Docker-Compose使用
文章目录 前言Compose大杀器编排服务 1、docker-compose安装curl方式安装增加可执行权限查看版本 2、Docker-compose.yaml命令3、 docker-compose实战4、Docker网络路由docker的跨主机网络路由**问题由来**:方案两台机分别配置路由表ip_forward配置 总结 前言 容器的管理工具&…...

策略模式(Strategy)
策略模式是一种行为设计模式,就是定义一系列算法,然后将每一个算法封装起来,并使它们可相互替换。本模式通过定义一组可相互替换的算法,实现将算法独立于使用它的用户而变化。 Strategy is a behavioral design pattern that def…...

webpack基础知识十:与webpack类似的工具还有哪些?区别?
一、模块化工具 模块化是一种处理复杂系统分解为更好的可管理模块的方式 可以用来分割,组织和打包应用。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体(bundle) 在前端领域中,并非只有webpack这一款…...

分享kubernetes部署:基于Ansible自动安装kubernetes
基于Ansible自动安装kubernetes 环境准备 我们以如下机器环境为例: 开放端口: 控制平面节点 工作节点 请按如上中规定的开放端口,或关闭防火墙: systemctlstopfirewalld&&\ systemctldisablefirewalld 安装常用工具 sudo…...

【Kubernetes部署篇】基于Ubuntu20.04操作系统搭建K8S1.23版本集群
文章目录 一、集群架构规划信息二、系统初始化准备(所有节点同步操作)三、安装kubeadm(所有节点同步操作)四、初始化K8S集群(master节点操作)五、添加Node节点到K8S集群中六、安装Calico网络插件七、测试CoreDNS可用性 一、集群架构规划信息 pod网段:10.244.0.0/16…...

c++--二叉树应用
1.根据二叉树创建字符串 力扣 给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。 空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符…...

以太网DHCP协议(十)
目录 一、工作原理 二、DHCP报文 2.1 DHCP报文类型 2.2 DHCP报文格式 当网络内部的主机设备数量过多是,IP地址的手动设置是一件非常繁琐的事情。为了实现自动设置IP地址、统一管理IP地址分配,TCPIP协议栈中引入了DHCP协议。 一、工作原理 使用DHCP之…...

企业服务器器中了360后缀勒索病毒怎么解决,勒索病毒解密数据恢复
随着网络威胁的增加,企业服务器成为黑客攻击的目标之一。近期,上海某知名律师事务所的数据库遭到了360后缀的勒索病毒攻击,导致企业服务器内的数据库被360后缀勒索病毒加密。许多重要的数据被锁定无法正常读取,严重影响了企业的正…...

详解Kafka分区机制原理|Kafka 系列 二
Kafka 系列第二篇,详解分区机制原理。为了不错过更新,请大家将本号“设为星标”。 点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达 上一篇文章介绍了 Kafka 的基本概念和术语,里面有个概念是 分区(Part…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
flow_controllers
关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...

边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...

Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...