[英]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_map
和y_map
以更正 forms,以便cv2.remap()
给出所需的结果。
DESIRED RESULT (this one is without interpolation using loops)期望的结果(这个没有使用循环插值)
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.