【问题标题】:Transform and remap an equirectangular image with a 90° roll使用 90° 滚动转换和重新映射等距矩形图像
【发布时间】:2016-05-15 21:51:37
【问题描述】:

我必须将 equirectangular 图像转换并重新映射到另一个 90° 滚动的 equirectangular 图像。

我用Pano2VR 做到了。

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

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

我将我的调查指向 OpenCV 和 libgnomonic。这是目前最有趣的方式。该库允许用户转换投影(等矩形到直线,反之亦然)或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()

【问题讨论】:

    标签: python c image opencv


    【解决方案1】:

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

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

    您可以通过以下步骤进行此转换;

    • 将每个像素的 x 和 y 位置转换为经度 -π ≤ long ≤ π 和纬度 -π/2 ≤ lat ≤ π/2。这是一个线性变换。
    • 在单位球面上创建对应经纬度的x、y、z坐标;正 z 是北极。
    • 旋转这些笛卡尔坐标。在您的情况下,您只需要交换一些维度,但这可能是任何转换矩阵的一般转换。
    • 计算旋转坐标的经纬度。
    • 将新的经度和纬度转换为像素位置。

    这是有效的 C 代码。 (我知道你已经用 Python 标记了这个问题,但下面的代码主要是在 python 中工作类似的公式。你必须注意:所有数字都是浮点数,除了像素索引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
        }
    }
    

    生成的图像质量还可以,但不如您的参考图像,尤其是在两极附近。更好的算法将平均和平滑颜色值。上面的算法只是将一个目标像素映射到一个源像素。

    【讨论】:

    • 非常感谢您的解释。好吧,我将尝试在 python 模块中实现您的代码。但是,在 C 中结果应该会更好更快。我可能会尝试使用 Cython。
    • 好吧,我做到了,但结果很糟糕。我认为我的代码的最后一部分不好。
    • 乍一看:您还没有将模运算符% 应用于您的x 坐标。这意味着上个季度的 x 坐标超出范围。尝试使用img2.putpixel([(x + width/4) % width, y], newpixel)。
    • 抱歉。好吧,我纠正了它,但错误仍然存​​在。我评论了我的代码,因为当我更正与您的代码的最后一个差异时,超出范围的错误又回来了。
    • 当我运行你的代码(但没有 PIL)时,我得到了源像素和目标像素的有效索引。抛出异常时最好知道像素位置的值。
    猜你喜欢
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    相关资源
    最近更新 更多