【双目视觉】双目立体匹配

article/2025/10/9 18:41:37

一、双目立体匹配算法

在opencv中用的比较多的双目立体匹配算法有两种:BM和SGBM。SGBM是BM立体匹配算法的优化版,属于半全局匹配,相对于BM花的时间要更多,但效果优于BM。本文使用的是SGBM半全局匹配方式。
步骤:
1.打开相机,获取到左目和右目的图像;
2.矫正畸变;
3.图像灰度化;
4.立体匹配,输出结果。

代码步骤

导入所需的第三方库

import cv2
import numpy as np
# 畸变矫正脚本
import camera_config

矫正畸变

left_remap = cv2.remap(imgLeft, camera_config.left_map1, camera_config.left_map2, cv2.INTER_LINEAR)
right_remap = cv2.remap(imgRight, camera_config.right_map1, camera_config.right_map2, cv2.INTER_LINEAR)

灰度化

imgL_gray = cv2.cvtColor(left_remap, cv2.COLOR_BGR2GRAY)
imgR_gray = cv2.cvtColor(right_remap, cv2.COLOR_BGR2GRAY)

立体匹配

### 设置参数
#块大小必须为奇数(3-11)
blockSize = 5img_channels = 2
num_disp = 16 * 8param = {'preFilterCap': 63,     #映射滤波器大小,默认15"minDisparity" : 0,    #最小视差"numDisparities" : num_disp,    #视差的搜索范围,16的整数倍"blockSize" : blockSize,"uniquenessRatio" : 10,     #唯一检测性参数,匹配区分度不够,则误匹配(5-15)"speckleWindowSize" : 0,      #视差连通区域像素点个数的大小(噪声点)(50-200)或用0禁用斑点过滤"speckleRange" : 1,             #认为不连通(1-2)"disp12MaxDiff" : 2,        #左右一致性检测中最大容许误差值"P1" : 8 * img_channels * blockSize** 2,   #值越大,视差越平滑,相邻像素视差+/-1的惩罚系数"P2" : 32 * img_channels * blockSize** 2,  #同上,相邻像素视差变化值>1的惩罚系数# 'mode': cv2.STEREO_SGBM_MODE_SGBM_3WAY}
## 开始计算深度图
left_matcher = cv2.StereoSGBM_create(**param)
left_disp = left_matcher.compute(imgL_gray, imgR_gray)
# 得到深度图
disp = cv2.normalize(dispL, dispL, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

效果
效果

二、wls滤波

从上面的结果来看,深度图存在很多“黑色区域”,“黑色区域”是没有正确匹配的地方,也就是说这部分是没有深度信息的,这种情况就是“不够稠密”。
在opencv的扩展包opencv-contrib里提供了一种WLS视差滤波的办法,可以使得重建更加稠密。
改进部分为立体匹配部分,在经过立体匹配后再做一步处理:

## 接上面的参数
left_matcher = cv2.StereoSGBM_create(**param)right_matcher = cv2.ximgproc.createRightMatcher(left_matcher)left_disp = left_matcher.compute(imgL_gray, imgR_gray)
right_disp = right_matcher.compute(imgR_gray, imgL_gray)
wls_filter = cv2.ximgproc.createDisparityWLSFilter(left_matcher)
# sigmaColor典型范围值为0.8-2.0
wls_filter.setLambda(8000.)
wls_filter.setSigmaColor(1.3)
wls_filter.setLRCthresh(24)
wls_filter.setDepthDiscontinuityRadius(3)filtered_disp = wls_filter.filter(left_disp, imgL_gray, disparity_map_right=right_disp)disp = cv2.normalize(filtered_disp, filtered_disp, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

效果
可以看到滤波之后的深度图变得相当稠密了。
但这种办法有利有弊:好处就是重建变得稠密,弊端就是这种办法会抹除掉一些细节深度,使得一块地方由原来的不同深度变成同一高度。
举个例子,上图中的杯子在实际观察中他应该是圆柱形,但滤波之后整个杯身将变成同一高度,即原来的高度差被抹除了。因此该方法请根据具体情况决定是否使用。

三、open3d点云重建

open3d提供了RGBD重建的办法,具体实现如下:
首先要准备一个相机内参文件(这样做比较省事),命名为camera_intrinsic.json
根据左目相机内参矩阵:

fx0cx
0fycy
001

以列为顺序写入:

{"width": 960,"height": 960,"intrinsic_matrix": [fx,0,0,0,fy,0,cx,cy,1]
}

保存,作为相机内参文件。再在主程序中继续接入以下代码:

# 获取内参
intrinsic = o3d.io.read_pinhole_camera_intrinsic("camera_intrinsic.json")
# 转换图像
color_image = o3d.geometry.Image(left_remap)
depth_image = o3d.geometry.Image(disp)
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_image, depth_image, depth_trunc=4.0, convert_rgb_to_intensity=False)
# 根据RGBD图像重建
temp = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, intrinsic)
pcd.points = temp.points
pcd.colors = temp.colors
# 显示效果
o3d.visualization.draw_geometries_with_editing([pcd], window_name="3D", width=1280, height=720)

效果

四、OpenCV的点云重建

除此之外也可以用opencv自带的办法重建,这个重建速度要比open3d快很多。
处理时需要剪掉一些不合理的点云数据。

# 将h×w×3数组转换为N×3的数组
def hw3ToN3(points):height, width = points.shape[0:2]points_1 = points[:, :, 0].reshape(height * width, 1)points_2 = points[:, :, 1].reshape(height * width, 1)points_3 = points[:, :, 2].reshape(height * width, 1)points_ = np.hstack((points_1, points_2, points_3))return points_def DepthColor2Cloud(points_3d, colors):rows, cols = points_3d.shape[0:2]size = rows * colspoints_ = hw3ToN3(points_3d).astype(np.int16)colors_ = hw3ToN3(colors).astype(np.int64)# 颜色信息blue = colors_[:, 0].reshape(size, 1)green = colors_[:, 1].reshape(size, 1)red = colors_[:, 2].reshape(size, 1)# rgb = np.left_shift(blue, 0) + np.left_shift(green, 8) + np.left_shift(red, 16)rgb = blue + green + red# 将坐标+颜色叠加为点云数组pointcloud = np.hstack((points_, red/255., green/255., blue/255.)).astype(np.float64)# 删掉一些不合适的点X = pointcloud[:, 0]Y = pointcloud[:, 1]Z = pointcloud[:, 2]remove_idx1 = np.where(Z <= 0)remove_idx2 = np.where(Z > 1000)remove_idx3 = np.where(X > 1000)remove_idx4 = np.where(X < -1000)remove_idx5 = np.where(Y > 1000)remove_idx6 = np.where(Y < -1000)remove_idx = np.hstack((remove_idx1[0], remove_idx2[0], remove_idx3[0], remove_idx4[0], remove_idx5[0], remove_idx6[0]))pointcloud_1 = np.delete(pointcloud, remove_idx, 0)return pointcloud_1

上面的函数可以单独用一个脚本文件保存再导入。
主脚本文件加入以下代码:

threeD = cv2.reprojectImageTo3D(disp, camera_config.Q)
pointcloud = DepthColor2Cloud(threeD, left_remap)# 转换为open3d的点云数据
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(pointcloud[:,:3])
pcd.colors = o3d.utility.Vector3dVector(pointcloud[:,3:])
o3d.visualization.draw_geometries_with_editing([pcd], window_name="3D", width=1280, height=720)

效果


http://chatgpt.dhexx.cn/article/jWVOjJQN.shtml

相关文章

双目视觉原理及流程概述

双目原理 双目视觉是利用视差原理的一种视觉方法。 如图所示为空间中一点P在左右相机中的成像点Pleft=(Xleft,Yleft),Pright=(Xright,Yright)。将两相机固定在同一平面上,则点P在Y方向的坐标是相同的,即Yleft = Yright =Y。根据三角原理,可得: 视差被定义为相同点在左…

双目视觉(一)双目视觉系统

系列文章&#xff1a; 双目视觉&#xff08;一&#xff09;双目视觉系统双目视觉&#xff08;二&#xff09;双目匹配的困难和评判标准双目视觉&#xff08;三&#xff09;立体匹配算法双目视觉&#xff08;四&#xff09;匹配代价双目视觉&#xff08;五&#xff09;立体匹配…

双目视觉简介

hi 小伙伴们&#xff0c;人啊&#xff0c;很容易有惰性&#xff0c;很久不跟新了&#xff0c;不做笔记了&#xff0c;如今“良心发现”&#xff0c;毕业之后第一次更新博客。当然还是学习&#xff0c;整合分享给更多的人&#xff01; 相信关注我博客和微信公众号的人很多都是做…

机器视觉——双目视觉的基础知识(视差深度、标定、立体匹配)

1、双目视觉的视差与深度 人类具有一双眼睛&#xff0c;对同一目标可以形成视差&#xff0c;因而能清晰地感知到三维世界。因此&#xff0c;计算机的一双眼睛通常用双目视觉来实现&#xff0c;双目视觉就是通过两个摄像头获得图像信息&#xff0c;计算出视差&#xff0c;从而使…

双目立体视觉(一) 基本原理和步骤

目录 一、双目立体视觉系统的四个基本步骤 二、各步骤原理 1、相机标定 2、立体校正 3、立体匹配 一、双目立体视觉系统的四个基本步骤 相机标定主要包含两部分内容: 单相机的内参标定和双目相机的外参标定&#xff0c;前者可以获得每个相机的焦距、光心、畸变系数等参数…

长连接和短链接的区别

长连接意味着进行一次数据传输后&#xff0c;不关闭连接&#xff0c;长期保持连通状态。如果两个应用程序之间有新的数据需要传输&#xff0c;则直接复用这个连接&#xff0c;无需再建立一个新的连接。就像下图这样。 它的优势是在多次通信中可以省去连接建立和关闭连接的开销…

springboot 实现长链接转短链接

实现结果&#xff1a; 转换短链接api&#xff1a; 接口&#xff1a;http://127.0.0.1/api?urlurlencode(要缩短的网址) 例如&#xff1a;http://127.0.0.1/api?urlhttp%3a%2f%2fwww.baidu.com 返回&#xff1a;http://127.0.0.1/baidu 访问短链接即可还原原url&#xff1b;…

长链接与短链接

1、Http协议 1.1 HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议&#xff0c;在传输层使用TCP协议&#xff0c;在网络层使用IP协议。IP协议主要解决网络路由和寻址问题&#xff0c;TCP协议主要解决如何在IP层之上可靠的传递…

长连接与短链接

短链接&#xff1a;客户端每次请求成功后&#xff0c;将关闭链接 长连接&#xff1a;客户端请求成功后&#xff0c;并不会立即关闭链接&#xff0c;适用于客户端请求较为频繁的情况 ———————————————————————————————————— 1. HTTP协议与TC…

如何实现 长链接变 短 链接?

短链接&#xff0c;通俗来说&#xff0c;就是将长的 URL 网址&#xff0c;通过程序计算等方式&#xff0c;转换为简短的网址字符串。 大家经常会收到一些莫名的营销短信&#xff0c;里面有一个非常短的链接让你跳转。新浪微博因为限制字数&#xff0c;所以也会经常见到这种看着…

微信:长链接转短链接

前言 微信复制出来的链接太长&#xff0c;想转短连接如何做&#xff1f; 将一条长链接转成短链接。 主要使用场景&#xff1a; 开发者用于生成二维码的原链接&#xff08;商品、支付二维码等&#xff09;太长导致扫码速度和成功率下降&#xff0c;将原长链接通过此接口转成短…

长链接 转换成 短链接

文章目录 参考来源思路方法一方法二 参考来源 豆瓣 短链接生成的算法原理 思路 方法一 一般会想到用哈希&#xff0c;这里可以用MD5码获取哈希值&#xff0c;但时MD5生成的串挺长的&#xff0c;这类要考虑怎么把它变短。 做法如下&#xff1a; 方法二 很好想的思路&…

长链接 转短链接URL的设计思路

最烂的回答 实现一个算法&#xff0c;将长地址转成短地址。实现长和短一一对应。然后再实现它的逆运算&#xff0c;将短地址还能换算回长地址。 这个回答看起来挺完美的&#xff0c;然后候选人也会说现在时间比较短&#xff0c;如果给我时间我去找这个算法就解决问题了。但是稍…

长链接转成短链接的原理和实现详解

一、为什么要设计短链接&#xff0c;短链接有什么好处&#xff1f; 1、链接变短&#xff0c;在对内容长度有限制的平台发文&#xff0c;可编辑的文字就变多了。 比如&#xff1a;微博&#xff0c;限定了只能发 140 个字&#xff0c;如果一串长链直接怼上去&#xff0c;其他可…

长链到短链转化

文章目录 1:为什么将长链转化为短链&#xff1f;2:短链跳转的基本原理3&#xff1a;将长链转化为短链&#xff08;Hash&#xff09;3.1:hash3.1.1:hash算法的选取3.1.2hash后还是有点长3.1.3:解决hash冲突 3.2:自增序列算法 1:为什么将长链转化为短链&#xff1f; 1、链接变短…

2022年最新Python学习路线图(内附视频资料)【六张图带你掌握Python技巧】

目录 一、基础语法学习 二、制定发展方向 三、编程实践 四、资料获取 五、学习路线图​ 一、基础语法学习 Python的基础语法包括两大部分&#xff0c;其一是函数式编程部分&#xff0c;其二是面向对象编程部分。函数式部分的内容还是比较简单的&#xff0c;包括列表、函数…

零基础Python学习路线图,小白的进阶之路!

近几年Python的受欢迎程度可谓是扶摇直上&#xff0c;当然了学习的人也是愈来愈多。一些学习Python的小白在学习初期&#xff0c;总希望能够得到一份Python学习路线图&#xff0c;小编经过多方汇总为大家汇总了一份Python学习路线图。 对于一个零基础的想学习python的朋友来说…

15张超详细的Python学习路线图,纯良心分享,零基础学习宝典

这是一篇 Python 入门指南&#xff0c;针对那些没有任何编程经验&#xff0c;从零开始学习 Python 的同学。不管你学习的出发点是兴趣驱动、拓展思维&#xff0c;还是工作需要、想要转行&#xff0c;都可以用此文作为一个参考。 在这个信息爆炸的时代&#xff0c;以 “Python入…

2020最新版Python学习路线图

Python学习路线图网上有很多版本&#xff0c;前川网的这套Python学习路线图是2020最新版的&#xff0c;是根据企业招聘的要求不断更新的学习路线图&#xff0c;对之前的Pyhton学习路线图做了一些调整和改变&#xff0c;想要用Python爬虫或者深度学习人工智能的看这套Python学习…

Python 学习之路

最近在疫情静默管理期间&#xff0c;刚好有时间可以学习一下Python&#xff0c;非常幸运&#xff0c;找到一本Eric Matthes的《Python Crash Course》Python编程从入门到实践&#xff0c;好好研究一下。基础的语法就是一带而过了&#xff0c;使用的Python3.8.10版本&#xff0c…