简体   繁体   English

OpenCV:以相反的顺序重新映射

[英]OpenCV: Remap in reverse order

I want to project an image from spherical to cubemap.我想将图像从球形投影到立方体贴图。 From what I understood studying maths, I need to create a theta, phi distribution for each pixel and then convert it into cartesian system to get a normalized pixel map.根据我学习数学的理解,我需要为每个像素创建一个 theta、phi 分布,然后将其转换为笛卡尔系统以获得归一化像素 map。

I used the following code to do so我使用以下代码来这样做

theta = 0
phi = np.pi/2
squareLength = 2048

# theta phi distribution for X-positive face
t = np.linspace(theta + np.pi/4, theta - np.pi/4, squareLength)
p = np.linspace(phi + np.pi/4, phi - np.pi/4, squareLength)
x, y = np.meshgrid(t, p)

# converting into cartesion sytem for X-positive face (where r is the distance from sphere center to cube plane and X is constantly 0.5 in cartesian system)
X = np.zeros_like(y)
X[:,:] = 0.5
r = X / (np.cos(x) * np.sin(y))
Y = r * np.sin(x) * np.sin(y)
Z = r * np.cos(y)
XYZ = np.stack((X, Y, Z), axis=2)

# shifting pixels from the negative side
XYZ = XYZ + [0, 0.5, 0.5]

# since i want to project on X-positive face my map should be
x_map = -XYZ[:, :, 1] * squareLength
y_map = XYZ[:,:, 2] * squareLength

The above map created should give me my desired result with cv2.remap() but it's not.上面创建的 map 应该用cv2.remap()给我我想要的结果,但事实并非如此。 Then I tried looping through pixels and implement my own remap without interpolation or extrapolation.然后我尝试循环遍历像素并实现我自己的重映射,无需插值或外推。 With some hit and trial, I deduced the following formula which gives me the correct result经过一些尝试和尝试,我推导出了以下公式,它给出了正确的结果

for i in range(2048):
    for j in range(2048):
        try:
            image[int(y_map[i,j]), int(x_map[i,j])] = im[i, j]
        except:
            pass

which is reverse of actual cv2 remapping which says dst(x,y)=src(mapx(x,y),mapy(x,y))这与实际的cv2 重新映射相反,它表示dst(x,y)=src(mapx(x,y),mapy(x,y))

I do not understand if did the math all wrong or is there a way to covert x_map and y_map to correct forms so that cv2.remap() gives the desired result.我不明白数学是否全部错误,或者是否有办法隐藏x_mapy_map以更正 forms,以便cv2.remap()给出所需的结果。

INPUT IMAGE输入图像在此处输入图像描述

DESIRED RESULT (this one is without interpolation using loops)期望的结果(这个没有使用循环插值) 在此处输入图像描述

CURRENT RESULT (using cv2.remap() )当前结果(使用cv2.remap() 在此处输入图像描述

I'm quite new in opencv and I didn't work with so difficult math algorithms before but I tried to do this.我是opencv的新手,之前我没有使用过如此困难的数学算法,但我尝试过这样做。 I rewrote your code a bit and here it is:我重写了你的代码,这里是:

import numpy as np
import cv2


src = cv2.imread("data/pink_sq.png")


def make_map():
    theta = 0
    phi = np.pi / 2
    squareLength = 4000

    # theta phi distribution for X-positive face
    t = np.linspace((theta - np.pi / 4), (theta + np.pi / 4), squareLength)
    p = np.linspace((phi + np.pi / 4), (phi - np.pi / 4), squareLength)
    x, y = np.meshgrid(t, p)

    x_res = np.zeros_like(y)
    x_res[:, :] = 0.5
    r = x_res * (np.cos(x))
    r /= np.amax(r)
    y_res = r * x
    z_res = r * np.cos(y)
    xyz = np.stack((x_res, y_res, z_res), axis=2)

    # shifting pixels from the negative side
    xyz = xyz + [0, 0.5, 0.5]

    # since i want to project on X-positive face my map should be
    x_map = xyz[:, :, 1] * squareLength
    y_map = xyz[:, :, 2] * squareLength

    map_x = y_map.astype("float32")
    map_y = x_map.astype("float32")
    return map_x, map_y


map_x, map_y = make_map()
dst = cv2.remap(src, map_y, map_x, cv2.INTER_LINEAR)

cv2.imwrite("res.png", dst)

I don't understand the math in this code at all but I rewrote it a bit and I should say that it works quite good.我根本不理解这段代码中的数学,但我重写了一点,我应该说它工作得很好。 Here is the result image:这是结果图像: 在此处输入图像描述 And yes, there is a bit difference between my result picture and yours but I hope it is ok:) If I'm not right somewhere of course downvote this answer because I'm not sure that it is correct one.是的,我的结果图片和您的结果图片之间存在一些差异,但我希望没问题:) 如果我在某个地方不正确,当然会否决这个答案,因为我不确定它是否正确。

I'm almost certain the issue has to do with the orientation of the reference frame in space.我几乎可以肯定这个问题与空间参考系的方向有关。 Maybe if you clarify the Math a bit we can help.也许如果您稍微澄清一下数学,我们可以提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM