void nearestNeighbour(Pixels &pixels, int channel) { for(int i=1; i<pixels.size(); i++) { for(int j=1; j<pixels[i].size(); j++) { if(i%2 == 0) { if(j%2 == 0) { if(channel == RED) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j-1]); } else if(channel == GREEN) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j]); } } else { if(channel == RED) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j]); } else if(channel == BLUE) { pixels[i][j].setChannelWithPixel(channel, pixels[i][j-1]); } } } else { if(j%2 == 0) { if(channel == RED) { pixels[i][j].setChannelWithPixel(channel, pixels[i][j-1]); } else if(channel == BLUE) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j]); } } else { if(channel == BLUE) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j-1]); } else if(channel == GREEN) { pixels[i][j].setChannelWithPixel(channel, pixels[i-1][j]); } } } } } }
SplineFunction::SplineFunction(Pixels& pixels, int direction, int i) : pixels(pixels) { // si es vertical, las columnas serian las filas de la imagen cols = direction == HORIZONTAL ? pixels[0].size() : pixels.size(); // saco los bordes if(cols % 2 == 0) { points_count = cols/2; } else { points_count = cols/2 - (i+1)%2; // si la fila es par hay un pixel verde menos } splines_count = points_count-1; h = 2; c_matrix = new vector<vector<double>>(points_count, vector<double>(points_count)); v = new vector<double>(points_count); a.resize(points_count); b.resize(points_count); c.resize(points_count); d.resize(points_count); if(direction == HORIZONTAL) DoHorizontal(i); else DoVertical(i); delete(c_matrix); delete(v); }
void directional_interpolation(Pixels& pixels) { int rows = pixels.size(); int cols = pixels[0].size(); vector<SplineFunction*> horizontal_splines(rows); vector<SplineFunction*> vertical_splines(cols); horizontal_splines[0] = NULL; for(int i = 1; i < rows-1; i++) { horizontal_splines[i] = new SplineFunction(pixels, HORIZONTAL, i); } horizontal_splines[rows-1] = NULL; vertical_splines[0] = NULL; for(int i = 1; i < cols-1; i++) { vertical_splines[i] = new SplineFunction(pixels, VERTICAL, i); } vertical_splines[cols-1] = NULL; for(int i = 1; i < rows-1; i++) { for(int j = 1; j < cols-1; j++) { if((i % 2 == 0 && j % 2 == 1) || (i % 2 == 1 && j % 2 == 0)) continue; // avoid green locations double gradient_v = (i >=2 && i <= rows-3) ? abs(pixels[i+2][j].green - pixels[i-2][j].green) : 0; double gradient_h = (j >=2 && j <= cols-3) ? abs(pixels[i][j+2].green - pixels[i][j-2].green) : 0; double value_v = vertical_splines[j]->eval(i); double value_h = horizontal_splines[i]->eval(j); double avg; if(gradient_h == gradient_v) avg = (value_h + value_v)/2; else { avg = value_h * (gradient_v / (gradient_h + gradient_v)) + value_v * (gradient_h / (gradient_h + gradient_v)); } pixels[i][j].green = MAX(0, MIN(255, round(avg))); } delete horizontal_splines[i]; } for(int i = 1; i < cols-1; i++) { delete vertical_splines[i]; } }
void bilinear(Pixels &pixels, int channel) { int color; for(int i=1; i<pixels.size()-1; i++) { for(int j=1; j<pixels[i].size()-1; j++) { if(i%2 == 0) { if(j%2 == 0) { if(channel == RED) { color = (pixels[i-1][j-1].getChannel(channel) + pixels[i-1][j+1].getChannel(channel) + pixels[i+1][j-1].getChannel(channel) + pixels[i+1][j+1].getChannel(channel)) / 4; pixels[i][j].setChannelWithColor(channel, color); } else if(channel == GREEN) { color = (pixels[i-1][j].getChannel(channel) + pixels[i][j-1].getChannel(channel) + pixels[i][j+1].getChannel(channel) + pixels[i+1][j].getChannel(channel)) / 4; pixels[i][j].setChannelWithColor(channel, color); } } else { if(channel == RED) { color = (pixels[i-1][j].getChannel(channel) + pixels[i+1][j].getChannel(channel)) / 2; pixels[i][j].setChannelWithColor(channel, color); } else if(channel == BLUE) { color = (pixels[i][j-1].getChannel(channel) + pixels[i][j+1].getChannel(channel)) / 2; pixels[i][j].setChannelWithColor(channel, color); } } } else { if(j%2 == 0) { if(channel == RED) { color = (pixels[i][j-1].getChannel(channel) + pixels[i][j+1].getChannel(channel)) / 2; pixels[i][j].setChannelWithColor(channel, color); } else if(channel == BLUE) { color = (pixels[i-1][j].getChannel(channel) + pixels[i+1][j].getChannel(channel)) / 2; pixels[i][j].setChannelWithColor(channel, color); } } else { if(channel == BLUE) { color = (pixels[i-1][j-1].getChannel(channel) + pixels[i-1][j+1].getChannel(channel) + pixels[i+1][j-1].getChannel(channel) + pixels[i+1][j+1].getChannel(channel)) / 4; pixels[i][j].setChannelWithColor(channel, color); } else if(channel == GREEN) { color = (pixels[i-1][j].getChannel(channel) + pixels[i][j-1].getChannel(channel) + pixels[i][j+1].getChannel(channel) + pixels[i+1][j].getChannel(channel)) / 4; pixels[i][j].setChannelWithColor(channel, color); } } } } } }
void MHC(Pixels& pixels) // only supports green channel { int color, rhombus_sum; double gradient; bilinear(pixels, GREEN); // se arranca con la bilinear for(int i=2; i<pixels.size()-2; i++) { for(int j=2; j<pixels[i].size()-2; j++) { if((i % 2 == 0 && j % 2 == 1) || (i % 2 == 1 && j % 2 == 0)) continue; // green locations color = i % 2 == 0 ? BLUE : RED; rhombus_sum = 0; rhombus_sum += pixels[i][j-2].getChannel(color); rhombus_sum += pixels[i][j+2].getChannel(color); rhombus_sum += pixels[i-2][j].getChannel(color); rhombus_sum += pixels[i+2][j].getChannel(color); gradient = pixels[i][j].getChannel(color) - rhombus_sum / 4.0; pixels[i][j].green += int(ALPHA * gradient); pixels[i][j].green = MAX(0, MIN(255, pixels[i][j].green)); } } }