Ejemplo n.º 1
0
void testBilateralFilter( const Array2D< float >& input,
	float ss, float sr,
	Array2D< float >& output )
{
	BilateralFilter bf( input.width(), input.height(), ss, sr );
	
	int nIterations = 100;

    
	bf.setInput( input );
	StopWatch sw;

	for( int i = 0; i < nIterations; ++i )
	{
		bf.apply( );
		cudaDeviceSynchronize();
	}

	float ms = sw.millisecondsElapsed();
	bf.getOutput( output );
	printf( "image size: %d x %d\n", input.width(), input.height() );
	printf( "ss = %f, sr = %f\n", ss, sr );
	printf( "Total time = %f ms, ms on average: %f\n",
		ms, ms / nIterations );
}
Ejemplo n.º 2
0
void d8_flow_directions(
  const Array2D<T> &elevations,
        Array2D<U> &flowdirs
){
  ProgressBar progress;

  std::cerr<<"A D8 Flow Directions"<<std::endl;
  std::cerr<<"C TODO"<<std::endl;

  std::cerr<<"p Setting up the flow directions matrix..."<<std::endl;
  flowdirs.resize(elevations);
  flowdirs.setAll(NO_FLOW);
  flowdirs.setNoData(FLOWDIR_NO_DATA);

  std::cerr<<"p Calculating D8 flow directions..."<<std::endl;
  progress.start( elevations.width()*elevations.height() );
  #pragma omp parallel for
  for(int y=0;y<elevations.height();y++){
    progress.update( y*elevations.width() );
    for(int x=0;x<elevations.width();x++)
      if(elevations(x,y)==elevations.noData())
        flowdirs(x,y) = flowdirs.noData();
      else
        flowdirs(x,y) = d8_FlowDir(elevations,x,y);
  }
  std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl;
}
Ejemplo n.º 3
0
void TA_CTI(
  const Array2D<T> &flow_accumulation,
  const Array2D<U> &riserun_slope,
        Array2D<V> &result
){
  Timer timer;

  RDLOG_ALG_NAME<<"d8_CTI";

  if(flow_accumulation.width()!=riserun_slope.width() || flow_accumulation.height()!=riserun_slope.height())
    throw std::runtime_error("Couldn't calculate CTI! The input matricies were of unequal dimensions!");

  RDLOG_PROGRESS<<"Setting up the CTI matrix..."<<std::flush;
  result.resize(flow_accumulation);
  result.setNoData(-1);  //Log(x) can't take this value of real inputs, so we're good
  RDLOG_PROGRESS<<"succeeded.";

  RDLOG_PROGRESS<<"Calculating CTI..."<<std::flush;
  timer.start();
  #pragma omp parallel for collapse(2)
  for(int x=0;x<flow_accumulation.width();x++)
    for(int y=0;y<flow_accumulation.height();y++)
      if(flow_accumulation(x,y)==flow_accumulation.noData() || riserun_slope(x,y)==riserun_slope.noData())
        result(x,y)=result.noData();
      else
        result(x,y)=log( (flow_accumulation(x,y)/flow_accumulation.getCellArea()) / (riserun_slope(x,y)+0.001) );
  RDLOG_TIME_USE<<"succeeded in "<<timer.stop()<<"s.";
}
Ejemplo n.º 4
0
Array2D matrix_multiply(const Array2D &M1,const Array2D &M2) {
	if (M1.height()!=M2.width()) return Array2D();
	Array2D ret(M1.width(),M2.height());
	for (int j=0; j<ret.height(); j++)
	for (int i=0; i<ret.width(); i++) {
		double val=0;
		for (int k=0; k<M1.height(); k++) {
			val+=M1.value(i,k)*M2.value(k,j);
		}
		ret.setValue(val,i,j);
	}
	return ret;
}
int SpotLightFallOFFIntensityCalculator::GetNumberOfRadiusSegments(const Array2D<Rgba>& inputImage_, const Point2D<int>& corePoint_) {
    
    //Get Max distance from core point to all points in image
    int max1 = std::sqrt(powf(corePoint_.x, 2) + powf(corePoint_.y, 2));
    int max2 = std::sqrt(powf(corePoint_.x - inputImage_.width(), 2) + powf(corePoint_.y - inputImage_.height(), 2));
    int max3 = std::sqrt(powf(corePoint_.x - inputImage_.width(), 2) + powf(corePoint_.y, 2));
    int max4 = std::sqrt(powf(corePoint_.x, 2) + powf(corePoint_.y - inputImage_.height(), 2));
    
    int max = std::max(std::max(std::max(max1, max2), max3), max4);
    return (int)(max/BLOCKSIZE);
}
Ejemplo n.º 6
0
void dinf_flow_flats(
    const Array2D<int32_t> &flat_resolution_mask,
    const Array2D<int32_t> &groups,
    Array2D<float> &flowdirs
) {
    ProgressBar progress;

    std::cerr<<"\n###Dinf Flow Flats"<<std::endl;

    std::cerr<<"%%Calculating Dinf flow directions using flat mask..."<<std::endl;
    progress.start( flat_resolution_mask.width()*flat_resolution_mask.height() );
    #pragma omp parallel for
    for(int x=1; x<flat_resolution_mask.width()-1; x++) {
        progress.update( x*flat_resolution_mask.height() );
        for(int y=1; y<flat_resolution_mask.height()-1; y++)
            if(flat_resolution_mask(x,y)==flat_resolution_mask.noData())
                continue;
            else if(flowdirs(x,y)==NO_FLOW)
                flowdirs(x,y)=dinf_masked_FlowDir(flat_resolution_mask,groups,x,y);
    }
    std::cerr<<"Succeeded in "<<progress.stop()<<"s."<<std::endl;
}
Ejemplo n.º 7
0
void testCrossBilateralFilter( const Array2D< float >& data, const Array2D< float >& edge,
	float ss, float sr,
	Array2D< float >& output )
{
	BilateralFilter cbf( data.width(), data.height(), ss, sr, 0.f, 1.f, true );
	
	int nIterations = 100;

	StopWatch sw;

	for( int i = 0; i < nIterations; ++i )
	{
		cbf.applyCross( data, edge, output );
		cudaDeviceSynchronize();
	}

	float ms = sw.millisecondsElapsed();
	printf( "image size: %d x %d\n", data.width(), data.height() );
	printf( "ss = %f, sr = %f\n", ss, sr );
	printf( "Total time = %f ms, ms on average: %f\n",
		ms, ms / nIterations );
}
Ejemplo n.º 8
0
int threshold(int th, Array2D &im) {
  int w = im.width();
  int h = im.height();
  int cnt=0;
  for (int i=0; i<h; ++i) {
    for (int j=0; j<w; ++j) {
      if (im[i][j] < th) {
	im[i][j] = 0;
      } else {
	im[i][j] = 255;
	++cnt;
      }
    }
  }
  return cnt;
}
Ejemplo n.º 9
0
void GridPerimToArray(const Array2D<U> &grid, std::vector<U> &vec){
  assert(vec.size()==0); //Ensure receiving array is empty

  std::vector<U> vec2copy;

  vec2copy = grid.getRowData(0);                         //Top
  vec.insert(vec.end(),vec2copy.begin(),vec2copy.end());

  vec2copy = grid.getColData(grid.width()-1);        //Right
  vec.insert(vec.end(),vec2copy.begin()+1,vec2copy.end());
  
  vec2copy = grid.getRowData(grid.height()-1);       //Bottom
  vec.insert(vec.end(),vec2copy.begin(),vec2copy.end()-1);
  
  vec2copy = grid.getColData(0);                         //Left
  vec.insert(vec.end(),vec2copy.begin()+1,vec2copy.end()-1);
}
Ejemplo n.º 10
0
void saveArrayAsImage( const Array2D< float >& array, QString prefix, float ss, float sr )
{
	Image4f im( array.width(), array.height() );

	for( int y = 0; y < im.height(); ++y )
	{
		for( int x = 0; x < im.width(); ++x )
		{
			float v = array( x, y );
			im.setPixel( x, y, Vector4f( v, v, v, 1 ) );
		}
	}

	QString filename = QString( "%1_%2_%3.png" ).arg( prefix ).arg( ss ).arg( sr );
	printf( "saving output: %s...", qPrintable( filename ) );
	im.flipUD().save( filename );
	printf( "done.\n\n" );
}
Ejemplo n.º 11
0
static inline void TerrainProcessor(F func, const Array2D<T> &elevations, const float zscale, Array2D<float> &output){
  if(elevations.getCellLengthX()!=elevations.getCellLengthY())
    RDLOG_WARN<<"Cell X and Y dimensions are not equal!";

  output.resize(elevations);
  ProgressBar progress;

  progress.start(elevations.size());
  #pragma omp parallel for
  for(int y=0;y<elevations.height();y++){
    progress.update(y*elevations.width());
    for(int x=0;x<elevations.width();x++)
      if(elevations.isNoData(x,y))
        output(x,y) = output.noData();
      else
        output(x,y) = func(elevations,x,y,zscale);
  }
  RDLOG_TIME_USE<<"Wall-time = "<<progress.stop();
}
Ejemplo n.º 12
0
void FindFlats(
  const Array2D<T>   &elevations,
  Array2D<int8_t>    &flats
){
  flats.resize(elevations);
  flats.setNoData(FLAT_NO_DATA);

  ProgressBar progress;

  progress.start( elevations.size() );

  #pragma omp parallel for
  for(int y=0;y<elevations.height();y++)
  for(int x=0;x<elevations.width();x++){
    if(elevations.isNoData(x,y)){
      flats(x,y) = FLAT_NO_DATA;
      continue;
    }

    if(elevations.isEdgeCell(x,y)){
      flats(x,y) = NOT_A_FLAT;
      continue;
    }

    //We'll now assume that the cell is a flat unless proven otherwise
    flats(x,y) = IS_A_FLAT;

    for(int n=1;n<=8;n++){
      const int nx = x+dx[n];
      const int ny = y+dy[n];
      if(elevations(nx,ny)<elevations(x,y) || elevations.isNoData(nx,ny)){
        flats(x,y) = NOT_A_FLAT;
        break;
      }
    }

    //We handled the base case just above the for loop
  }

  RDLOG_TIME_USE<<"Succeeded in = "<<progress.stop()<<" s";
}
void SpotLightFallOFFIntensityCalculator::GetLightFallOffPointsfromCorePoints_UsingGradientEstimation(const Array2D<Rgba>& inputImage_, const Point2D<int>& corePoint_) {
 
    int imageHeight = (int)inputImage_.height();
    int imageWidth  = (int)inputImage_.width();
    
    UtilityClass* util = new UtilityClass();
    Rgba* outputPixels = util->GetImagePixelsToWrite(imageWidth, imageHeight);
    Array2D<Rgba> outputImage(imageHeight,imageWidth);
    Array2D<Rgba> outputImage1(imageHeight,imageWidth);
    
    ImageFilterFactoryClass* imageFilterFactoryClass = new ImageFilterFactoryClass();
    ImageFilterClass* imageFilterClass = imageFilterFactoryClass->GetImageFilterClass(inputImage_, 5, FILTERTYPE::GAUSSIAN);
    imageFilterClass->ProcessImage(inputImage_, outputImage);
    
    imageFilterClass = imageFilterFactoryClass->GetImageFilterClass(outputImage, 1, FILTERTYPE::SOBEL);
    imageFilterClass->ProcessImage(outputImage,outputImage1);
    
//    imageFilterClass = imageFilterFactoryClass->GetImageFilterClass(inputImage_, 2, FILTERTYPE::GAUSSIAN);
//    imageFilterClass->ProcessImage(outputImage1, outputImage);
//    
//    imageFilterClass = imageFilterFactoryClass->GetImageFilterClass(outputImage, 1, FILTERTYPE::SOBEL);
//    imageFilterClass->ProcessImage(outputImage,outputImage1);
    
    for (int row = 0; row < (imageHeight); ++row) {
        for (int col = 0; col < (imageWidth); ++col) {
            int i = row * imageWidth + col;
            outputPixels[i] = outputImage1[row][col];
        }
    }
    
    util->WriteImage2DArrayPixels("../../Output/LOG1.exr", outputPixels, imageWidth, imageHeight);
    
    delete util;
    delete imageFilterFactoryClass;
   
}
Ejemplo n.º 14
0
void dinf_flow_directions(const Array2D<T> &elevations, Array2D<float> &flowdirs){
  ProgressBar progress;

  std::cerr<<"\nA Dinf Flow Directions"<<std::endl;
  std::cerr<<"C Tarboton, D.G. 1997. A new method for the determination of flow directions and upslope areas in grid digital elevation models. Water Resources Research. Vol. 33. pp 309-319."<<std::endl;

  std::cerr<<"p Setting up the Dinf flow directions matrix..."<<std::endl;
  flowdirs.resize(elevations);
  flowdirs.setNoData(dinf_NO_DATA);
  flowdirs.setAll(NO_FLOW);

  std::cerr<<"p Calculating Dinf flow directions..."<<std::endl;
  progress.start( elevations.size() );
  #pragma omp parallel for
  for(int y=0;y<elevations.height();y++){
    progress.update( y*elevations.width() );
    for(int x=0;x<elevations.width();x++)
      if(elevations(x,y)==elevations.noData())
        flowdirs(x,y) = flowdirs.noData();
      else
        flowdirs(x,y) = dinf_FlowDir(elevations,x,y);
  }
  std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl;
}
Ejemplo n.º 15
0
void Array2DPrivate::copy_from(const Array2D &X) {	
	allocate(X.width(),X.height());
	long N=X.width()*X.height();
	for (long ii=0; ii<N; ii++)
		m_data[ii]=X.d->m_data[ii];
}
void SpotLightFallOFFIntensityCalculator::GetLightFallOffPointsfromCorePoints_UsingBlocksOfPixels(const Array2D<Rgba>& inputImage_, const Point2D<int>& corePoint_) {
    
    int imageWidth = (int)inputImage_.width();
    int imageHeight = (int)inputImage_.height();
    
    UtilityClass* util = new UtilityClass();
    
    Point2D<int> currPoint = corePoint_;
    Point2D<int> corePoint = corePoint_;
    int block = 1;
    double currBlockIntensity = 0;
    double prevBlockIntensity = 0;
    double currPixelWindowIntensity = 0;
    
    
    // Loop through 0 to 360
    for (int degree = 0; degree < 360; ++degree) {
        currPoint   =   corePoint_;
        block       =   1;
        currBlockIntensity = 0;
        
        std::cout << "*********** degree = " << degree << std::endl;
        while ((currPoint.x >= 0) && (currPoint.x < imageWidth) && (currPoint.y >= 0) && (currPoint.y < imageHeight)) {
            prevBlockIntensity = currBlockIntensity;
            currBlockIntensity = 0;
            
            for (int radius = block; radius <=(block+BLOCKSIZE); ++radius) {
                
                currPoint = const_cast<Point2D<int>&>(corePoint_) + Point2D<int>(radius * cos(degree), radius * sin(degree));
                //currPoint = corePoint + Point2D<double>(radius*cos(degree), radius*sin(degree));
                
                if ((currPoint.x < 0) || (currPoint.x > imageWidth) || (currPoint.y < 0) || (currPoint.y > imageHeight)) {
                    break;
                }
                currPixelWindowIntensity = 0;
                util->GetAveragePixelIntensityAroundaPoint(inputImage_, currPoint, WINDOWRADIUS);
                currBlockIntensity += currPixelWindowIntensity;
                //currBlockIntensity += inputImage->at<uchar>(currPoint.y,currPoint.x);
            }
            currBlockIntensity /= BLOCKSIZE;
            
            double intensityDifference = prevBlockIntensity - currBlockIntensity;
            std::cout << "intensity difference  = " << intensityDifference << std::endl;
            //if ((intensityDifference > 2 && intensityDifference < 5) && (block != 1)) {
            
            /*
            if ((intensityDifference >= 5 && intensityDifference <= 8) && (block != 1)) {
                if ((currPoint.x >= 0) && (currPoint.x < imageWidth) && (currPoint.y >= 0) && (currPoint.y < imageHeight)) {
                    cv::circle(refImage, currPoint, 2, cv::Scalar(0,0,255), -1);
                }
            }
            
            if ((intensityDifference >= 10 && intensityDifference <= 15) && (block != 1)) {
                if ((currPoint.x >= 0) && (currPoint.x < imageWidth) && (currPoint.y >= 0) && (currPoint.y < imageHeight)) {
                    cv::circle(refImage, currPoint, 2, cv::Scalar(0,255,255), -1);
                }
            }
             */
            
            block += BLOCKSIZE;
        }
    }
    return;
}
Ejemplo n.º 17
0
static float dinf_FlowDir(const Array2D<T> &elevations, const int x, const int y){
  //Ensure that flow is pulled off the edge of the grid
  if (elevations.isEdgeCell(x,y)){
    if(x==0 && y==0)
      return 3*M_PI/4;  //D8: 2
    else if(x==0 && y==elevations.height()-1)
      return 5*M_PI/4;  //D8: 8
    else if(x==elevations.width()-1 && y==0)
      return 1*M_PI/4;  //D8: 4
    else if(x==elevations.width()-1 && y==elevations.height()-1)
      return 7*M_PI/4;  //D8: 6
    else if(x==0)
      return 4*M_PI/4;  //D8: 1
    else if(x==elevations.width()-1)
      return 0*M_PI/4;  //D8: 5
    else if(y==0)
      return 2*M_PI/4;  //D8: 3
    else if(y==elevations.height()-1)
      return 6*M_PI/4;  //D8: 7
  }

  int    nmax = -1;
  double smax = 0;
  double rmax = 0;

  //I am not on the edge of the grid. All my neighbours can be examined.

  for(int n=0;n<8;n++){
    //Is is assumed that cells with a value of NoData have very negative
    //elevations with the result that they draw flow off of the grid.

    //Choose elevations based on Table 1 of Tarboton (1997), Barnes TODO
    const double e0 = elevations(x,y);
    const double e1 = elevations(x+dx_e1[n],y+dy_e1[n]);
    const double e2 = elevations(x+dx_e2[n],y+dy_e2[n]);

    //TODO: Assumes that the width and height of grid cells are equal and scaled
    //to 1.
    const double d1 = 1;
    const double d2 = 1;

    const double s1 = (e0-e1)/d1;
    const double s2 = (e1-e2)/d2;
    double r        = atan2(s2,s1);

    double s;

    if(r<0){
      r = 0;
      s = s1;
    } else if(r>atan2(d2,d1)){
      r = atan2(d2,d1); //TODO: This is a constant
      s = (e0-e2)/sqrt(d1*d1+d2*d2);
    } else {
      s = sqrt(s1*s1+s2*s2);
    }

    if(s>smax){
      smax = s;
      nmax = n;
      rmax = r;
    }
  }

  double rg = NO_FLOW;
  if(nmax!=-1)
    rg = (af[nmax]*rmax+ac[nmax]*M_PI/2);

  return rg;
}
void SpotLightFallOFFIntensityCalculator::GetLightFallOffPointsfromCorePoints_UsingTableMapOfSectorsAndSegment(const Array2D<Rgba>& inputImage_, const Point2D<int>&corePoint_) {
    
    // Create a Table with Degree and radius
    //  PixelInSegment[degree][radius] -> vector of pixels.
    
    int maxNumberOfRadiusSegment =  GetNumberOfRadiusSegments(inputImage_, corePoint_);
    InitializeSectorsOfImage(inputImage_, corePoint_);
    
    int numOfRows = (int)inputImage_.height();
    int numOfCols = (int)inputImage_.width();
    
    for (int row=0; row < numOfRows; ++row) {
        for (int col = 0; col < numOfCols; ++col) {
            // Which pixel belongs to which sector and which segment
            // Get distance from corePoint_;
            
            if (row == corePoint_.y && col == corePoint_.x) {
                continue;
            }
 
            Point2D<int> currPixel = Point2D<int>((row - corePoint_.y),(col - corePoint_.x));
            
            double distance = std::sqrt(powf(currPixel.x, 2) + powf(currPixel.y, 2));
            int theta = (int)rad2deg(atan2(-currPixel.y, currPixel.x));
            int block = (distance - 1) / (BLOCKSIZE );
            
            if (theta < 0) {
                theta = 360 + theta;
            }
            Sector[theta][block].push_back(Point2D<int>(row,col));
            SectorIntensity[theta][block].push_back(inputImage_[row][col]);
        }
    }
    
    GetFallOffRegionForNoAmbientLightBackground(maxNumberOfRadiusSegment);
    //GetIntensityDifferenceForEachSectorSegments(maxNumberOfRadiusSegment);
 
    /*
//    UtilityClass* util = new UtilityClass();
//    Rgba* outputPixels = util->GetImagePixelsToWrite(numOfCols, numOfRows);
//    
//    std::vector<double>diffInIntensity = std::vector<double>(360,0);
//    
//    for (int index = 0; index < 360; ++index) {
//        for (int block = 1; block < (maxNumberOfRadiusSegment); ++block) {
//            
//            int numberOfZeroIntensityVectorBlock1 = 0, numberOfZeroIntensityVectorBlock2 = 0;
//  
//            if (Sector[index][block].size() > 0) {
//
//                numberOfZeroIntensityVectorBlock1 = (int)std::count_if(SectorIntensity[index][block].begin(), SectorIntensity[index][block].end(), value_equal(Rgba(0, 0, 0)));
//                
//                std::cout << index << "-" << block << " = " << numberOfZeroIntensityVectorBlock1 << " total = " << SectorIntensity[index][block].size() << "  normalized = " << (double)((double)numberOfZeroIntensityVectorBlock1/ (double)SectorIntensity[index][block].size()) << " -- " << Sector[index][block][0].y << "," << Sector[index][block][0].x <<  std::endl;
//            }
//            
//            else if (Sector[index][block-1].size() > 0) {
//                numberOfZeroIntensityVectorBlock2 = (int)std::count_if(SectorIntensity[index][block-1].begin(), SectorIntensity[index][block-1].end(), value_equal(Rgba(0, 0, 0)));
//                
//                 std::cout << index << "-" << block-1 << " = " << numberOfZeroIntensityVectorBlock2 << " total = " << SectorIntensity[index][block-1].size() << "  normalized = " << (double)((double)numberOfZeroIntensityVectorBlock2/ (double)SectorIntensity[index][block-1].size()) << " -- " << Sector[index][block-1][0].y << "," << Sector[index][block-1][0].x <<  std::endl;
//            }
//            
//            if (std::abs((int)Sector[index][block].size() - (int)Sector[index][block-1].size()) > 0) {
//  
//                // Sum of all pixel intensities in each block.
//                int avgSumOfElementsInFirstBlock   =   (std::accumulate(SectorIntensity[index][block].begin(),SectorIntensity[index][block].end(),0, Vector_acc))/((int)SectorIntensity[index][block].size() + EPSILON);
//                int avgSumOfElementsInSecondBlock  =   std::accumulate(SectorIntensity[index][block-1].begin(),SectorIntensity[index][block-1].end(),0, Vector_acc)/((int)SectorIntensity[index][block-1].size() + EPSILON);
//                
//                int averagePixelIntensityDifference = std::abs( avgSumOfElementsInFirstBlock - avgSumOfElementsInSecondBlock);
//                
//                if (Sector[index][block].size() > 0) {
//                std::cout << index << "::" << block << "::" << Sector[index][block][0].y << ","<< Sector[index][block][0].x << " = " << averagePixelIntensityDifference << std::endl;
//                }
//                else {
//                    std::cout << index << "::" << block-1 << "::" << Sector[index][block-1][0].y << ","<< Sector[index][block-1][0].x << " = " << averagePixelIntensityDifference << std::endl;
//                }
//                
//                if (averagePixelIntensityDifference > diffInIntensity[index]) {
//                    diffInIntensity[index] = averagePixelIntensityDifference;
//                    std::cout << "Overall difference in intensity = " ;
//                    if (Sector[index][block].size() > 0) {
//                    
//                    std::cout << index << "::" << block << "::" << Sector[index][block][0].y << ","<< Sector[index][block][0].x << " = " << diffInIntensity[index] << std::endl;
//                    }
//                    else {
//                    std::cout << index << "::" << block << "::" << Sector[index][block-1][0].y << ","<< Sector[index][block-1][0].x << " = " << diffInIntensity[index] << std::endl;
//                    }
//                }
//            }
//        }
//    }
//    
//    
//    for (int index = 0; index <360; ++index) {
//        for (int pixelIndex = 0; pixelIndex < Sector[index][5].size(); ++pixelIndex) {
//             int i = Sector[index][5][pixelIndex].y * numOfCols + Sector[index][5][pixelIndex].x;
//             outputPixels[i].r = 1.0;
//            std::cout << Sector[index][5][pixelIndex].y << "," << Sector[index][5][pixelIndex].x << "   ";
//        }
//        std::cout << std::endl;
//    }
//    util->WriteImage2DArrayPixels("output-angle90.exr", outputPixels, numOfCols, numOfRows);
//    
//    delete[] outputPixels;
//    delete util;
    */
}
Ejemplo n.º 19
0
void dinf_upslope_area(
  const Array2D<T> &flowdirs,
  Array2D<U> &area
){
  Array2D<int8_t> dependency;
  std::queue<GridCell> sources;
  ProgressBar progress;

  std::cerr<<"\nA D-infinity Upslope Area"<<std::endl;
  std::cerr<<"C Tarboton, D.G. 1997. A new method for the determination of flow directions and upslope areas in grid digital elevation models. Water Resources Research. Vol. 33. pp 309-319."<<std::endl;

  std::cerr<<"p Setting up the dependency matrix..."<<std::endl;
  dependency.resize(flowdirs);
  dependency.setAll(0);

  std::cerr<<"p Setting up the area matrix..."<<std::endl;
  area.resize(flowdirs);
  area.setAll(0);
  area.setNoData(dinf_NO_DATA);

  bool has_cells_without_flow_directions=false;
  std::cerr<<"p Calculating dependency matrix & setting noData() cells..."<<std::endl;
  progress.start( flowdirs.size() );

  ///////////////////////
  //Calculate the number of "dependencies" each cell has. That is, count the
  //number of cells which flow into each cell.

  #pragma omp parallel for reduction(|:has_cells_without_flow_directions)
  for(int y=0;y<flowdirs.height();y++){
    progress.update( y*flowdirs.width() );
    for(int x=0;x<flowdirs.width();x++){
      //If the flow direction of the cell is NoData, mark its area as NoData
      if(flowdirs.isNoData(x,y)){
        area(x,y)       = area.noData();
        dependency(x,y) = 9;  //TODO: This is an unnecessary safety precaution. This prevents the cell from ever being enqueued (an unnecessary safe guard? TODO)
        continue;             //Only necessary if there are bugs below (TODO)
      }

      //If the cell has no flow direction, note that so we can warn the user
      if(flowdirs(x,y)==NO_FLOW){
        has_cells_without_flow_directions=true;
        continue;
      }

      //TODO: More explanation of what's going on here
      int n_high, n_low;
      int nhx,nhy,nlx,nly;
      where_do_i_flow(flowdirs(x,y),n_high,n_low);
      nhx=x+dinf_dx[n_high];
      nhy=y+dinf_dy[n_high];
      if(n_low!=-1){
        nlx = x+dinf_dx[n_low];
        nly = y+dinf_dy[n_low];
      }
      if( n_low!=-1 && flowdirs.inGrid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.noData() )
        dependency(nlx,nly)++;
      if( flowdirs.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData() )
        dependency(nhx,nhy)++;
    }
  }
  std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl;

  if(has_cells_without_flow_directions)
    std::cerr<<"W \033[91mNot all cells had defined flow directions! This implies that there will be digital dams!\033[39m"<<std::endl;

  ///////////////////////
  //Find those cells which have no dependencies. These are the places to start
  //the flow accumulation calculation.

  std::cerr<<"p Locating source cells..."<<std::endl;
  progress.start( flowdirs.size() );
  for(int y=0;y<flowdirs.height();y++){
    progress.update( y*flowdirs.width() );
    for(int x=0;x<flowdirs.width();x++)
      if(flowdirs(x,y)==flowdirs.noData())
        continue;
      else if(flowdirs(x,y)==NO_FLOW)
        continue;
      else if(dependency(x,y)==0)
        sources.emplace(x,y);
  }
  std::cerr<<"t Source cells located in = "<<progress.stop()<<" s"<<std::endl;





  ///////////////////////
  //Calculate the flow accumulation by "pouring" a cell's flow accumulation
  //value into the cells below it, as indicated by the D-infinite flow routing
  //method.

  std::cerr<<"p Calculating up-slope areas..."<<std::endl;
  progress.start( flowdirs.numDataCells() );
  long int ccount=0;
  while(sources.size()>0){
    auto c = sources.front();
    sources.pop();

    progress.update(ccount++);

    if(flowdirs.isNoData(c.x,c.y))  //TODO: This line shouldn't be necessary since NoData's do not get added below
      continue;

    area(c.x,c.y)+=1;

    if(flowdirs(c.x,c.y)==NO_FLOW)
      continue;

    int n_high,n_low,nhx,nhy,nlx,nly;
    where_do_i_flow(flowdirs(c.x,c.y),n_high,n_low);
    nhx = c.x+dinf_dx[n_high];
    nhy = c.y+dinf_dy[n_high];

    float phigh,plow;
    area_proportion(flowdirs(c.x,c.y), n_high, n_low, phigh, plow);
    if(flowdirs.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData())
      area(nhx,nhy)+=area(c.x,c.y)*phigh;

    if(n_low!=-1){
      nlx = c.x+dinf_dx[n_low];
      nly = c.y+dinf_dy[n_low];
      if(flowdirs.inGrid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.noData()){
        area(nlx,nly)+=area(c.x,c.y)*plow;
        if((--dependency(nlx,nly))==0)
          sources.emplace(nlx,nly);
      }
    }

    if( flowdirs.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData() && (--dependency(nhx,nhy))==0)
      sources.emplace(nhx,nhy);
  }
  std::cerr<<"p Succeeded in = "<<progress.stop()<<" s"<<std::endl;
}
Ejemplo n.º 20
0
void Garbrecht_FindFlats(const Array2D<d8_flowdir_t> &flowdirs, garbrecht_flat_type &flats){
  for(int x=0;x<flowdirs.width();++x)
  for(int y=0;y<flowdirs.height();++y)
    if(flowdirs(x,y)==NO_FLOW)
      flats.emplace_back(x,y);
}
Ejemplo n.º 21
0
void Zhou2015Labels(
  Array2D<elev_t>                         &dem,
  Array2D<label_t>                        &labels,
  std::vector<std::map<label_t, elev_t> > &my_graph,
  uint8_t edge,
  bool    flipH,
  bool    flipV
){
  std::queue<GridCellZ<elev_t> > traceQueue;
  std::queue<GridCellZ<elev_t> > depressionQue;

  label_t current_label = 2;

  labels.setAll(0);

  GridCellZ_pq<elev_t> priorityQueue;

  for(int32_t x=0;x<dem.width();x++){
    const int height = dem.height()-1;
    priorityQueue.emplace(x,0,     dem(x,0     ));
    priorityQueue.emplace(x,height,dem(x,height));
  }

  for(int32_t y=1;y<dem.height()-1;y++){
    const int width = dem.width()-1;
    priorityQueue.emplace(0,    y,dem(0,    y));
    priorityQueue.emplace(width,y,dem(width,y));
  }

  while (!priorityQueue.empty()){
    GridCellZ<elev_t> c = priorityQueue.top();
    priorityQueue.pop();

    auto my_label = labels(c.x,c.y) = GetNewLabelZhou(c.x,c.y,current_label,edge,dem,labels);

    for(int n=1;n<=8;n++){
      int nx = c.x+dx[n];
      int ny = c.y+dy[n];

      if (!dem.inGrid(nx,ny))
        continue;

      WatershedsMeet(my_label,labels(nx,ny),dem(c.x,c.y),dem(nx,ny),my_graph);

      if(labels(nx,ny)!=0)
        continue;

      labels(nx,ny) = labels(c.x,c.y);

      if(dem(nx,ny)<=c.z){ //Depression cell
        dem(nx,ny) = c.z;
        depressionQue.emplace(nx,ny,c.z);
        ProcessPit_onepass(dem,labels,depressionQue,traceQueue,priorityQueue,my_graph);
      } else {          //Slope cell
        traceQueue.emplace(nx,ny,dem(nx,ny));
      }     
      ProcessTraceQue_onepass(dem,labels,traceQueue,priorityQueue,my_graph);
    }
  }

  //Connect the DEM's outside edges to Special Watershed 1. This requires
  //knowing whether the tile has been flipped toe snure that we connect the
  //correct edges.
  if( ((edge & GRID_TOP)    && !flipV) || ((edge & GRID_BOTTOM) && flipV) )
    for(int32_t x=0;x<labels.width();x++)
      WatershedsMeet(labels(x,0),(label_t)1,dem(x,0),dem(x,0),my_graph);

  if( ((edge & GRID_BOTTOM) && !flipV) || ((edge & GRID_TOP)    && flipV) ){
    int bottom_row = labels.height()-1;
    for(int32_t x=0;x<labels.width();x++)
      WatershedsMeet(labels(x,bottom_row),(label_t)1,dem(x,bottom_row),dem(x,bottom_row),my_graph);
  }

  if( ((edge & GRID_LEFT)  && !flipH) || ((edge & GRID_RIGHT) && flipH) )
    for(int32_t y=0;y<labels.height();y++)
      WatershedsMeet(labels(0,y),(label_t)1,dem(0,y),dem(0,y),my_graph);  

  if( ((edge & GRID_RIGHT) && !flipH) || ((edge & GRID_LEFT)  && flipH) ){
    int right_col = labels.width()-1;
    for(int32_t y=0;y<labels.height();y++)
      WatershedsMeet(labels(right_col,y),(label_t)1,dem(right_col,y),dem(right_col,y),my_graph);
  }

  my_graph.resize(current_label);
}
Ejemplo n.º 22
0
void FM_Freeman(
  const Array2D<E> &elevations,
  Array3D<float> &props,
  const double xparam
){
  RDLOG_ALG_NAME<<"Freeman (1991) Flow Accumulation (aka MFD, MD8)";
  RDLOG_CITATION<<"Freeman, T.G., 1991. Calculating catchment area with divergent flow based on a regular grid. Computers & Geosciences 17, 413–422.";
  RDLOG_CONFIG<<"p = "<<xparam;

  props.setAll(NO_FLOW_GEN);
  props.setNoData(NO_DATA_GEN);

  ProgressBar progress;
  progress.start(elevations.size());

  #pragma omp parallel for collapse(2)
  for(int y=0;y<elevations.height();y++)
  for(int x=0;x<elevations.width();x++){
    ++progress;

    if(elevations.isNoData(x,y)){
      props(x,y,0) = NO_DATA_GEN;
      continue;
    }

    if(elevations.isEdgeCell(x,y))
      continue;

    const E e    = elevations(x,y);

    double C = 0;
    for(int n=1;n<=8;n++){
      const int nx = x+dx[n];
      const int ny = y+dy[n];

      if(!elevations.inGrid(nx,ny))
        continue;
      if(elevations.isNoData(nx,ny)) //TODO: Don't I want water to drain this way?
        continue;

      const E ne = elevations(nx,ny);

      if(ne<e){
        const double rise = e-ne;
        const double run  = dr[n];
        const double grad = rise/run;
        const auto cval   = std::pow(grad,xparam);
        props(x,y,n)      = cval;
        C                += cval;
      }
    }

    if(C>0){
      props(x,y,0) = HAS_FLOW_GEN;

      C = 1/C; //TODO

      for(int n=1;n<=8;n++){
        auto &this_por = props(x,y,n);
        if(this_por>0)
          this_por *= C;
        else
          this_por = 0;
      }
    }
  }
  progress.stop();
}