【传感器标定】图片校正(c++、python代码)

前言


代码

python 代码

普通相机

import cv2
import numpy as np

mtx = np.array(
    [1018.488091073461, 0.0, 976.4698604089125, 0.0, 1018.1743205737621, 524.3940644115754, 0.0, 0.0, 1.0]).reshape(3,
                                                                                                                    3)
dist = np.array(
    [-0.39265196173805544, 0.20922680814651598, -4.70111490361179e-05, 4.289211380146578e-05, -0.06715044674693742]
).reshape(5, 1)
h, w = 1080, 1920
alpha = 0
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), alpha, (w, h))
img = cv2.imread("F:\\1.png")
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
dst = cv2.resize(dst, (1920, 1080))
cv2.imshow("show", dst)  # 这里只针对单张图片校正,多张校正可以根据需求更改
cv2.waitKey(0)

鱼眼相机

import cv2
import numpy as np


def fish_image_dist(img):
    map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, (1920, 1080), cv2.CV_16SC2)
    undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
    return undistorted_img


K = np.array([[508.0680189, 0., 947.9423389],
              [0., 508.02681978, 506.37321985],
              [0., 0., 1.]]).reshape(3, 3)
D = np.array([[0.13142053],
              [-0.01600879],
              [-0.01790873],
              [0.00550534]]).reshape(4, 1)

img = cv2.imread("F:\\1.png")
dist = fish_image_dist(img)
cv2.imshow("show", dist)  # 这里只针对单张图片校正,多张校正可以根据需求更改
cv2.waitKey(0)

c++ 代码

普通相机

#include <iostream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <io.h>
#include <string>

using namespace std;
using namespace cv;

vector<Mat> read_images_in_folder(cv::String pattern);

int main()
{	
	// 原图所在的目录
	cv::String dirName = "F:\\*jpg";
	vector<Mat> images = read_images_in_folder(dirName);
	return 0;
}

vector<Mat> read_images_in_folder(cv::String pattern)
{
	const int ImgWidth = 1920;
	const int ImgHeight = 1080;
	const cv::Mat K = (cv::Mat_<double>(3, 3) << 1.00880026e+03, 0.00000000e+00, 9.45387230e+02,
												0.00000000e+00, 1.00784680e+03, 5.65509311e+02,
												0.00000000e+00, 0.00000000e+00, 1.00000000e+00);
	const cv::Mat D = (cv::Mat_<double>(5, 1) << -0.3900199, 0.21476073, - 0.00118118, 0.00081861, - 0.06851613);
	cv::Mat map1, map2;
	const double alpha = 0;	// 决定保留多少黑边
	cv::Size imageSize(ImgWidth, ImgHeight);
	cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, imageSize, alpha, imageSize, 0);
	// 非鱼眼相机
	initUndistortRectifyMap(K, D, cv::Mat(), NewCameraMatrix, imageSize, CV_16SC2, map1, map2);
	vector<cv::String> fn;
	glob(pattern, fn, false);
	vector<Mat> images;
	size_t count = fn.size(); // 文件夹有多少图片

	for (size_t i = 0; i < count; i++)
	{
		images.push_back(imread(fn[i]));
		cout << fn[i] << endl;
		cv::Mat RawImage = cv::imread(fn[i]);
		cv::Mat UndistortImage;
		remap(RawImage, UndistortImage, map1, map2, cv::INTER_LINEAR);
		cv::imwrite(fn[i], UndistortImage);
	}
	return images;
}

鱼眼相机

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<Mat> read_images_in_folder(cv::String pattern);

int main()
{
    cv::String dirName = "F:\\*.jpg";
    vector<Mat> images = read_images_in_folder(dirName);
    return 0;
}

vector<Mat> read_images_in_folder(cv::String pattern) 
{
    const cv::Mat K = (cv::Mat_<double>(3, 3) << 510.1529232524548, 0, 978.097474431498,0, 510.4286100550981, 529.9045678787428,0, 0, 1);
    const cv::Mat D = (cv::Mat_<double>(4, 1) << 0.13159907730082632, -0.025159280794422065, -0.011608807129743496, 0.003894052503105539);

    const int ImgWidth = 1920;
    const int ImgHeight = 1080;

    cv::Mat map1, map2;
    cv::Size imageSize(ImgWidth, ImgHeight);
    const double alpha = 0;
    cv::Mat NewCameraMatrix;
    cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, imageSize, cv::Matx33d::eye(), NewCameraMatrix, alpha);
    cv::fisheye::initUndistortRectifyMap(K, D, cv::Matx33d::eye(), NewCameraMatrix, imageSize, CV_16SC2, map1, map2);

    vector<cv::String> fn;
    glob(pattern, fn, false);
    vector<Mat> images;
    size_t count = fn.size(); //number of png files in images folder

    for (int i = 0; i < count; i++)
    {
        images.push_back(imread(fn[i]));
        cout << fn[i] << endl;
        cv::Mat RawImage = cv::imread(fn[i]);
        cv::Mat UndistortImage;
        cv::fisheye::undistortImage(RawImage, UndistortImage, K, D, K, imageSize);
        cv::imwrite(fn[i], UndistortImage);
    }
    return images;
}
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: 标定相机是指确定相机的内部参数和外部参数,以便对其进行修正和校正,从而提高图像质量和测量精度。OpenCV是一个开源的计算机视觉库,提供了用于相机标定的相关函数和方法。 在OpenCV中,相机标定可以通过使用calibrateCamera函数来实现。以下是一个大致的代码示例: 1. 导入OpenCV库: import cv2 2. 定义需要标定的图像的大小: width = 640 height = 480 3. 提供用于相机标定的棋盘格图像: chessboard_images = [] for i in range(1, 21): image = cv2.imread("chessboard_{}.jpg".format(i)) chessboard_images.append(image) 4. 创建棋盘格角点的三维坐标数组: square_size = 2 # 棋盘格每个方格的实际尺寸 obj_points = [] for i in range(0, width, square_size): for j in range(0, height, square_size): obj_points.append((i, j, 0)) 5. 定义图像中的角点数组: img_points = [] 6. 寻找每个图像中的棋盘格角点并追加到角点数组中: for image in chessboard_images: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 将图像转换为灰度图像 ret, corners = cv2.findChessboardCorners(gray, (width, height), None) # 寻找棋盘格角点 if ret: img_points.append(corners) 7. 运行相机标定函数来计算相机的内部参数和外部参数: ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (width, height), None, None) 通过这些步骤,我们可以获取到相机的内部参数矩阵(camera_matrix),畸变系数(dist_coeffs)以及每个图像的旋转向量(rvecs)和平移向量(tvecs)。 相机标定的目的是提取和矫正相机获取图像时的畸变,从而提高图像质量和测量精度。OpenCV提供的相机标定函数可以快速准确地完成这些任务。 ### 回答2: OpenCV是一个开源的计算机视觉库,可以用于图像处理和分析。其中相机标定是一项重要的功能,用于确定相机的内部和外部参数,以便在图像中进行准确的测量和估计。 以下是一个基本的OpenCV相机标定代码示例: ```python import cv2 import numpy as np # 定义棋盘格的尺寸,通常是(宽度-1,高度-1) chessboard_size = (8, 6) # 创建棋盘格角点的空数组 object_points = [] # 3D点在真实世界中的坐标 image_points = [] # 图像中对应的2D点坐标 # 生成棋盘格的3D坐标 objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32) objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) # 打开摄像头 cap = cv2.VideoCapture(0) while True: # 读取图像帧 ret, frame = cap.read() # 转换为灰度图像 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 查找棋盘格角点 ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) # 如果找到了角点 if ret == True: object_points.append(objp) image_points.append(corners) # 在图像上绘制角点 cv2.drawChessboardCorners(frame, chessboard_size, corners, ret) # 显示图像 cv2.imshow('Camera Calibration', frame) # 按下键盘上的空格键开始标定 if cv2.waitKey(1) & 0xFF == ord(' '): break # 完成图像采集,关闭摄像头 cap.release() cv2.destroyAllWindows() # 相机标定 ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None) # 输出相机内部参数和畸变系数 print("相机内部参数:") print(camera_matrix) print("\n畸变系数:") print(dist_coeffs) ``` 以上代码演示了通过使用OpenCV的`calibrateCamera`函数来进行相机标定。在代码中,我们首先从摄像头读取图像帧,在灰度图像上查找棋盘格角点,并将其存储到`object_points`和`image_points`中。然后,通过调用`calibrateCamera`函数,我们可以获得相机的内部参数矩阵(`camera_matrix`)和畸变系数(`dist_coeffs`)。最后,我们将它们打印出来。 相机标定对于许多计算机视觉应用非常重要,它可以让我们更准确地测量和估计图像中的物体。通过使用OpenCV的相机标定功能,我们可以轻松地获取相机的内外参数。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

读书猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值