欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV——将针孔相机模型图片转换成鱼眼相机模型图片

程序员文章站 2022-04-17 18:12:14
...

一 理论基础

        关于针孔相机模型,参考博客

        关于鱼眼相机模型,参考参考文献[1][2]。

        这里只需要知道我们这里使用的鱼眼相机模型是等距投影的鱼眼相机模型,即r=fθ(1),而针孔相机模型是透视投影,即r=ftanθ(2)。其中f是焦距focus,r是成像平面内某像素点到主光点principal point的距离,principal point是成像平面和主光轴的焦点,θ是入射光线和主光轴的夹角。根据(1)和(2),可以得到从正常图像上某点P(xc,yc)到鱼眼相机上某点P(xf,yf)的映射关系:

rf = f*arctan(rc/f)

二 OpenCV实现

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <cmath>

int main() {
	cv::Mat srcImg;
	srcImg = cv::imread("E:/Data Sets/ORIGINAL/data_road/training/image_2/um_000000.png");
	if (srcImg.data != nullptr) {
		std::cout << "Load Image Successfully" << std::endl;
	}
	const int f = 200;
	std::cout << srcImg.type() << std::endl;
	cv::Mat dstImg = cv::Mat(srcImg.cols, srcImg.cols, CV_8UC3, cv::Scalar(0,0,0));
	//---------transform pinhole image to fisheye image---------------//
	int ux = srcImg.cols / 2;
	int uy = srcImg.rows / 2;
	std::cout << uy << std::endl;
	int dx, dy, xf, yf, x, y;
	double rc, rf, theta, gama;
	for (int i = 0; i < srcImg.rows; i++) {
		for (int j = 0; j < srcImg.cols; j++) {
			dy = i - uy;
			dx = j - ux;
			rc = sqrt(pow(dy, 2) + pow(dx, 2));
			theta = atan2(rc, f);
			gama = atan2(dy, dx);
			rf = f * theta;
			xf = rf * cos(gama);
			yf = rf * sin(gama);
			x = xf + ux;
			y = yf + uy;
			dstImg.at<cv::Vec3b>(y, x)[0] = srcImg.at<cv::Vec3b>(i, j)[0];
			dstImg.at<cv::Vec3b>(y, x)[1] = srcImg.at<cv::Vec3b>(i, j)[1];
			dstImg.at<cv::Vec3b>(y, x)[2] = srcImg.at<cv::Vec3b>(i, j)[2];
		}
	}
	//----------------------------------------------------------------//
	cv::namedWindow("srcImg");
	cv::namedWindow("dstImg");
	cv::imshow("srcImg", srcImg);
	cv::imshow("dstImg", dstImg);
	cv::waitKey(0);
	cv::destroyAllWindows();
	return 0;
}

效果如下:

OpenCV——将针孔相机模型图片转换成鱼眼相机模型图片

三 代码实现过程总结

        1 求取dy的平方时,用pow()函数,dy ^ 2表示dy和2进行位异或操作,还是码得少啊...

        2 用一张像素值为0的图片初始化dstImg,cv::Mat dstImg = cv::Mat(rows, cols, CV_8UC3, cv::Scalar(0,0,0));

        3 imread()的路径名不能是有\,使用/可以正确读取。


参考文献:

[1]K. Miyamoto, "Fish Eye Lens," Journal of the Optical Society of America, vol. 54, 1964.

[2]J. Kannala and S. S. Brandt, "A generic camera model and calibration method for conventional, wide-angle, and fish-eye lenses," IEEE Transactions on Pattern Analysis & Machine Intelligence, vol. 28, pp. 1335-40, 2006.