双目立体视觉标定

双目立体视觉标定

1. 两个摄像头录像

摄像头是通过电脑浏览器页面打开的,为了方便,我直接在电脑上开启了两个摄像头,并且使用左右分屏直接开始录像,效果如下:
image
(模糊了一下隐私信息,可以大致看出是左右两个摄像头,棋盘格图像分别在两个摄像头正中间)

2. 视频切割

使用python,分割为独立的左右摄像头视频

import cv2


def extract_video_roi(src_video_path, dst_video_path, roi_start, roi_end):
    cap = cv2.VideoCapture(src_video_path)
    if not cap.isOpened():
        print(f"无法打开视频文件:{src_video_path}")
        return

    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS)

    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    out = cv2.VideoWriter(dst_video_path, fourcc, fps, (roi_end[0] - roi_start[0], roi_end[1] - roi_start[1]))

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        roi_frame = frame[roi_start[1]:roi_end[1], roi_start[0]:roi_end[0]]
        out.write(roi_frame)

    cap.release()
    out.release()


# 示例用法
src_video_path = "test.mp4"
dst_video_path = "test3.mp4"
roi_start = (978, 178)
roi_end = (1684, 969)

extract_video_roi(src_video_path, dst_video_path, roi_start, roi_end)

src_video_path是原摄像头mp4地址
dst_video_path是切割后的视频存放地址
roi_start和roi_end是左上角和右下角像素位置
修改完以上三个数值,就可以进行切割,我将左右摄像头画面存为test2.mp4和test3.mp4

test2.mp4:
image

test3.mp4
image

3. 逐帧提取

每秒一帧,将视频转为图片

import cv2
import os


def extract_frames(video_path, result_folder):
    # 创建结果文件夹
    os.makedirs(result_folder, exist_ok=True)

    # 打开视频文件
    cap = cv2.VideoCapture(video_path)

    frame_count = 0
    saved_count = 0
    # fps = cap.get(cv2.CAP_PROP_FPS)  # 获取视频的帧率
    frame_interval = int(cap.get(cv2.CAP_PROP_FPS))  # 设置帧采样间隔为1秒
    while cap.isOpened():
        # 读取视频帧
        ret, frame = cap.read()

        if not ret:
            break

        frame_count += 1
        # 每秒保存一帧
        if frame_count % frame_interval == 0:
            saved_count += 1

            # 保存帧到结果文件夹
            # frame_path = os.path.join(result_folder, f"{saved_count}.jpg")
            frame_path = os.path.join(result_folder, '%s.jpg' % saved_count)
            print(frame_path)
            cv2.imwrite(frame_path, frame)

    # 释放视频文件
    cap.release()


# 文件夹路径不能有中文!!!!!!
video_path, result_folder = 'test3.mp4', 'right'
extract_frames(video_path, result_folder)

video_path, result_folder分别是视频路径和图片存放文件夹。
根据刚刚的左右摄像头录像(test2.mp4,test3.mp4),我将图片存在left文件夹和right文件夹。

图片提取完毕效果如下(left文件夹):
image
right文件夹效果也差不多,就不展示了。

4. 转灰度图

如果直接用现在的图片到matlab中标定,会显示一个错误:串联的数组维度不一致
image

原因,是因为matlab双目标定工具箱有bug,不支持彩色图输入,只能输入灰度图。
于是将文件夹中的图片进行批量灰度化处理:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time      :2023/10/1 22:41
# @Author    :Ji Huiting


import cv2
import os


def to_gray(input_path, output_path):
    images = os.listdir(input_path)
    if not os.path.exists(output_path):
        os.makedirs(output_path)
    for image in images:
        print(image)
        input_image = os.path.join(input_path, image)
        output_image = os.path.join(output_path, image)
        image = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
        cv2.imwrite(output_image, image)


if __name__ == '__main__':
    input_path = "right"  # 要处理的图片所在的文件夹
    output_path = "right2"  # 处理完的图片放在这里
    to_gray(input_path, output_path)

input_path是图片文件夹
output_path是图片转灰度图后要存放的文件夹

现在我将left和right文件夹分别转灰度图,存放到left2和right2文件夹中。

5. matlab双目标定

【matlab启动】->【导航栏APP】->【Stero Camera Cailbrator为双目标定工具箱】
image

左右摄像头地址选择为刚刚转完灰度图的left2和right2文件夹
第三个参数是棋盘格每个格子的边长,每个人参数不一,自定义。(注意,单位是毫米,不是厘米)

确定后得到结果:
image
可以看到参数:
左右摄像头每个是180张,148张可用,32张不可用。

点击确定后,出现窗口:
image
在棋盘格上绿色的圈圈就是棋盘格的黑白相交的角点,可以看到是很准确的,没有出现错误。
如果出现了,需要手动剔除。

image
工具栏中:
Radial Distortion Compute选择【3 Coefficients】和【Tangential Distortion】,然后点击Calibrate进行校准。(时间比较长不用担心,去玩会再回来)

最后,工具栏中点击导出参数【Export Camera Parameters】就行了。可以顺便点击【save session】保存变量。

导出参数后,可以看到:
右边变量取出现了【stereoParams】变量:
image
这就是需要的相机参数。为了避免手工获取数据时出错,下面转载一个参数导出代码,将【stereoParams】变量转为excel:

rowName = cell(1,10);
rowName{1,1} = '平移矩阵';
rowName{1,2} = '旋转矩阵';
rowName{1,3} = '相机1内参矩阵';
rowName{1,4} = '相机1径向畸变';
rowName{1,5} = '相机1切向畸变';
rowName{1,6} = '相机2内参矩阵';
rowName{1,7} = '相机2径向畸变';
rowName{1,8} = '相机2切向畸变';
rowName{1,9} = '相机1畸变向量';
rowName{1,10} = '相机2畸变向量';
xlswrite('out.xlsx',rowName(1,1),1,'A1');
xlswrite('out.xlsx',rowName(1,2),1,'A2');
xlswrite('out.xlsx',rowName(1,3),1,'A5');
xlswrite('out.xlsx',rowName(1,4),1,'A8');
xlswrite('out.xlsx',rowName(1,5),1,'A9');
xlswrite('out.xlsx',rowName(1,6),1,'A10');
xlswrite('out.xlsx',rowName(1,7),1,'A13');
xlswrite('out.xlsx',rowName(1,8),1,'A14');
xlswrite('out.xlsx',rowName(1,9),1,'A15');
xlswrite('out.xlsx',rowName(1,10),1,'A16');
xlswrite('out.xlsx',stereoParams.TranslationOfCamera2,1,'B1');  % 平移矩阵
xlswrite('out.xlsx',stereoParams.RotationOfCamera2.',1,'B2');  % 旋转矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters1.IntrinsicMatrix.',1,'B5');  % 相机1内参矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters1.RadialDistortion,1,'B8');  % 相机1径向畸变(1,2,5)
xlswrite('out.xlsx',stereoParams.CameraParameters1.TangentialDistortion,1,'B9');  % 相机1切向畸变(3,4)
xlswrite('out.xlsx',stereoParams.CameraParameters2.IntrinsicMatrix.',1,'B10');  % 相机2内参矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters2.RadialDistortion,1,'B13');  % 相机2径向畸变(1,2,5)
xlswrite('out.xlsx',stereoParams.CameraParameters2.TangentialDistortion,1,'B14');  % 相机2切向畸变(3,4)
xlswrite('out.xlsx',[stereoParams.CameraParameters1.RadialDistortion(1:2), stereoParams.CameraParameters1.TangentialDistortion,...
    stereoParams.CameraParameters1.RadialDistortion(3)],1,'B15');  % 相机1畸变向量
xlswrite('out.xlsx',[stereoParams.CameraParameters2.RadialDistortion(1:2), stereoParams.CameraParameters2.TangentialDistortion,...
    stereoParams.CameraParameters2.RadialDistortion(3)],1,'B16');  % 相机2畸变向量

效果图:
image

亲测有效,在选择的目录下生成了out.xlsx文件,所见即所得。

可以顺便把【stereoParams】右键另存为文件,备份一下。

最后

标定已经完成,可以整理一下所有的数据。

└── matlab过程数据/
    ├── calibrationSession.mat
    ├── stereoParams.mat
    ├── 一些截图………………
└── 图片/
    └── left/
        ├── 1.jpg
        ├── ……………………
    └── left2/
        ├── 1.jpg
        ├── ……………………
    └── right/
        ├── 1.jpg
        ├── ……………………
    └── right2/
        ├── 1.jpg
        ├── ……………………
├── 结果.xlsx
└── 视频/
    ├── test.mp4
    ├── 右.mp4
    ├── 左.mp4
posted @ 2023-10-01 23:14  jijfurhg  阅读(208)  评论(0)    收藏  举报