如何解决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_map
和 y_map
转换为更正形式,以便 cv2.remap()
给出想要的结果。
解决方法
我是 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)
我完全不懂这段代码中的数学原理,但我重写了一点,我应该说它运行得很好。这是结果图像: 是的,我的结果图片和你的结果有点不同,但我希望它没问题:) 如果我在某个地方不对,当然不赞成这个答案,因为我不确定它是正确的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。