Beispiel #1
0
void Image::Shift(double sx, double sy)
{
  for(int y = 0; y < height; y++) {
    int y_ = (0 < sy) ? height - 1 - y : y;

    for(int x = 0; x < width; x++) {
      int x_ = (0 < sx) ? width - 1 - x : x;

      if(sx == floor(sx) && sy == floor(sy))
        GetPixel(x_, y_) = (ValidCoord(x_ - (int) sx, y_ - (int) sy)) 
          ? GetPixel(x_ - (int) sx, y_ - (int) sy) : Pixel(0, 0, 0);

      else {
        if(sampling_method == IMAGE_SAMPLING_HAT) {
          if(ValidCoord(x_ - (int) sx, y_ - (int) sy)) {
            float h_r, h_g, h_b, h_all, h_tmp;
            h_r = h_g = h_b = h_all = 0.0f;
            for(int c = -1; c < 2; c++) {
              for(int r = -1; r < 2; r++) {
                if(ValidCoord(x_ - (int) sx + r, y_ - (int) sy + c)) {
                  h_tmp = hat(-((int) sx) + r + (float) sx)
                    * hat(-((int) sy) + c + (float) sy);
                  h_all += h_tmp;
                  h_r += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).r * h_tmp;
                  h_g += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).g * h_tmp;
                  h_b += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).b * h_tmp;
                }
              }
            }
            GetPixel(x_, y_).SetClamp(h_r / h_all, h_g / h_all, h_b / h_all);
          }
          else GetPixel(x_, y_) = Pixel(0, 0, 0);
        }
        else if (sampling_method == IMAGE_SAMPLING_MITCHELL) {
          if (ValidCoord(x_ - (int) sx, y_ - (int) sy)) {
            float h_r, h_g, h_b, h_all, h_tmp;
            h_r = h_g = h_b = h_all = 0.0f;
            for(int c = -4; c < 5; c++) {
              for(int r = -4; r < 5; r++) {
                if(ValidCoord(x_ - (int) sx + r, y_ - (int) sy + c)) {
                  h_tmp = mitchell(-((int) sx) + r + (float) sx)
                    * mitchell(-((int) sy) + c + (float) sy);
                  h_all += h_tmp;
                  h_r += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).r * h_tmp;
                  h_g += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).g * h_tmp;
                  h_b += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).b * h_tmp;
                }
              }
            }
            GetPixel(x_, y_).SetClamp(h_r / h_all, h_g / h_all, h_b / h_all);
          }
          else GetPixel(x_, y_) = Pixel(0, 0, 0);
        }
      }
    }
  }
}
void BlockMap::ResetConnectivity() {
  for (int r = 0; r < Rows(); r++) {
    for (int c = 0; c < Cols(); c++) {
      Block& currBlock = m_BlockMatrix[r][c];

      // Set reachable neighbors
      currBlock.neighborOffsets.clear();
      Vector2 lOffset(0, -1);
      Vector2 rOffset(0, 1);
      Vector2 tOffset(-1, 0);
      Vector2 bOffset(1, 0);
      if (ValidCoord(currBlock.coord + lOffset)) currBlock.neighborOffsets.insert(lOffset);
      if (ValidCoord(currBlock.coord + rOffset)) currBlock.neighborOffsets.insert(rOffset);
      if (ValidCoord(currBlock.coord + tOffset)) currBlock.neighborOffsets.insert(tOffset);
      if (ValidCoord(currBlock.coord + bOffset)) currBlock.neighborOffsets.insert(bOffset);
    }
  }
}
Beispiel #3
0
void Image::Convolve(int *filter, int n, int normalization, int absval) {
  // This is my definition of an auxiliary function for image convolution 
  // with an integer filter of width n and certain normalization.
  // The absval param is to consider absolute values for edge detection.
  
  // It is helpful if you write an auxiliary convolve function.
  // But this form is just for guidance and is completely optional.
  // Your solution NEED NOT fill in this function at all
  // Or it can use an alternate form or definition
  int sumr, sumg, sumb;
  sumr = sumg = sumb = 0;

  for (int h = 0; h < height; h++) {
    for (int w = 0; w < width; w++) {
      for (int p = 0; p < n; p++) {
        for (int q = 0; q < n; q++) {
          int x = 0;
          int y = 0;
          int mp = 0;
          if (absval) {
            mp = 2;
            x = Lim(w - (p - mp), width);
            y = Lim(h - (q - mp), height);
            //x = w - (p - mp);
            //y = h - (q - mp); 
          }
          else {
            mp = n / 2;
            x = LimRef(w - (p - mp), width);
            y = LimRef(h - (q - mp), height);
          }
          if (!ValidCoord(x, y)) continue;
          Pixel curr = GetPixel(x, y);
          int filt = filter[q * n + p];
          sumr += (int)curr.r * filt;
          sumg += (int)curr.g * filt;
          sumb += (int)curr.b * filt;
        }
      }
      if (absval) {
        sumr = abs(sumr);
        sumg = abs(sumg);
        sumb = abs(sumb);
      }
      GetPixel(w, h).SetClamp(sumr / normalization, sumg / normalization, sumb / normalization);
      sumr = sumg = sumb = 0;
    }
  }
}
Block& BlockMap::GetBlock(const Vector2& vec) {
  ASSERT(ValidCoord(vec));
  return m_BlockMatrix[vec.r][vec.c];
}
Block& BlockMap::GetBlock(int r, int c) {
  ASSERT(ValidCoord(Vector2(r, c)));
  return m_BlockMatrix[r][c];
}
Beispiel #6
0
Pixel Image::Sample (double u, double v, double sx, double sy)
{
  // To sample the image in scale and shift
  // This is an auxiliary function that it is not essential you fill in or 
  // you may define it differently.
  // u and v are the floating point coords of the points to be sampled.
  // sx and sy correspond to the scale values. 
  // In the assignment, it says implement MinifyX MinifyY MagnifyX MagnifyY
  // separately.  That may be a better way to do it.
  // This hook is primarily to get you thinking about that you have to have 
  // some equivalent of this function.

  if (sampling_method == IMAGE_SAMPLING_POINT) {
    // Your work here
    return GetPixel((int) round(u / sx), (int) round(v / sy));
  }

  else if (sampling_method == IMAGE_SAMPLING_HAT) {
    int sumr, sumg, sumb;
    sumr = sumg = sumb = 0;
    float xdif = 0;
    float ydif = 0;
    if (sx < 1)
      xdif = 1 / sx;
    else
      xdif = 1;
    if (sy < 1)
      ydif = 1 / sy;
    else
      ydif = 1;
    float n = 0;
    for (int x = round(u / sx - xdif); x <= round(u / sx + xdif); x++) {
      float hu = hat((x - u / sx) / xdif);
      for (int y = round(v / sy - ydif); y <= round(v / sy + ydif); y++) {
        float hv = hat((y - v / sy) / ydif);
        float h = hu * hv;
        n += h;
        if (!ValidCoord(x, y))
          continue;
        Pixel curr = GetPixel(x, y);
        sumr += h * curr.r;
        sumg += h * curr.g;
        sumb += h * curr.b;
      }
    }
    sumr /= n;
    sumg /= n;
    sumb /= n;
    if (sumr > 255)
      sumr = 255;
    else if (sumr < 0)
      sumr = 0;
    if (sumg > 255)
      sumg = 255;
    else if (sumg < 0)
      sumg = 0;
    if (sumb > 255)
      sumb = 255;
    else if (sumb < 0)
      sumb = 0;
    return Pixel(sumr, sumg, sumb);
  }

  else if (sampling_method == IMAGE_SAMPLING_MITCHELL) {
    int sumr, sumg, sumb;
    sumr = sumg = sumb = 0;
    float xdif = 0;
    float ydif = 0;
    if (sx < 1)
      xdif = 1 / sx;
    else
      xdif = 1;
    if (sy < 1)
      ydif = 1 / sy;
    else
      ydif = 1;
    float n = 0;
    for (int x = round(u / sx - xdif); x <= round(u / sx + xdif); x++) {
      float hu = mitchell((x - u / sx) / xdif);
      for (int y = round(v / sy - ydif); y <= round(v / sy + ydif); y++) {
        float hv = mitchell((y - v / sy) / ydif);
        float h = hu * hv;
        n += h;
        if (!ValidCoord(x, y))
          continue;
        Pixel curr = GetPixel(x, y);
        sumr += h * curr.r;
        sumg += h * curr.g;
        sumb += h * curr.b;
      }
    }
    sumr /= n;
    sumg /= n;
    sumb /= n;
    if (sumr > 255)
      sumr = 255;
    else if (sumr < 0)
      sumr = 0;
    if (sumg > 255)
      sumg = 255;
    else if (sumg < 0)
      sumg = 0;
    if (sumb > 255)
      sumb = 255;
    else if (sumb < 0)
      sumb = 0;
    return Pixel(sumr, sumg, sumb);
  }

  else {
    fprintf(stderr,"I don't understand what sampling method is used\n") ;
    exit(1) ;
  }

  return Pixel() ;
}