【问题标题】:OpenCV: Remap in reverse orderOpenCV:以相反的顺序重新映射
【发布时间】:2021-06-02 18:10:09
【问题描述】:

我想将图像从球形投影到立方体贴图。根据我学习数学的理解,我需要为每个像素创建一个 theta、phi 分布,然后将其转换为笛卡尔系统以获得归一化的像素图。

我使用下面的代码来做到这一点

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

上面创建的地图应该会给我我想要的cv2.remap() 的结果,但事实并非如此。然后我尝试循环遍历像素并实现我自己的重映射而不进行插值或外推。经过一番尝试和尝试,我推导出了以下公式,它给了我正确的结果

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

这与实际的cv2 remapping 相反,它说dst(x,y)=src(mapx(x,y),mapy(x,y))

我不明白数学是否全错了,或者有没有办法将x_mapy_map 转换为更正表格,以便cv2.remap() 给出所需的结果。

输入图片

DESIRED RESULT(这个没有使用循环插值)

当前结果(使用cv2.remap()

【问题讨论】:

    标签: python opencv projection remap


    【解决方案1】:

    我是opencv 的新手,之前我没有使用过如此困难的数学算法,但我尝试过这样做。我稍微重写了你的代码,这里是:

    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)
    

    我根本不懂这段代码中的数学,但我重写了一点,我应该说它工作得很好。这是结果图像: 是的,我的结果图片和您的结果图片之间存在一些差异,但我希望没问题 :) 如果我在某个地方不正确,当然会否决这个答案,因为我不确定它是否正确。

    【讨论】:

    • 嘿,这是非常正确的结果。尚未接受答案,因为我需要验证不同 theta phi 角度的数学运算
    • 正如你已经说过的,你不知道数学。所以这是错误的数学,它只适用于 X 阳性脸(那太不完美了)。我已经为其他面孔相应地更改了数学和角度,但它不起作用。您刚刚拟合了我们需要的模式,当角度为 120(theta) 和 0(phi) 时,该模式停止工作
    • 那么对不起,希望对您有所帮助
    • cv2.error: OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\imgwarp.cpp:668: 错误: (-215 :Assertion failed) !ssize.empty() in function 'cv::remapBilinear'
    猜你喜欢
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    相关资源
    最近更新 更多