Пример #1
0
double FastMarchingMethod(Image<Color> &input, Image<DistancePixel> &distance_image) {
  
  //
  // IMPLEMENT THIS FUNCTION
  //
  // (using the advancing front method, and a priority queue)
  //
  DistancePixel_PriorityQueue reds; //list of surronding pixels
  std::vector<DistancePixel*> black_pixels; //list of known distance value pixels
  int w = input.Width();
  int h = input.Height();
  double answer = 0;
  //initialize black pixels to 0, all other to double max value, store black pixel locations
  for (int i=0;i<w;i++) { 
    for (int n=0;n<h;n++) {
      if (input.GetPixel(i,n).isBlack()) {
        DistancePixel* p = &distance_image.GetPixel(i,n);
        p->setX(i);
        p->setY(n);
        p->setValue(0);
        black_pixels.push_back(p);
      }
      else {
        DistancePixel* p = &distance_image.GetPixel(i,n);
        p->setX(i);
        p->setY(n);
        p->setValue(std::numeric_limits<double>::max());
      }
    }
  }
  for (unsigned int i=0;i<black_pixels.size();i++) { //propogate from black pixels
    Propogate(distance_image,black_pixels[i],reds);
  }
  while (reds.size()!=0) { //until queue is empty
    if (reds.top()->getValue()>answer) {
      answer = reds.top()->getValue();
    }
    black_pixels.push_back(reds.top()); //add minimum element in queue to known values
    reds.pop(); //remove from queue
    Propogate(distance_image,black_pixels[black_pixels.size()-1],reds); //propogate from new location
  }
  return answer;
}
Пример #2
0
double FastMarchingMethod(Image<Color> &input, Image<DistancePixel> &distance_image) {
  int w = input.Width();
  int h = input.Height();
  std::vector<std::pair<int, int> > blackPixels;
  for (int x = 0; x < w; x++) 
    {
       for (int y = 0; y < h; y++) 
       {
          const Color& d = input.GetPixel(x,y);
          DistancePixel& beefy = distance_image.GetPixel(x,y);   
          beefy.setX(x);
          beefy.setY(y);
          // skip all pixels that are not bladk
          if (d.isBlack())
          {
            blackPixels.push_back(std::make_pair(x,y));
            beefy.setValue(0);
            beefy.makeFinalValue();
          }
          else
            beefy.setValue(1000000); // ome million m**********r          
        }
    }
  double answer = 0;
  DistancePixel_PriorityQueue theQueue;
  for(int x = 0; x < blackPixels.size(); x++){
    int b = blackPixels[x].first;
    int j = blackPixels[x].second;
    DistancePixel& tempPixel = distance_image.GetPixel(b,j);
    std::vector<std::pair<int, int> > nearbyPixels = getNearbyPixels(b,j, distance_image);
    for (int v = 0; v < nearbyPixels.size(); v++)
    {
      int xVal = nearbyPixels[v].first;
      int yVal = nearbyPixels[v].second;
      DistancePixel& somePixelWorkin = distance_image.GetPixel(xVal,yVal);
      double distance = tempPixel.getValue() + (sqrt((b-xVal)*(b-xVal) + (j-yVal)*(j-yVal)));
      if(somePixelWorkin.getValue() > distance){
        somePixelWorkin.setValue(distance);
        if(!theQueue.in_heap(&somePixelWorkin))
          theQueue.push(&somePixelWorkin);
        else
          theQueue.update_position(&somePixelWorkin);
      }
    }
  }
  while(theQueue.size() > 0){
    const DistancePixel* aPixel = theQueue.top();
    int b = aPixel->getX();
    int j = aPixel->getY();
    DistancePixel& anotherPixel = distance_image.GetPixel(b, j);
    anotherPixel.makeFinalValue();
    std::vector<std::pair<int, int> > nearbyPixels = getNearbyPixels(b,j, distance_image);
    for (int v = 0; v < nearbyPixels.size(); v++)
    {
      int xVal = nearbyPixels[v].first;
      int yVal = nearbyPixels[v].second;
      DistancePixel& somePixelWorkin = distance_image.GetPixel(xVal,yVal);
      double distance = anotherPixel.getValue() + (sqrt((b-xVal)*(b-xVal) + (j-yVal)*(j-yVal)));
      if(somePixelWorkin.getValue() > distance){
        somePixelWorkin.setValue(distance);
        if(!theQueue.in_heap(&somePixelWorkin))
          theQueue.push(&somePixelWorkin);
        else
          theQueue.update_position(&somePixelWorkin);
      }
    }
    answer = std::max(answer, anotherPixel.getValue());
    theQueue.pop();
  }
  return answer;
}
Пример #3
0
//takes pixel and adds surronding valid pixels to priority queue
void Propogate(Image<DistancePixel> &distance_image, DistancePixel* & pix,
               DistancePixel_PriorityQueue & reds) {
  int w = distance_image.Width();
  int h = distance_image.Height();
  int x = pix->getX();
  int y = pix->getY();
  double d = pix->getValue();
  DistancePixel* p;
  if ((x-1) >= 0 and (y-1) >= 0) { //top-left
    p = &distance_image.GetPixel(x-1,y-1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (y-1 >= 0) { //top
    p = &distance_image.GetPixel(x,y-1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (x+1 < w and y-1 >= 0) { //top-right
    p = &distance_image.GetPixel(x+1,y-1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (x-1 >= 0) { //left
    p = &distance_image.GetPixel(x-1,y);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (x+1 < w) { //right
    p = &distance_image.GetPixel(x+1,y);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (x-1 >= 0 and y+1 < h) { //bottom-left
    p = &distance_image.GetPixel(x-1,y+1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (y+1 < h) { //bottom
    p = &distance_image.GetPixel(x,y+1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
  if (x+1 < w and y+1 < h) { //top-right
    p = &distance_image.GetPixel(x+1,y+1);
    double distance = sqrt((x-p->getX())*(x-p->getX()) + (y-p->getY())*(y-p->getY()));
    
    if (p->getValue() > (d+distance)) {
      p->setValue(d+distance);
      if (reds.in_heap(p)) {
        reds.update_position(p);
      }
      else {
        reds.push(p);        
      }
    }
  }
}