我经常问自己,生命的界限到底是什么。
死亡带给生命意义,但是却没人想接近它。
不停地死亡却又不停重生,二者的界限模糊不清。
为了追寻这个答案,年纪不大的我曾一度陷入疯狂。
后来我明白,原来是我的胸量太小,目光亦是狭窄。
正因为我看不到共性,所以世界在我眼中变得分崩离析。
雅尼在帕特农神庙前的音乐会上说,不久前他收看了一对刚从航天飞机上下来的宇航员的采访。采访中,宇航员描述了它环绕这颗星球的经历。他说,从那高高的地方观赏下来,地球是如此美丽。他又说,当他经过欧洲上方时,他发现他很难把国家们区分开来。他说这当中的原因,是因为那些地图上的"线"根本就不曾存在于地球上。
这些界限,根本就不存在。
土地,是相连的!
原来如此,假象这些界限的存在根本就是自找麻烦。
正确就是错误、重生就是死亡,它们本来就是同一个东西。
我们总是受着“彼此各不相同”的幻想所束缚,如果我们哪一天停止这些假象,而把目光转到我们的相似之处上,这个世界该变得多么美好啊?我们把地球划分成不同的国家,却忘了彼此相似的事实。
其实我们每个人都有着相同的胸量,因为,我们都是一样的。
好了,我们进入主题。
写了一段代码完成了图像的柱面投影纠正。 采用的理论方法是我的恩师邓飞邓老师的论文<基于SURF算法的柱面全景影像拼接方法>中的节选。因为最近要做一个全景影像的贴图,没有思路,所以就旁敲侧击一下想看看有什么发现,于是乎就看到了这个。
用到了opencv直接上代码:
double Plane2Cylin_X(double x,double theta,double W,double r)
死亡带给生命意义,但是却没人想接近它。
不停地死亡却又不停重生,二者的界限模糊不清。
为了追寻这个答案,年纪不大的我曾一度陷入疯狂。
后来我明白,原来是我的胸量太小,目光亦是狭窄。
正因为我看不到共性,所以世界在我眼中变得分崩离析。
雅尼在帕特农神庙前的音乐会上说,不久前他收看了一对刚从航天飞机上下来的宇航员的采访。采访中,宇航员描述了它环绕这颗星球的经历。他说,从那高高的地方观赏下来,地球是如此美丽。他又说,当他经过欧洲上方时,他发现他很难把国家们区分开来。他说这当中的原因,是因为那些地图上的"线"根本就不曾存在于地球上。
这些界限,根本就不存在。
土地,是相连的!
原来如此,假象这些界限的存在根本就是自找麻烦。
正确就是错误、重生就是死亡,它们本来就是同一个东西。
我们总是受着“彼此各不相同”的幻想所束缚,如果我们哪一天停止这些假象,而把目光转到我们的相似之处上,这个世界该变得多么美好啊?我们把地球划分成不同的国家,却忘了彼此相似的事实。
其实我们每个人都有着相同的胸量,因为,我们都是一样的。
好了,我们进入主题。
写了一段代码完成了图像的柱面投影纠正。 采用的理论方法是我的恩师邓飞邓老师的论文<基于SURF算法的柱面全景影像拼接方法>中的节选。因为最近要做一个全景影像的贴图,没有思路,所以就旁敲侧击一下想看看有什么发现,于是乎就看到了这个。
公式(1)中的第二行中的三角函数代表像点在图像中究竟移动了多少。像点的移动将会影响到图(b)中的P‘和Q‘的左移或者右移,这样就引起了投影后图像的像点位置在y方向上的移动,这也就是为什么在公式(1)中y‘的数值与x的数值相关。
具体操作的时候实际上使用的是反解公式,即从结果影像的每一个像素值反解出其在原始影像中的位置。反解公式由本人自己推导,公式如下:
具体操作的时候实际上使用的是反解公式,即从结果影像的每一个像素值反解出其在原始影像中的位置。反解公式由本人自己推导,公式如下:
double Plane2Cylin_X(double x,double theta,double W,double r)
{
double xp = (theta / 2.0 + atan((x - W / 2.0) / r))*r;
return xp;
}
double Plane2Cylin_Y(double x,double y,double H,double W,double r)
{
//double yp = H / 2.0 + cos(atan((x - W / 2.0) / r))*(y - H / 2.0);
double yp = y;
return yp;
}
double Cylin2Plane_X(double xp,double theta,double W,double r)
{
double x = r*tan(xp / r - theta / 2) + W / 2.0;
return x;
}
double Cylin2Plane_Y(double xp,double yp,double H,double r,double theta)
{
//double y = (yp - H / 2) / (cos(xp / r - theta / 2)) + H / 2;
double y = yp;
return y;
}
cv::Point2f PlaneP2CylinP(cv::Point2f PlaneP, double theta, double H, double W, double r)
{
double x = PlaneP.x;
double y = PlaneP.y;
double xp = Plane2Cylin_X(x, theta, W, r);
double yp = Plane2Cylin_Y(x, y, H, W, r);
cv::Point2f xpyp(xp, yp);
return xpyp;
}
void Panoramic_2_Cylindrical()
{
//std::string PanoramaIMGFile = std::string(".\\Data\\picture\\PanoramaIMG.jpg");//全景
std::string SinglePanoramaIMGFile = std::string(".\\Data\\picture\\SingleSphericalIMG.JPG");//单张
//cv::Mat PanoramaIMG = imread(PanoramaIMGFile);
cv::Mat SinglePanoramaIMG = imread(SinglePanoramaIMGFile);
//首先计算并猜测全景相机的CCD宽度
double CCDW_mm = 35.9;
double f_mm = 20;//同样满足焦距越大投影出来畸变越小的原理
double MaxLen = SinglePanoramaIMG.cols > SinglePanoramaIMG.rows ? SinglePanoramaIMG.cols : SinglePanoramaIMG.rows;
double f_pix = MaxLen / CCDW_mm*f_mm;
cout << "f_pix:" << f_pix << endl;
double r = f_pix;//一般投影的半径就取r
int W_col = SinglePanoramaIMG.cols;
int H_row = SinglePanoramaIMG.rows;
double theta = 2 * atan(W_col / (2 * r));
cout << "theta:" << theta << endl;//每张影像在全景影像中的视场角
//原始四个角点的位置:
cv::Point2f leftUp = cv::Point2f(0.0, 0.0);//x,y
cv::Point2f leftDown = cv::Point2f(0.0, H_row);//也许位置应该扩大一个像素比较好
cv::Point2f rightUp = cv::Point2f(W_col, 0.0);
cv::Point2f rightDown = cv::Point2f(W_col, H_row);
//变换后四个角点的位置:
cv::Point2f leftUp_Cylin = PlaneP2CylinP(leftUp, theta, H_row, W_col, r);
cv::Point2f leftDown_Cylin = PlaneP2CylinP(leftDown, theta, H_row, W_col, r);
cv::Point2f rightUp_Cylin = PlaneP2CylinP(rightUp, theta, H_row, W_col, r);
cv::Point2f rightDown_Cylin = PlaneP2CylinP(rightDown, theta, H_row, W_col, r);
cout << "leftUp_Cylin " << leftUp_Cylin << endl;
cout << "leftDown_Cylin " << leftDown_Cylin << endl;
cout << "rightUp_Cylin " << rightUp_Cylin << endl;
cout << "rightDown_Cylin " << rightDown_Cylin << endl;
int maxX = cvRound(rightDown_Cylin.x + 0.5);
int maxY = cvRound(rightDown_Cylin.y + 0.5);
cout << "maxX 、Y:" << maxX << " " << maxY << endl;
cv::Mat CylinImg(maxY, maxX, CV_8UC3, Scalar(0, 0, 0));//row cols
//每张图像翻解出原来图像的位置:
for (int r_y = 0; r_y<maxY; r_y++)
{
for (int c_x = 0; c_x<maxX; c_x++)
{
cv::Point2f CylinPoint = cv::Point2f(c_x, r_y);
//double Cylin2Plane_X(double xp,double theta,double W,double r)
//double Cylin2Plane_Y(double xp,double yp,double H,double r,double theta)
int findPlane_x = cvRound(Cylin2Plane_X(c_x, theta, W_col, r));
int findPlane_y = cvRound(Cylin2Plane_Y(c_x, r_y, H_row, r, theta));
//越界判断
if (findPlane_x < 0 || findPlane_x >= maxX)continue;
if (findPlane_y < 0 || findPlane_y >= maxY)continue;
//原来图像上对应的像素值
int color_b = SinglePanoramaIMG.at<cv::Vec3b>(findPlane_y, findPlane_x)[0];
int color_g = SinglePanoramaIMG.at<cv::Vec3b>(findPlane_y, findPlane_x)[1];
int color_r = SinglePanoramaIMG.at<cv::Vec3b>(findPlane_y, findPlane_x)[2];
CylinImg.at<cv::Vec3b>(r_y, c_x)[0] = color_b;
CylinImg.at<cv::Vec3b>(r_y, c_x)[1] = color_g;
CylinImg.at<cv::Vec3b>(r_y, c_x)[2] = color_r;
}
}
std::string SaveStr = std::string(".\\Output\\OutCylin.jpg");
imwrite(SaveStr, CylinImg);
}
原始影像和转换结果如下:
下一步要做的是借鉴这一理论,制作出球面投影和平面投影的转换代码。
原始影像和转换结果如下:
下一步要做的是借鉴这一理论,制作出球面投影和平面投影的转换代码。