Exemple #1
0
osg::Matrix vpb::MyDataSet::getImageSection(vips::VImage &in,const osg::Vec2 minT, const osg::Vec2 maxT,int origX,int origY,osg::Vec4 &texsize,const osg::Matrix &toTex,osg::ref_ptr<osg::Image> &image,osg::Vec4 &ratio,int level){

    double downsampleFactor=pow(2,level);
    double downsampleRatio=1.0/downsampleFactor;
    // std::cout<< minT << " " << maxT<<std::endl;
    // printf("%f %f\n",downsampleRatio,downsampleRatio);
    int x=(int)std::max((int)floor(minT.x()),0);
    int y=(int)std::max((int)floor(minT.y()),0);
    int xMax=(int)std::min((int)ceil(maxT.x()),origX);
    int yMax=(int)std::min((int)ceil(maxT.y()),origY);
    int xRange=(xMax-x);
    int yRange=(yMax-y);
    //printf("X:%d -- %d Y:%d -- %d ",x,xMax,y,yMax);

    //Need bias of 1.0 or will round down
    double maxSide=std::max(osg::Image::computeNearestPowerOfTwo(xRange,1.0),osg::Image::computeNearestPowerOfTwo(yRange,1.0));
    osg::Vec2 subSize=osg::Vec2(maxSide,maxSide);
    if(downsampleRatio*maxSide < 1.0){
        printf("Clipping %f %f to",downsampleRatio,downsampleFactor);
        downsampleRatio=1.0/maxSide;
        downsampleFactor=maxSide;
        printf("%f %f\n",downsampleRatio,downsampleFactor);

    }
    texsize[0]=origX;
    texsize[1]=origY;
    texsize[2]=subSize.x();
    texsize[3]=subSize.y();
    osg::Vec2 downsampleSize(subSize.x(),subSize.y());
    downsampleSize.x()*=downsampleRatio;
    downsampleSize.y()*=downsampleRatio;

    // printf("Range %d %d\n",xRange,yRange);
    // printf("%f %f %f %f\n",subSize.x(),subSize.y(),downsampleSize.x(),downsampleSize.y());
    image = new osg::Image;
    image->allocateImage(downsampleSize.x(),downsampleSize.y(), 1, GL_RGB,GL_UNSIGNED_BYTE);
    if(image->data() == 0 ){
        fprintf(stderr,"Failed to allocate\n");
        exit(-1);
    }
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_imageMutex);
        vips::VImage osgImage(image->data(),downsampleSize.x(),downsampleSize.y(),3,vips::VImage::FMTUCHAR);
        in.extract_area(x,y,xRange,yRange).embed(1,0,0,subSize.x(),subSize.y()).shrink(downsampleFactor,downsampleFactor).write(osgImage);
    }
    ratio=osg::Vec4(x,y,subSize.x(),subSize.y());
    //osg::Vec2 f(xRange-subSize.x(),yRange-subSize.y());
    //std::cout << f<<std::endl;
    return toTex;
}
MatrixXf computeDepthImage( osg::Camera* camera, osg::ref_ptr<osg::Image> depthbufferimg ) {
  cout << "computing depth image" << endl;
  // from https://svn.lcsr.jhu.edu/cisst/trunk/saw/components/sawOpenSceneGraph/code/osaOSGCamera.cpp
  // This is used by glutUnProject

  const osg::Viewport* viewport = camera->getViewport();
  size_t width = viewport->width();
  size_t height = viewport->height();
  
  // Create a 3xN range data destination matrix.
  // [ x1 ... xN ]
  // [ y1 ... yN ]
  // [ z1 ... zN ]
  // VCT_COL_MAJOR is used because we will write in the following order
  // x1, y1, z1, x2, y2, z2, ..., xN, yN, zZ
  MatrixXf depthimage( width, height);
  float* Z = depthimage.data();
  float* z = (float*)depthbufferimg->data();

  // get the intrinsic parameters of the camera
  double fovy, aspectRatio, Zn, Zf;
  camera->getProjectionMatrixAsPerspective( fovy, aspectRatio, Zn, Zf );

  size_t i=0;
  // convert zbuffer values [0,1] to depth values + flip the image vertically
  for( int r=height-1; 0<=r; r-- ){
    for( int c=0; c<width; c++ ){
      // forgot where I took this equation
      Z[ i++ ] = Zn*Zf / (Zf - z[ r*width + c ]*(Zf-Zn));
    }
  }

  return depthimage;

}
GeometryTexturePatch16::GeometryTexturePatch16( int x , int y , int sizeC , int scaleC , osg::ref_ptr<osg::Image> image , double dAdd , double dScale )
{
	//сдвиг и масштабирование
	m_dAdd = dAdd;
	m_dScale = dScale;

	//создать объект для хранения в нем геометрии
	m_patchGeom = new osg::Geometry;

	//создать массив вершин
	m_patchGeom->setVertexArray( CreateVertexArray( x , y , sizeC , scaleC ).get() );

	//создать массив текстурных координат
	m_patchGeom->setTexCoordArray( 0, CreateTexCoordArray( x , y , sizeC , scaleC , 
		image->data() ).get() );

	// Create an array for the single normal.
	osg::ref_ptr< osg::Vec3Array > n = new osg::Vec3Array;
	n->push_back( osg::Vec3( 0, -1, 0 ) );
	m_patchGeom->setNormalArray( n.get() );
	m_patchGeom->setNormalBinding( osg::Geometry::BIND_OVERALL );

	std::vector< unsigned int > m_vIndex;

	//заполнить вектор индексами
	FillIndexVector( m_vIndex , sizeC );

	m_patchGeom->addPrimitiveSet( new osg::DrawElementsUInt(
		osg::PrimitiveSet::TRIANGLE_STRIP, m_vIndex.size() , &m_vIndex[ 0 ] ) );
}
ColorCloudPtr computePointCloud( osg::Camera* camera, osg::ref_ptr<osg::Image> depthbufferimg, osg::ref_ptr<osg::Image> colorbufferimg) {
  MatrixXf X,Y,Z;
  computeRangeData(camera, depthbufferimg, X, Y, Z);
  int nRows = X.rows();
  int nCols = X.cols();
  ColorCloudPtr out(new ColorCloud(nCols, nRows));

  for (int row=0; row < nRows; row++) {
    for (int col=0; col < nCols; col++) {
      ColorPoint& pt = out->at(col, row);
      pt.x = X(row,col);
      pt.y = Y(row,col);
      pt.z = Z(row,col);
      pt.r = *(colorbufferimg->data(col,row));
      pt.g = *(colorbufferimg->data(col,row));
      pt.b = *(colorbufferimg->data(col,row));
    }
  }

  return out;
}
void computeRangeData( osg::Camera* camera , osg::ref_ptr<osg::Image> depthbufferimg, MatrixXf& Ximg, MatrixXf& Yimg, MatrixXf& Zimg) {
  // from https://svn.lcsr.jhu.edu/cisst/trunk/saw/components/sawOpenSceneGraph/code/osaOSGCamera.cpp
  // This is used by glutUnProject

  const osg::Viewport* viewport = camera->getViewport();
  size_t width = viewport->width();
  size_t height = viewport->height();

  GLint view[4];
  view[0] = (int)viewport->x();
  view[1] = (int)viewport->y();
  view[2] = width;
  view[3] = height;
  
  // Create a 3xN range data destination matrix.
  // [ x1 ... xN ]
  // [ y1 ... yN ]
  // [ z1 ... zN ]
  // VCT_COL_MAJOR is used because we will write in the following order
  // x1, y1, z1, x2, y2, z2, ..., xN, yN, zZ

  Ximg.resize(height,width);
  Yimg.resize(height,width);
  Zimg.resize(height,width);


  // get the intrinsic parameters of the camera
  double fovy, aspectRatio, Zn, Zf;
  camera->getProjectionMatrixAsPerspective( fovy, aspectRatio, Zn, Zf );
  
  osg::Matrixd modelm = camera->getViewMatrix();
  osg::Matrixd projm = camera->getProjectionMatrix();

  //for( int y=0; y<height; y++ ){
  for( int y=height-1; 0<=y; y-- ){
    for( size_t x=0; x<width; x++ ){
      GLdouble X, Y, Z;
      float* d = (float*)depthbufferimg->data( x, y );
      gluUnProject( x, y, *d, modelm.ptr(), projm.ptr(), view, &X, &Y, &Z );
      //gluUnProject( x, y, *d, &model[0][0], &proj[0][0], view, &X, &Y, &Z );
      // rangedata is 4xN column major
      Ximg(y,x) = X;
      Yimg(y,x) = Y;
      Zimg(y,x) = Z;
    }
  }

}