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); } } }
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]; }
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() ; }