stereocamera.cc
来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 695 行 · 第 1/2 页
CC
695 行
/* * Gazebo - Outdoor Multi-Robot Simulator * Copyright (C) 2003 * Nate Koenig & Andrew Howard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *//* Desc: A stereo camera sensor using OpenGL * Author: Andrew Howard * Date: 7 Oct 2004 * CVS: $Id: StereoCamera.cc,v 1.11 2005/09/30 20:50:09 natepak Exp $ */#if HAVE_CONFIG_H #include <config.h>#endif#include <assert.h>#include <stdlib.h>#include <string.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>#include "World.hh"#include "WorldFile.hh"#include "Body.hh"#include "StereoCamera.hh"//////////////////////////////////////////////////////////////////////////////// Constructor StereoCamera::StereoCamera(World *world) : Sensor(world){ this->imgWidth = this->imgHeight = 0; this->pose = GzPoseSet(GzVectorZero(), GzQuaternIdent()); this->cameraPoses[0] = GzPoseSet(GzVectorZero(), GzQuaternIdent()); this->cameraPoses[0] = GzPoseSet(GzVectorZero(), GzQuaternIdent()); this->baseline = 0; this->imageSize = 0; this->images[0] = this->images[1] = NULL; this->depthSize = 0; this->depthImages[0] = this->depthImages[1] = NULL; this->disparitySize = 0; this->disparityImages[0] = this->disparityImages[1] = NULL; this->saveEnable = false; this->saveCount = 0; this->savePathname = NULL; return;}//////////////////////////////////////////////////////////////////////////////// DestructorStereoCamera::~StereoCamera(){ return;}//////////////////////////////////////////////////////////////////////////////// Initialize the sensorint StereoCamera::Init(int width, int height, double hfov, double baseline, double nearClip, double farClip, const char *method){ double focal; this->imgWidth = width; this->imgHeight = height; this->hfov = hfov; this->baseline = baseline; this->nearClip = nearClip; this->farClip = farClip; // Do some sanity checks if (this->imgWidth == 0 || this->imgHeight == 0) { PRINT_ERR("image has zero size"); return -1; } if (this->hfov < 0.01 || this->hfov > M_PI) { PRINT_ERR("bad field of view"); return -1; } if (this->baseline < 0.01) { PRINT_ERR("zero baseline"); return -1; } if (this->nearClip < 0.01) { PRINT_ERR("near clipping plane (min depth) is zero"); return -1; } // Set the relative camera poses this->cameraPoses[0] = GzPoseSet(GzVectorSet(0, +baseline / 2, 0), GzQuaternIdent()); this->cameraPoses[1] = GzPoseSet(GzVectorSet(0, -baseline / 2, 0), GzQuaternIdent()); // Initialize the GL rendering context for regular images if (this->imageContext.Init(this->imgWidth, this->imgHeight, 5, 0, 16, method) != 0) { PRINT_ERR("camera initialization failed: no rendering context"); return -1; } // Initialize the GL rendering context for disparity images if (this->depthContext.Init(this->imgWidth, this->imgHeight, 5, 0, 16, method) != 0) { PRINT_ERR("camera initialization failed: no rendering context"); return -1; } // Initialize camera model: standard perspective projection focal = this->imgWidth / 2 / tan(this->hfov / 2); this->P.m[0][0] = focal; this->P.m[0][1] = 0; this->P.m[0][2] = this->imgWidth / 2; this->P.m[1][0] = 0; this->P.m[1][1] = focal; this->P.m[1][2] = this->imgHeight / 2; this->P.m[2][0] = 0; this->P.m[2][1] = 0; this->P.m[2][2] = 1; // Inverse projection this->iP = GzHomoInverse(P); // Initialize the image buffers this->imageSize = this->imgWidth * this->imgHeight * 3; this->images[0] = new unsigned char[this->imageSize]; this->images[1] = new unsigned char[this->imageSize]; this->depthSize = this->imgWidth * this->imgHeight; this->depthImages[0] = new float[this->depthSize]; this->depthImages[1] = new float[this->depthSize]; this->disparitySize = this->imgWidth * this->imgHeight; this->disparityImages[0] = new float[this->disparitySize]; this->disparityImages[1] = new float[this->disparitySize]; this->imageEnable[0] = false; this->imageEnable[1] = false; this->disparityEnable[0] = false; this->disparityEnable[1] = false; // Initialize display options this->renderOpt.displayBBox = false; this->renderOpt.displayAxes = false; this->renderOpt.displayCoM = false; this->renderOpt.displaySkins = false; this->renderOpt.displayRays = false; this->renderOpt.displayFrustrums = false; this->renderOpt.displayMaterials = true; this->renderOpt.displayTextures = true; return 0;}//////////////////////////////////////////////////////////////////////////////// Finalize the cameraint StereoCamera::Fini(){ if (this->disparityImages[0]) delete [] this->disparityImages[0]; if (this->disparityImages[1]) delete [] this->disparityImages[1]; if (this->depthImages[0]) delete [] this->depthImages[0]; if (this->depthImages[1]) delete [] this->depthImages[1]; if (this->images[0]) delete [] this->images[0]; if (this->images[1]) delete [] this->images[1]; this->imageContext.Fini(); this->depthContext.Fini(); return 0;}//////////////////////////////////////////////////////////////////////////////// Set the pose of the cameravoid StereoCamera::SetPose(GzPose pose){ this->pose = pose; return;}//////////////////////////////////////////////////////////////////////////////// Get the pose of the cameraGzPose StereoCamera::GetPose(){ return this->pose;}//////////////////////////////////////////////////////////////////////////////// Get the image dimensionsvoid StereoCamera::GetSize(int *w, int *h){ *w = this->imgWidth; *h = this->imgHeight; return;}//////////////////////////////////////////////////////////////////////////////// Enable image rendering void StereoCamera::EnableImage(int camera, bool enable){ assert(camera == 0 || camera == 1); this->imageEnable[camera] = enable; return;}//////////////////////////////////////////////////////////////////////////////// Enable disparity rendering void StereoCamera::EnableDisparity(int camera, bool enable){ assert(camera == 0 || camera == 1); this->disparityEnable[camera] = enable; return;}//////////////////////////////////////////////////////////////////////////////// Update the drawingvoid StereoCamera::Update(){ // Render the camera views if (this->imageEnable[0]) this->Render(0); if (this->imageEnable[1]) this->Render(1); // Render the disparity images if (this->disparityEnable[0] || this->disparityEnable[1]) { this->RenderDepth(0); this->RenderDepth(1); // Post process to correct disparity values and compute occulsions this->ProcessDisparity(); } // Save image frames if (this->saveEnable) this->SaveFrame(); return;}//////////////////////////////////////////////////////////////////////////////// Render the scene from the camera perspectivevoid StereoCamera::Render(int camera){ // Select the GL context if (this->imageContext.MakeCurrent() != 0) return; // Clear the window glClearColor(this->world->skyColor.r, this->world->skyColor.g, this->world->skyColor.b, this->world->skyColor.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use disparity buffering for hidden surface elimination glEnable(GL_DEPTH_TEST); // Enable back face culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Set the camera lens propeties (assumes square pixels) glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(this->hfov * 180 / M_PI, (double) this->imgWidth / this->imgHeight, this->nearClip, this->farClip); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GzPose pose; GzVector a, b; // Set the camera pose; compute the point to look at, and the // orientation vector pose = GzCoordPoseAdd(this->cameraPoses[camera], this->pose); a = GzVectorSet(1, 0, 0); b = GzVectorSet(1, 0, 1); a = GzCoordPositionAdd(a, pose.pos, pose.rot); b = GzCoordPositionAdd(b, pose.pos, pose.rot); b = GzVectorSub(b, a); gluLookAt(pose.pos.x, pose.pos.y, pose.pos.z, a.x, a.y, a.z, b.x, b.y, b.z); // Enable lighting glEnable(GL_LIGHTING); // Set the ambient light; this should be stored in the world // somewhere GLfloat col[4]; GZ_COLOR_COPY(col, GzColor(1.0, 1.0, 1.0, 1.0)); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col); // Ligth model (two-sided) glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); // Set rendering options glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Enable blending for transparency //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); this->renderOpt.displayMaterials = true; this->renderOpt.displayTextures = true; this->renderOpt.cameraIndex = this->imageContext.GetContextIndex(); this->renderOpt.cameraPose = pose;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?