PPMImage PPMImage::resize(int out_rows, int out_columns)const{ PPMImage output = PPMImage(magic, meta, out_rows, out_columns); for (int r=0; r < out_rows; r++){ for (int c=0; c < out_columns; c++){ // Convert r,c into old style coordinates float r_real = (float)r / out_rows * rows; float c_real = (float)c / out_columns * columns; int r_0 = floor(r_real); int r_1 = ceil(r_real); int c_0 = floor(c_real); int c_1 = ceil(c_real); float r_d = r_real - r_0; float c_d = c_real - c_0; /* tl--t------tr * | | | * |---p------| * | | | * | | | * | | | * bl--b------br */ float tl, tr, bl, br; float t, b, R, G, B; tl = (*this)[r_0][c_0].r; tr = (*this)[r_0][c_1].r; bl = (*this)[r_1][c_0].r; br = (*this)[r_1][c_1].r; t = tr + (tr - tl)*c_d; b = br + (br - bl)*c_d; R = b + (b - t)*r_d; tl = (*this)[r_0][c_0].g; tr = (*this)[r_0][c_1].g; bl = (*this)[r_1][c_0].g; br = (*this)[r_1][c_1].g; t = tr + (tr - tl)*c_d; b = br + (br - bl)*c_d; G = b + (b - t)*r_d; tl = (*this)[r_0][c_0].b; tr = (*this)[r_0][c_1].b; bl = (*this)[r_1][c_0].b; br = (*this)[r_1][c_1].b; t = tr + (tr - tl)*c_d; b = br + (br - bl)*c_d; B = b + (b - t)*r_d; output[r][c] = RGBPixel(R,G,B); // r / rows * this->rows() same for cols // find the 4 vals adjacent and the distances from each // Do a weighted sum (possibly split into x and y separately) // Set output[r][c] = val; } } return output; }
RGBImageView* visualize(const T &src ) { typedef typename T::value_type value_type; int x,y; RGBImageData* dest_data = new RGBImageData(src.size(), src.origin()); RGBImageView* dest = new RGBImageView(*dest_data); RGBPixel blackval = black(*dest); RGBPixel whiteval = white(*dest); for (y = 0; y < (int)src.nrows(); y++) for (x = 0; x < (int)src.ncols(); x++) { switch (src.get(Point(x,y))) { case (1) : dest->set(Point(x,y),blackval); break; // black, music case (2) : dest->set(Point(x,y),RGBPixel(228, 228, 228)); break; // light grey, border case (4) : dest->set(Point(x,y),RGBPixel(0, 127, 0)); break; // dark green, ornate letter case (8) : dest->set(Point(x,y),RGBPixel(0, 255, 0)); break; // light green, text in staff case (16) : dest->set(Point(x,y),RGBPixel(255, 127, 0)); break; // orange, lyrics case (32) : dest->set(Point(x,y),RGBPixel(255, 227, 0)); break; // yellow, title case (64) : dest->set(Point(x,y),RGBPixel(0, 0, 255)); break; // blue, UNUSED case (128) : dest->set(Point(x,y),RGBPixel(255, 0, 255)); break; // magenta, UNUSED default : dest->set(Point(x,y),whiteval); } } return dest; }
PPMImage PPMImage::convolve(const PixelGrid<MonoPixel> kernel)const{ std::cout << "Convolving" << std::endl; PPMImage conv(magic, meta, rows-kernel.rows+1, columns-kernel.columns+1); // std::cout << conv.rows << ' ' << conv.columns << std::endl; for (int r = kernel.rows-1; r < rows; r++){ for (int c = kernel.columns-1; c < columns; c++){ float red = 0; float green = 0; float blue = 0; for (int x = 0; x < kernel.rows; x++){ for (int y = 0; y < kernel.columns; y++){ red += kernel[x][y].i * (*this)[r-x][c-y].r; green += kernel[x][y].i * (*this)[r-x][c-y].g; blue += kernel[x][y].i * (*this)[r-x][c-y].b; } } conv[r-kernel.rows+1][c-kernel.columns+1] = RGBPixel(red, green, blue); } } // std::cout << "end of convolution" << std::endl; return conv; }