影像畸变矫正带扭曲参数s(skew)像素比例ρ

本文详细介绍了使用OpenCV进行影像畸变矫正的方法,包括处理扭曲参数s和像素比例ρ,通过自定义代码实现影像畸变矫正,涵盖了OpenCV和Smart3D畸变模型的原理及应用。

影像畸变矫正带扭曲参数s(skew)像素比例ρ

OpenCV自带纠正方法不能矫正扭曲参数s和ρ。因此自己写代码来完成纠正。包括OpenCV的畸变模型,和Smart3D的畸变模型,其原理见影像畸变纠正详解
remap()不懂的可以看remap详解

	Mat src_cpu = imread(in_filename);

	cv::Mat mapx, mapy;
	mapx.create(src_cpu.size(), CV_32FC1);
	mapy.create(src_cpu.size(), CV_32FC1);

	float u0 = src_cpu.size().width / 2 + cx;
	float v0 = src_cpu.size().height / 2 + cy;

	double u0 = src_cpu.size().width / 2 + cx;
	double v0 = src_cpu.size().height / 2 + cy;
	double k1, k2, k3, p1, p2;

	// Smart3d model
	//k1 = distortionArr[0];
	//k2 = distortionArr[1];
	//k3 = distortionArr[2];
	//p1 = distortionArr[3];
	//p2 = distortionArr[4];

	//for (int i = 0; i<src_cpu.cols; ++i)
	//	for (int j = 0; j < src_cpu.rows; ++j)
	//	{
	//		double x = (i - u0) / f, y = (j - v0) / f;
	//		double x2 = x*x, y2 = y*y;
	//		double r2 = x2 + y2, _2xy = 2 * x*y;
	//		double kr = (1 + ((k3*r2 + k2)*r2 + k1)*r2);
	//		double xd = (x*kr + p2*_2xy + p1*(r2 + 2 * x2));
	//		double yd = (y*kr + p2*(r2 + 2 * y2) + p1*_2xy);
	//		double u = f*xd + u0 + skew*yd;
	//		double v = f*pixelRadio*yd + v0;
	//		mapx.at<float>(j, i) = u;
	//		mapy.at<float>(j, i) = v;
	//	}

	// OpenCV model
	k1 = distortionArr[0];
	k2 = distortionArr[1];
	p1 = distortionArr[2];
	p2 = distortionArr[3];
	k3 = distortionArr[4];

	for(int i = 0;i<src_cpu.cols;++i)
		for (int j = 0; j < src_cpu.rows; ++j)
		{
			double x = (i-u0)/f, y = (j - v0) / f;
			double x2 = x*x, y2 = y*y;
			double r2 = x2 + y2, _2xy = 2 * x*y;
			double kr = (1 + ((k3*r2 + k2)*r2 + k1)*r2);
			double xd = (x*kr + p1*_2xy + p2*(r2 + 2 * x2));
			double yd = (y*kr + p1*(r2 + 2 * y2) + p2*_2xy);
			double u = f*xd + u0 + skew*yd;
			double v = f*pixelRadio*yd + v0;
			mapx.at<float>(j, i) = u;
			mapy.at<float>(j, i) = v;
		}

	// GPU version
	cv::cuda::GpuMat src(src_cpu);
	cv::cuda::GpuMat distortion(src.size(), src.type());
	cv::Mat result;

	::cv::cuda::GpuMat m_mapx;
	::cv::cuda::GpuMat m_mapy;
	m_mapx = ::cv::cuda::GpuMat(mapx);
	m_mapy = ::cv::cuda::GpuMat(mapy);

	::cv::cuda::remap(src, distortion, m_mapx, m_mapy, INTER_LINEAR);
	distortion.download(result);

	imshow("img", src_cpu);
	imshow("undistort", result);
	waitKey(0);
### 使用OpenCV实现鱼眼镜头畸变矫正的棋盘格标定 #### 准备工作 为了成功完成鱼眼镜头的畸变校正,需要准备一组包含棋盘格图案的照片。这些照片应该覆盖不同的角度和位置,以便全面捕捉相机的特性。 #### 加载必要的库并初始化变量 首先加载所需的Python库,并定义一些全局参数: ```python import cv2 as cv import numpy as np import glob # 定义棋盘格内部角点的数量(宽度, 高度) pattern_size = (9, 6) # 创建用于存储对象点的世界坐标系下的三维点数组 objp = np.zeros((np.prod(pattern_size), 3), np.float32) objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) # 存储所有图片的对象点和图像点向量列表 objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. ``` #### 查找棋盘格角点 遍历所有采集到的标定图集文件夹内的每一张图片来查找其中是否存在有效的棋盘格模式,并保存相应的二维像素坐标与对应的真实世界三维坐标: ```python images = glob.glob('calibration_images/*.jpg') for fname in images: img = cv.imread(fname) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) ret, corners = cv.findChessboardCorners(gray, pattern_size, None) if ret is True: objpoints.append(objp) criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001) refined_corners = cv.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) imgpoints.append(refined_corners) # 绘制检测到的角点供可视化验证 cv.drawChessboardCorners(img, pattern_size, refined_corners, ret) cv.imshow('Found Corners', img) cv.waitKey(500) cv.destroyAllWindows() ``` #### 执行鱼眼模型标定过程 当收集足够的数据之后就可以调用`fisheye.calibrate()`函数来进行实际的标定了。此操作会返回内参矩阵K以及径向失真k1,k2,tangential p1,p2等参数[^3]: ```python N_OK = len(objpoints) K = np.zeros((3, 3)) D = np.zeros((4, 1)) rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)] tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)] rms, _, _, _, _ = \ cv.fisheye.calibrate( objpoints, imgpoints, gray.shape[::-1], K, D, rvecs, tvecs, calibrationFlags=cv.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv.fisheye.CALIB_CHECK_COND+cv.fisheye.CALIB_FIX_SKEW, criteria=(cv.TERM_CRITERIA_EPS+cv.TERM_CRITERIA_MAX_ITER, 30, 1e-6) ) print("RMS re-projection error:", rms) print("Intrinsic matrix:\n", K) print("Distortion coefficients:\n", D.ravel()) ``` #### 应用得到的结果进行去畸变变换 最后一步是对原始输入帧应用之前获得的信息来做反向映射以消除扭曲效果。可以利用`initUndistortRectifyMap()`预先计算好转换表再通过`remap()`快速执行重映射操作[^1]: ```python def undistort_image(image_path): img = cv.imread(image_path) h, w = img.shape[:2] map1, map2 = cv.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, dims, cv.CV_16SC2) undistorted_img = cv.remap(img, map1, map2, interpolation=cv.INTER_LINEAR, borderMode=cv.BORDER_CONSTANT) return undistorted_img undistorted_result = undistort_image('test_fisheye.jpg') cv.imwrite('output/undistorted_test.png', undistorted_result) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值