diff --git a/src/seam-carving.cpp b/src/seam-carving.cpp index c76485b..d233292 100644 --- a/src/seam-carving.cpp +++ b/src/seam-carving.cpp @@ -39,6 +39,7 @@ void export_image(const char* filename, const void* data, int width, int height, /** e_1 energy, energy is always normalized between 0 and 1 */ std::vector energy_e1(std::vector source, int width, int height, int nbChannels) { + int nbColorChannels = nbChannels > 3 ? 3 : nbChannels; // nombre de canaux, excepté le alpha std::vector energy(width*height); float max_energy = 0; @@ -51,7 +52,7 @@ std::vector energy_e1(std::vector source, int width, int h auto indexPixel_right = (i+1 < width) ? nbChannels*(width*j+(i+1)) : indexPixel; energy[width*j+i] = 0; - for (auto ch=0; ch < nbChannels; ch++) { + for (auto ch=0; ch < nbColorChannels; ch++) { // Le alpha n'est pas pris en compte dans l'énergie energy[width*j+i] += ( fabs((float)source[indexPixel_up+ch] - source[indexPixel+ch]) +fabs((float)source[indexPixel_down+ch] - source[indexPixel+ch]) @@ -160,12 +161,11 @@ std::vector carving_step(const std::vector source, std::vect int cur_j = 0; for (auto j=0; cur_j < dim_large-1 && j < dim_large; j++) { if (!blacklist[im_index(i, j)]) { - int out_pixelIndex = 3*(vertical ? ((width-1)*i + cur_j) : (width*cur_j + i)); - int src_pixelIndex = 3*im_index(i, j); + int out_pixelIndex = nbChannels*(vertical ? ((width-1)*i + cur_j) : (width*cur_j + i)); + int src_pixelIndex = nbChannels*im_index(i, j); - output[ out_pixelIndex ] = source[ src_pixelIndex ]; - output[out_pixelIndex+1] = source[src_pixelIndex+1]; - output[out_pixelIndex+2] = source[src_pixelIndex+2]; + for (auto ch=0; ch < nbChannels; ch++) + output[out_pixelIndex+ch] = source[src_pixelIndex+ch]; cur_j++; } } @@ -175,17 +175,18 @@ std::vector carving_step(const std::vector source, std::vect void seam_carving(unsigned char* source, int width, int height, int nbChannels, const char* out_filename, int nbSeams, bool vertical, bool test_energy=false) { + int nbColorChannels = nbChannels > 3 ? 3 : nbChannels; int curWidth = width; int curHeight = height; int dim_large = vertical ? width : height; int dim_long = vertical ? height : width; - std::vector carve_output(width*height*3); // Receives at each step the newly carved image + std::vector carve_output(width*height*nbChannels); // Receives at each step the newly carved image std::vector source_img(width*height*nbChannels); // Contains at each step the carved image std::vector complete_blacklist(width*height); // Contains all removed pixels, for "test_energy" std::vector ini_energy; // Contains the initial energy, only for "test_energy" - std::vector test_energy_output(width*height*3); // Final output for "test_energy" + std::vector test_energy_output(width*height*nbChannels); // Final output for "test_energy" for (auto i=0; i < width*height*nbChannels; i++) { source_img[i] = source[i]; } @@ -196,12 +197,13 @@ void seam_carving(unsigned char* source, int width, int height, int nbChannels, //* Prepare final output for (auto k=0; k < width*height; k++) { - //output[3*k] = source_img[3*k]/3; //* Uncomment if you prefer to see darkened source image - //output[3*k+1] = source_img[3*k+1]/3; - //output[3*k+2] = source_img[3*k+2]/3; - test_energy_output[3*k] = ini_energy[k]*255; - test_energy_output[3*k+1] = ini_energy[k]*255; - test_energy_output[3*k+2] = ini_energy[k]*255; + //for (auto i=0; i < nbColorChannels; i++) //* Uncomment if you prefer to see darkened source image + // output[nbChannels*k+i] = source_img[nbChannels*k+i]/nbChannels; + for (auto i=0; i < nbColorChannels; i++) + test_energy_output[nbChannels*k+i] = ini_energy[k]*255; + + if (nbChannels==4) + test_energy_output[nbChannels*k+3] = source_img[nbChannels*k+3]; } } @@ -224,7 +226,7 @@ void seam_carving(unsigned char* source, int width, int height, int nbChannels, assert(cur_j == opt_seam[i]); // Else, j == width and cur_j is not in the source image.. complete_blacklist[im_index(i, j)] = true; - test_energy_output[3*im_index(i, j)] = 255; // Set carved pixel to red + test_energy_output[nbChannels*im_index(i, j)] = 255; // Set carved pixel to red } } bar.increment(); @@ -261,10 +263,7 @@ int main(int argc, char **argv) { unsigned char *source = stbi_load(sourceImage.c_str(), &width, &height, &nbChannels, 0); nbSeams = min(nbSeams, width); - if (nbChannels < 3) { // TODO : really ? - std::cout<< "Input images must be RGB images."<