我必须将一个equirectangular图像转换并重新映射到另一个90°滚动的equirectangular图像.
我用Pano2VR做了.
问题是我必须从服务器端以编程方式执行此操作.所以我不能使用G.U.I.去做吧.
首先,我将我的研究定位于imagemagick.我尝试了Fred ImageMagick scripts,但找不到任何人做我想做的事.而且,与Pano2VR相比,图像的处理时间显得非常长.
我将我的调查指导到OpenCV和libgnomonic.这是目前最有趣的方式.这个库允许用户转换投影(equirectangular到直线,反之亦然)或make equirectangular mapping transformation.我玩@L_404_4@,包含一些处理库的脚本.例如,我想将直线图像转换为equirectangular,但输出只是一个黑色背景图像(为什么?我找不到答案).
我想把它转换成这个图像
好吧,我对C一点也不舒服.
我想我应该使用这两个文件:
> https://www.github.com/FoxelSA/libgnomonic/blob/master/src/gnomonic-transform.h
> https://www.github.com/FoxelSA/libgnomonic/blob/master/src/gnomonic-transform.c
但我不知道怎么做.最重要的是,我想了解.
我是正确的吗?在第一张图片上应用了哪些转换?有没有办法用python或bash脚本来做?
好的,谢谢你的帮助.
**在python中编辑C的转换**
以下代码不起作用并返回和IndexError.
但是我试图抓住并传递异常,图像的第一个右侧部分似乎没有改变.
import math
from PIL import Image
img = Image.open("img1.jpg")
img = img.convert('RGB')
pixel = img.load()
width,height = img.size
img2 = img.copy()
for y in xrange(height):
for x in xrange(width):
xx = 2*(y+0.5) / width - 1.0
yy = 2*(y+0.5)/ height - 1.0
lng = math.pi * xx
lat = 0.5 * math.pi * yy
# NOTE! These axes are transposed because that's what the question is about
Z = math.cos(lat) * math.cos(lng) # normally X
Y = math.cos(lat) * math.sin(lng) # normally Y
X = -math.sin(lat) # normally -Z
D = math.sqrt(X*X+Y*Y)
lat = math.atan2(Z,D) # ? normally lat = math.asin(Z)
lng = math.atan2(Y,X)
#ix and iy must be integers
ix = int((0.5 * lng / math.pi + 0.5) * width - 0.5)
iy = int((lat/math.pi + 0.5) * height - 0.5)
#not sure of this part to remap the image
newpixel = pixel[ix,iy]
img2.putpixel([(x+width/4) % width,y],newpixel)
#I tries as mentionned in the following code to invert x and y in the two prevIoUs lines but the index error out of range comes back
img2.show()
90°的等角矩形图像只是图像宽度的四分之一的水平偏移.第一个转换更复杂:你基本上想要旋转球体,使得北极位于纬度0和经度0(几内亚湾的某个地方,如果你把thze地球作为参考.)
您可以通过这些步骤进行此转换;
>将每个像素的x和y位置转换为经度,-π≤long≤π,以及纬度,-π/2≤lat≤π/ 2.这是线性变换.
>在单位球面上创建相应经度和纬度的x,y和z坐标;正z是北极.
>旋转这些笛卡尔坐标.在您的情况下,您只需要交换一些维度,但这可能是任何转换矩阵的一般转换.
>计算旋转坐标的longituide和纬度.
>将新的经度和纬度转换为像素位置.
这是有效的C代码. (我知道你已经用Python标记了这个问题,但是下面的代码主要是在python中使用类似的公式.你必须小心:除了像素indixes x,y,ix和iy之外,所有数字都是浮点数.我本可以在Python中完成这项工作,但我没有Python图像库的经验.)
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
double xx = 2 * (x + 0.5) / width - 1.0;
double yy = 2 * (y + 0.5) / height - 1.0;
double lng = pi * xx;
double lat = 0.5 * pi * yy;
double X,Y,Z;
double D;
int ix,iy;
Z = cos(lat) * cos(lng); // corresponds to original x
Y = cos(lat) * sin(lng); // corresponds to original y
X = -sin(lat); // corresponds to original z
D = sqrt(X*X + Y*Y); // distance in the XY plane
lat = atan2(Z,D);
lng = atan2(Y,X);
ix = (0.5 * lng / pi + 0.5) * width - 0.5;
iy = (lat / pi + 0.5) * height - 0.5;
dest[y][(x + width / 4) % width] = src[iy][ix];
// width/4 offset ist the 90° roll
// % width wraps the longitude
}
}
结果图像的质量是可以的,但不如参考图像的质量好,特别是在极点附近.更好的算法可以平均并平滑颜色值.上面的算法仅将一个目标像素映射到源像素.