Add --until-mask-removal
Are all seams contributing to mask ?
This commit is contained in:
parent
a7d2c74a89
commit
7b07f66bfb
@ -12,9 +12,12 @@
|
|||||||
#include <SimpleProgressBar.hpp>
|
#include <SimpleProgressBar.hpp>
|
||||||
#include <stb_image_write.h>
|
#include <stb_image_write.h>
|
||||||
|
|
||||||
|
#define DEFAULT_SEAMS 1
|
||||||
|
|
||||||
// Global flags
|
// Global flags
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
bool test_energy = false;
|
bool test_energy = false;
|
||||||
|
bool until_mask_removal = false;
|
||||||
int max_step = 1;
|
int max_step = 1;
|
||||||
|
|
||||||
// Get index for any table indexed by [width*(i : height) + (j : width)], but a
|
// Get index for any table indexed by [width*(i : height) + (j : width)], but a
|
||||||
@ -310,6 +313,18 @@ std::vector<std::pair<int, float>> mask_energy(std::vector<float> energy,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool does_seam_remove_mask(unsigned char* mask, int width, int height, int nbChannels,
|
||||||
|
std::vector<int> opt_seam, bool vertical)
|
||||||
|
{
|
||||||
|
int dim_large = vertical ? width : height;
|
||||||
|
int dim_long = vertical ? height : width;
|
||||||
|
|
||||||
|
for (int i=0; i < dim_long; i++) {
|
||||||
|
if (mask[im_index(i, opt_seam[i])] == 0) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void seam_carving(unsigned char *source, int width, int height, int nbChannels,
|
void seam_carving(unsigned char *source, int width, int height, int nbChannels,
|
||||||
const char *out_filename, int nbSeams, bool vertical, unsigned char* mask=nullptr) {
|
const char *out_filename, int nbSeams, bool vertical, unsigned char* mask=nullptr) {
|
||||||
int nbColorChannels = nbChannels > 3 ? 3 : nbChannels;
|
int nbColorChannels = nbChannels > 3 ? 3 : nbChannels;
|
||||||
@ -384,16 +399,23 @@ void seam_carving(unsigned char *source, int width, int height, int nbChannels,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleProgressBar::ProgressBar bar(nbSeams);
|
SimpleProgressBar::ProgressBar bar(until_mask_removal ? dim_large : nbSeams);
|
||||||
bar.print();
|
bar.print();
|
||||||
|
|
||||||
for (auto seam_index = 0; seam_index < nbSeams; seam_index++) {
|
auto seam_index = 0;
|
||||||
|
while (seam_index++ < nbSeams || until_mask_removal) {
|
||||||
std::vector<int> opt_seam;
|
std::vector<int> opt_seam;
|
||||||
if (mask) {
|
if (mask) {
|
||||||
opt_seam = carving_step(
|
opt_seam = carving_step(
|
||||||
source_img, masked_energy, output_img, output_masked_energy,
|
source_img, masked_energy, output_img, output_masked_energy,
|
||||||
curWidth, curHeight, nbChannels, nbColorChannels, vertical
|
curWidth, curHeight, nbChannels, nbColorChannels, vertical
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
until_mask_removal &&
|
||||||
|
!does_seam_remove_mask(mask, width, height, nbChannels, opt_seam, vertical)
|
||||||
|
) break;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
opt_seam = carving_step(
|
opt_seam = carving_step(
|
||||||
source_img, source_energy, output_img, output_energy,
|
source_img, source_energy, output_img, output_energy,
|
||||||
@ -446,7 +468,7 @@ int main(int argc, char **argv) {
|
|||||||
std::string maskImage;
|
std::string maskImage;
|
||||||
std::string sourceImage;
|
std::string sourceImage;
|
||||||
std::string outputImage = "output.png";
|
std::string outputImage = "output.png";
|
||||||
int nbSeams = 1;
|
int nbSeams = DEFAULT_SEAMS;
|
||||||
bool vertical = false;
|
bool vertical = false;
|
||||||
|
|
||||||
app.add_option("-s,--source", sourceImage, "Source image")
|
app.add_option("-s,--source", sourceImage, "Source image")
|
||||||
@ -466,6 +488,8 @@ int main(int argc, char **argv) {
|
|||||||
app.add_flag("--silent", silent, "No verbose messages");
|
app.add_flag("--silent", silent, "No verbose messages");
|
||||||
app.add_flag("--test-energy", test_energy,
|
app.add_flag("--test-energy", test_energy,
|
||||||
"Don't resize image, just try the specified energy function");
|
"Don't resize image, just try the specified energy function");
|
||||||
|
app.add_flag("-u,--until-mask-removal", until_mask_removal,
|
||||||
|
"Carve the image until there are no more red pixels in the mask");
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
// Image loading
|
// Image loading
|
||||||
@ -505,6 +529,14 @@ int main(int argc, char **argv) {
|
|||||||
//* . (1) nothing in particular
|
//* . (1) nothing in particular
|
||||||
//* . (0) we want to remove the pixel
|
//* . (0) we want to remove the pixel
|
||||||
}
|
}
|
||||||
|
if (until_mask_removal && maskImage.empty()) {
|
||||||
|
std::cerr << "Flag --until-mask-removal but no mask provided." << std::endl;
|
||||||
|
until_mask_removal = false;
|
||||||
|
}
|
||||||
|
if (until_mask_removal && nbSeams != DEFAULT_SEAMS) {
|
||||||
|
std::cerr << "Flag --nb-seams specified but --until-mask-removal provided." << std::endl;
|
||||||
|
nbSeams = DEFAULT_SEAMS;
|
||||||
|
}
|
||||||
|
|
||||||
nbSeams = std::min(nbSeams, vertical ? width-1 : height-1); // We want to keep at least one row or column
|
nbSeams = std::min(nbSeams, vertical ? width-1 : height-1); // We want to keep at least one row or column
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user