微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决OpenCV:以相反的顺序重新映射

我想将图像从球形投影到立方体贴图。根据我学习数学的理解,我需要为每个像素创建一个 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() 给出想要的结果。

输入图像

enter image description here

期望的结果(这个没有使用循环插值)

enter image description here

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

enter image description here

解决方法

我是 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)

我完全不懂这段代码中的数学原理,但我重写了一点,我应该说它运行得很好。这是结果图像: enter image description here 是的,我的结果图片和你的结果有点不同,但我希望它没问题:) 如果我在某个地方不对,当然不赞成这个答案,因为我不确定它是正确的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。