2016-02-05 30 views
4

我必须变换并将等轴矩形图像重新映射到具有90°卷的另一个等矩形图像。变换并重新映射90°卷的等矩形图像

我用Pano2VR做了。

问题是我必须从服务器端以编程方式执行。所以我不能使用G.U.I.去做吧。

首先,我将我的研究导向imagemagick。我试过Fred ImageMagick scripts,但找不到任何人做我想做的事。此外,与Pano2VR相比,图像的处理时间显得非常长。

我指示我的调查OpenCVlibgnomonic。这是目前最有趣的方式。该库允许te用户转换投影(equirectangular为直线,反之亦然)或make equirectangular mapping transformation。我玩Norama-suite这包含一些脚本来处理图书馆。例如,我会将直线图像转换为等矩形图像,但是输出只是一个黑色背景图像(为什么?我没有找到答案)。

但是,这第二个链接可以解决我的问题。我有这样的形象:

,我想将它转化到该图像

嗯,我不舒服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() 

回答

3

您的转换有两个步骤。第一步是投影球体的变换,第二步是90°滚动。

等轴矩形图像的90°滚动只是图像宽度四分之一的水平移位。第一个转换比较复杂:你基本上想要旋转球体,使北极在0纬度和0纬度(在几内亚湾的某处,如果你以地球为参照)

你可以去关于这些转变与这些步骤;

  • 翻译x和每个像素的y位置到经度,− π ≤长≤ π,以及纬度,− π/2 ≤ LAT ≤ π/2。这是一个线性变换。
  • 在单位球体上创建相应经度和纬度的x,y和z坐标;正z是北极。
  • 旋转这些直角坐标。在你的情况下,你只需交换一些维度,但这可能是任何变换矩阵的一般变换。
  • 计算旋转坐标的longituide和纬度。
  • 将新的经度和纬度转换为像素位置。

以下是可用的C代码。 (我知道你已经用Python标记了这个问题,但是下面的代码大部分都是在python中类似工作的公式,你必须注意:除了像素指针外,所有数字都是浮点数x,y,ixiy我会在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 
    } 
} 

所产生的图像的质量是好的,但不如你的参考图像,尤其是靠近两极。更好的算法会使颜色值平均并平滑。上面的算法只是将一个目标像素映射到源像素。

+0

非常感谢您的解释。那么,我会尝试在python模块中实现你的代码。但是,在C中结果应该更好更快。我可能会尝试使用Cython。 – pep

+0

那么,我做到了,但结果很糟糕。我认为我的代码的最后一部分不好。 – pep

+0

乍一看:您没有将模运算符'%'应用于'x'坐标。这意味着上一季度的x坐标超出范围。尝试使用'img2.putpixel([(x + width/4)%width,y],newpixel)''。 –