【opencv】鱼眼图像畸变校正——双经度法

5月23日更新代码
参考:基于双经度模型的鱼眼图像畸变矫正方法_魏利胜
http://download.csdn.net/detail/qq_15947787/9583010
注意:原文中公式14,15,17,18,22,23有误,均未考虑符号问题。双经度法适用与视场接近180°以及小于180°情况

#define Q_R 311
#define X0 392
#define Y0 282

IplImage* Double( IplImage* img)
{
	float R = Q_R;
	IplImage* imgCalib = cvCreateImage( cvSize( 2*R, 2*R ),IPL_DEPTH_8U, 3);		//创建校正后图像大小
	float sita = 0;
	float fi = 0;
	float tempu = 0;
	float tempv = 0;
	float x0 = X0 ;//扩展边界后圆心发生偏移
	float y0 = Y0 ;
	float flag1 =1;
	float flag2 =1;
	CvPoint2D32f xy;
	CvPoint2D32f uv;
	
	for (int i = 0; i < imgCalib->width; i++)
	{
		for (int j = 0; j < imgCalib->height; j++)
		{
			sita = PI - (PI/2/R)*i;
			fi = PI - (PI/2/R)*j;
			tempu = tan(fi)*tan(fi) + 1 + (tan(fi)*tan(fi))/(tan(sita)*tan(sita));
			tempv = tan(sita)*tan(sita) + 1 + (tan(sita)*tan(sita))/(tan(fi)*tan(fi));
			if (fi >PI/2)    //文中公式22,23 ,17,18有符号错误
				flag1 = 1;
			else
				flag1 = -1;

			if (sita <PI/2)
				flag2 = 1;
			else
				flag2 = -1;
			uv.x = flag1*R/sqrt(tempu) + x0;//u-fi 下正上负
			uv.y = flag2*R/sqrt(tempv) + y0;//v-sita 右正左负

			int iu = (int)uv.x;
			int iv = (int)uv.y;
			//!此处取的是左上点,为了双线性方便
			CvPoint3D32f f1;
			CvPoint3D32f f2;
			if (iu>=0&&iv>=0&&iu<img->width&&iv<img->height)
			{
				//双线性插值法
				f1.x = ((uchar*)(img->imageData + img->widthStep*iv))[iu*3] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*iv))[(iu+1)*3] * (1-abs(uv.x-(iu+1)));

				f1.y = ((uchar*)(img->imageData + img->widthStep*iv))[iu*3+1] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*iv))[(iu+1)*3+1] * (1-abs(uv.x-(iu+1)));

				f1.z = ((uchar*)(img->imageData + img->widthStep*iv))[iu*3+2] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*iv))[(iu+1)*3+2] * (1-abs(uv.x-(iu+1)));

				f2.x = ((uchar*)(img->imageData + img->widthStep*(iv+1)))[iu*3] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*(iv+1)))[(iu+1)*3] * (1-abs(uv.x-(iu+1)));

				f2.y = ((uchar*)(img->imageData + img->widthStep*(iv+1)))[iu*3+1] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*(iv+1)))[(iu+1)*3+1] * (1-abs(uv.x-(iu+1)));

				f2.z = ((uchar*)(img->imageData + img->widthStep*(iv+1)))[iu*3+2] * (1-abs(uv.x-iu))+
					((uchar*)(img->imageData + img->widthStep*(iv+1)))[(iu+1)*3+2] * (1-abs(uv.x-(iu+1)));

				((uchar*)(imgCalib->imageData + imgCalib->widthStep*j))[i*3] = f1.x*(1-abs(uv.y-iv))+f2.x*(abs(uv.y-iv));
				((uchar*)(imgCalib->imageData + imgCalib->widthStep*j))[i*3+1] = f1.y*(1-abs(uv.y-iv))+f2.y*(abs(uv.y-iv));
				((uchar*)(imgCalib->imageData + imgCalib->widthStep*j))[i*3+2] = f1.z*(1-abs(uv.y-iv))+f2.z*(abs(uv.y-iv));
			}			
		}
	}
	return imgCalib;
}

这里写图片描述
这里写图片描述

可以看到在四个极点图像拉伸现象非常严重。

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
鱼眼图像畸变校正的透视变换原理如下: 1. 首先,需要确定图像中的两个灭点,这可以通过球面透视投影得到。 2. 然后,根据灭点的位置,确定仿射变换矩阵,将图像进行仿射变换。 3. 最后,对变换后的图像进行裁剪,得到最终的校正图像。 下面是一个使用OpenCV进行鱼眼图像畸变校正的Python代码示例: ```python import cv2 import numpy as np # 读取鱼眼图像 img = cv2.imread('fisheye.jpg') # 确定灭点 h, w = img.shape[:2] K = np.array([[w, 0, w/2], [0, w, h/2], [0, 0, 1]]) D = np.array([0, 0, 0, 0]) newK = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, (w, h), np.eye(3)) map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), newK, (w, h), cv2.CV_16SC2) img_undistorted = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT) # 确定仿射变换矩阵 src_points = np.float32([[0, 0], [w-1, 0], [0, h-1], [w-1, h-1]]) dst_points = np.float32([[w/4, h/4], [w*3/4, h/4], [0, h], [w, h]]) M = cv2.getPerspectiveTransform(src_points, dst_points) # 进行仿射变换 img_transformed = cv2.warpPerspective(img_undistorted, M, (w, h)) # 裁剪图像 img_corrected = img_transformed[int(h/4):int(h*3/4), int(w/4):int(w*3/4)] # 显示结果 cv2.imshow('Original Image', img) cv2.imshow('Undistorted Image', img_undistorted) cv2.imshow('Transformed Image', img_transformed) cv2.imshow('Corrected Image', img_corrected) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值