Accept transparency channel
This commit is contained in:
parent
28a71c5dd2
commit
964d597bdd
@ -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<float> energy_e1(std::vector<unsigned char> source, int width, int height, int nbChannels) {
|
||||
int nbColorChannels = nbChannels > 3 ? 3 : nbChannels; // nombre de canaux, excepté le alpha
|
||||
std::vector<float> energy(width*height);
|
||||
|
||||
float max_energy = 0;
|
||||
@ -51,7 +52,7 @@ std::vector<float> energy_e1(std::vector<unsigned char> 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<int> carving_step(const std::vector<unsigned char> 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<int> carving_step(const std::vector<unsigned char> 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<unsigned char> carve_output(width*height*3); // Receives at each step the newly carved image
|
||||
std::vector<unsigned char> carve_output(width*height*nbChannels); // Receives at each step the newly carved image
|
||||
std::vector<unsigned char> source_img(width*height*nbChannels); // Contains at each step the carved image
|
||||
std::vector<bool> complete_blacklist(width*height); // Contains all removed pixels, for "test_energy"
|
||||
std::vector<float> ini_energy; // Contains the initial energy, only for "test_energy"
|
||||
std::vector<unsigned char> test_energy_output(width*height*3); // Final output for "test_energy"
|
||||
std::vector<unsigned char> 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."<<std::endl;
|
||||
exit(1);
|
||||
}
|
||||
//std::cout << "channels: " << nbChannels << std::endl;
|
||||
|
||||
seam_carving(source, width, height, nbChannels, outputImage.c_str(), nbSeams, vertical, test_energy=test_energy);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user