我正试着从某个角度投射一张照片
如果照片是在相机直视前方时拍摄的,那么相机角度(yaw
,pitch
,roll
)都为零
现在让我们假设相机向上看,假设使用pitch=1 radians
,那么照片实际上捕捉的是梯形而不是矩形:
现在让我们来看一下代码——这是一个简单的程序,使用moderngl-window投影一张没有角度的照片:
import moderngl
import moderngl_window
import numpy as np
from PIL import Image
class Pygame(moderngl_window.WindowConfig):
window_size = 1280, 720
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.program = self.ctx.program(
vertex_shader="""
#version 330
in vec2 vertex_xy;
in vec2 vertex_uv;
uniform mat4 model;
out vec2 fragment_uv;
void main() {
vec4 p = vec4(vertex_xy, 0.0, 1.0);
gl_Position = model * p;
fragment_uv = vertex_uv;
}
""",
fragment_shader="""
#version 330
in vec2 fragment_uv;
uniform sampler2D texture0;
out vec4 fragment_color;
void main() {
fragment_color = texture(texture0, fragment_uv);
}
"""
)
self.program['model'].write(bytes(np.eye(4, dtype=np.float32)))
self.program['texture0'].value = 0
self.vertex_array = self.init_vertex_array(self.ctx, self.program)
image = Image.open('test.jpg').transpose(Image.FLIP_TOP_BOTTOM)
self.texture = self.ctx.texture(image.size, 3, image.tobytes())
self.texture.use()
def render(self, time, frametime):
self.ctx.clear()
self.vertex_array.render()
def init_vertex_array(self, context: moderngl.Context, program: moderngl.Program) -> moderngl.VertexArray:
vertices_xy = self.get_vertices_for_quad_2d(size=(2.0, 2.0), bottom_left_corner=(-1.0, -1.0))
vertex_buffer_xy = context.buffer(vertices_xy.tobytes())
vertices_uv = self.get_vertices_for_quad_2d(size=(1.0, 1.0), bottom_left_corner=(0.0, 0.0))
vertex_buffer_uv = context.buffer(vertices_uv.tobytes())
vertex_array = context.vertex_array(program, [(vertex_buffer_xy, "2f", "vertex_xy"),
(vertex_buffer_uv, "2f", "vertex_uv")])
return vertex_array
def get_vertices_for_quad_2d(self, size=(2.0, 2.0), bottom_left_corner=(-1.0, -1.0)) -> np.array:
# A quad is composed of 2 triangles: https://en.wikipedia.org/wiki/Polygon_mesh
w, h = size
x_bl, y_bl = bottom_left_corner
vertices = np.array([x_bl, y_bl + h,
x_bl, y_bl,
x_bl + w, y_bl,
x_bl, y_bl + h,
x_bl + w, y_bl,
x_bl + w, y_bl + h], dtype=np.float32)
return vertices
if __name__ == '__main__':
moderngl_window.run_window_config(Pygame, args=('--window', 'glfw'))
运行此程序时,您将看到以下窗口:
现在,如果我们编辑render
函数以添加角度:
def render(self, time, frametime):
pitch_rad = 1
rotate_around_y_pitch = np.array([[np.cos(pitch_rad), 0, np.sin(pitch_rad), 0],
[0, 1, 0, 0],
[-np.sin(pitch_rad), 0, np.cos(pitch_rad), 0],
[0, 0, 0, 1]], dtype=np.float32)
self.program['model'].write(bytes(rotate_around_y_pitch))
self.ctx.clear()
self.vertex_array.render()
然后投影的照片仍将是矩形(仅在纵横比发生变化时)而不是梯形
我错过了什么?
非常感谢@Grimmy提供了缺失的细节:
我应该使用
projection
矩阵我应该把物体放在远离摄像机的地方
完整的工作代码:
相关问题 更多 >
编程相关推荐