OpenCV:以相反顺序重新映射

问题描述 投票:0回答:3

我想将图像从球形投影到立方体贴图。根据我学习数学的理解,我需要为每个像素创建一个 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 重新映射相反,它表示

dst(x,y)=src(mapx(x,y),mapy(x,y))

我不明白数学是否全部错误,或者是否有办法隐藏

x_map
y_map
来纠正形式,以便
cv2.remap()
给出所需的结果。

输入图片

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

当前结果(使用

cv2.remap()

python opencv projection remap
3个回答
2
投票

我对

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)

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


0
投票

我几乎可以肯定这个问题与参考系在空间中的方向有关。也许如果您稍微澄清一下数学,我们可以提供帮助。


0
投票

我制作了一个适合您情况的

cv2.remap
用法示例。您可以更改弯曲比例的
conf
参数。

# Load an image
img = cv2.imread('/content/doc.png')
# To RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
[enter image description here][1]
# Create depth map
h, w = img.shape[:2]
x_axis = np.linspace(-1, 1, w)
y_axis = np.linspace(-1, 1, h)
xx, yy = np.meshgrid(x_axis, y_axis)
arr = np.sqrt(xx ** 2 + yy ** 2)
inner = 0
outer = 1
arr /= arr.max()
arr = arr * outer + (1 - arr) * inner

# map1 and map2 for cv2.remap function
rows, cols = img.shape[:2]
conf =.2
map1 = np.arange(cols) - arr * (np.arange(cols) - cols / 2) * conf
map2 = np.arange(rows) - arr.T * (np.arange(rows) - rows / 2) * conf
map2 = map2.T
map1 = map1.astype(np.float32)
map2 = map2.astype(np.float32)

img_remapped = cv2.remap(
    src=img,
    map1=map1,
    map2=map2,
    interpolation=cv2.INTER_NEAREST,
    borderMode=cv2.BORDER_CONSTANT
    )
© www.soinside.com 2019 - 2024. All rights reserved.