这是我关于堆栈溢出的第一个问题,很抱歉有任何错误,但我现在不知道如何处理我的问题。我正在编写一个应用程序,它使用OpenGl在pyQt5中呈现点云。我可以使用VBO渲染所有的点,但是查看点的唯一方法是将其坐标标准化为-0.5 - 0.5值。你能帮我解决这个问题吗?
这是我的密码:
def initializeGL(self):
self.setClearColor(self.backgroundColor)
self.object = self.makeDefaultObject()
if not self.drawDefaultData and self.pts.size == 0: self.pts = default.pointCloud
gl.glShadeModel(gl.GL_FLAT)
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glEnable(gl.GL_CULL_FACE)
self.reloadPoints()
def reloadPoints(self):
if self.pts.size == 0:
self.pts = default.pointCloud
self.vbo_disp, self.vbo_disp_clr, self.disp_count = self.loadVBO()
self.xPos = -np.mean(self.pts, axis=0)[0]
self.yPos = np.mean(self.pts, axis=0)[1]
self.zPos = np.min(self.pts, axis=0)[2] -10
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glLoadIdentity()
gl.glTranslated(self.xPos, self.yPos, self.zPos)
gl.glScaled(self.zoomScale, self.zoomScale, self.zoomScale)
gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
gl.glCallList(self.object)
if self.pts.size != 0: self.drawPointCloud()
def resizeGL(self, width, height):
side = min(width, height)
if side < 0:
return
gl.glViewport((width - side) // 2, (height - side) // 2, side,
side)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
gl.glMatrixMode(gl.GL_MODELVIEW)
def drawPointCloud(self):
gl.glPushMatrix()
gl.glPointSize(self.pointSize)
glEnableClientState(gl.GL_VERTEX_ARRAY)
glEnableClientState(gl.GL_COLOR_ARRAY)
vtx_disp = self.vbo_disp[0]
clr_disp = self.vbo_disp_clr[0]
cnt_disp = self.disp_count[0]
vtx_disp.bind()
gl.glVertexPointer(3, gl.GL_FLOAT, 0, vtx_disp)
vtx_disp.unbind()
clr_disp.bind()
gl.glColorPointer(3, gl.GL_FLOAT, 0, clr_disp)
clr_disp.unbind()
gl.glDrawArrays(gl.GL_POINTS, 0, cnt_disp)
glDisableClientState(gl.GL_VERTEX_ARRAY)
glDisableClientState(gl.GL_COLOR_ARRAY)
gl.glPopMatrix()
def loadVBO(self):
vtx_list = [ [] for _ in range(1) ]
clr_list = [ [] for _ in range(1) ]
vtx_count = np.zeros( 1, dtype=np.int32 )
vtx_count[0] = len(self.pts)
vtx_list[0] = qlVBO.VBO( self.pts[:,:3].copy().astype(np.float32) )
if (np.size(self.pts, 1) == 6):
clr_list[0] = qlVBO.VBO( self.pts[:,3:].copy().astype(np.float32) / 255.0 )
elif (np.size(self.pts, 1) == 3):
clr_list[0] = qlVBO.VBO( np.ones([vtx_count[0],3]).astype(np.float32) )
else:
print("Internal error")
vtx_count[0] = len(self.pts)
return vtx_list, clr_list, vtx_count我一直试图改变相机的定位方式,但没有任何结果。我认为问题在于:
gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)但如何改变这种状况..。请帮我一把!
发布于 2020-04-13 08:49:34
您可以在视口上看到的是三维视图卷的投影。投影矩阵定义了相对于投影到视口的观察者(查看者)的面积(体积)。
在您的例子中,您使用了一个正射投影。在正射投影中,这个区域(体积)由6个距离(左、右、下、上、近和远)定义。空间(卷)中的所有对象(点)在视口上都是“可见的”。在这个空间之外的所有对象(点)都被裁剪在卷的边框上。
..。但看到点的唯一方法是将坐标正常化为-0.5 - 0.5值.
其实你做错了。您可以更改顶点坐标(点)的比例,而不是扩展查看量。
正投影可由glOrtho设定。
gl.glOrtho(-0.5,+0.5,+0.5,-0.5,4.0,15.0)
这个设置定义了一个长方体体积与左,底部,接近od (-0.5,-0.5,4.0)和右,顶部,远的(0.5,0.5,15.0)。
增加这个体积,而不是缩放坐标:
gl.glOrtho(min_x, max_x, max_y, min_y, min_z, max_z)我建议采取以下措施:
计算点云的轴对齐包围框,从(self.min_x,self._min_y,self.min_z)到(self.max_x,self._max_y,self.max_z),并定义一个正正转投影,该投影定义一个长方体体积,其大小足以将所有与其方向无关的点(欧氏距离)包围起来:
ef resizeGL(self, width, height):
side = min(width, height)
if side < 0:
return
gl.glViewport((width - side) // 2, (height - side) // 2, side, side)
dx = self.max_x - self.min_x
dy = self.max_y - self.min_y
dz = self.max_z - self.min_z
dia = math.sqrt(dx*dx + dy*dy + dz*dz)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(-dia/2, dia/2, dia/2, -dia/2, -dia/2, dia/2)
gl.glMatrixMode(gl.GL_MODELVIEW)计算包围框的中心,并定义一个相反方向的初始平移。翻译必须将点云的中心“移动”到世界的起源:
self.center_x = (self.min_x + self.max_x) / 2
self.center_y = (self.min_y + self.max_y) / 2
self.center_z = (self.min_z + self.max_z) / 2self.xPos = 0
self.yPos = 0
self.zPos = 0观看量足够大,因此没有必要缩放点(self.zoomScale = 1)。首先对点云进行缩放,然后将其平移并最终旋转是很重要的,因此旋转的支点是点云的中心:
modelview = translate * rotation * scale * translateToOrigin glRotate、glScale和glTranslate等矩阵变换操作定义了一个新矩阵,并将当前矩阵与新矩阵相乘。因此,操作的顺序必须是1. glTranslate 2. glRotate,3. glScale,4. glTranslate(-center),:
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glLoadIdentity()
gl.glTranslated(self.xPos, self.yPos, self.zPos)
gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
gl.glScaled(self.zoomScale, self.zoomScale, self.zoomScale)
gl.glTranslated(-self.center_x, -self.center_y, -self.center_z)
# [...]https://stackoverflow.com/questions/61184158
复制相似问题