Load mask

This commit is contained in:
augustin64 2025-04-01 18:27:35 +02:00
parent 1d2a139d4c
commit 4ee23bb442

View File

@ -242,7 +242,7 @@ std::vector<int> carving_step(const std::vector<unsigned char> source_img,
} }
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) { const char *out_filename, int nbSeams, bool vertical, unsigned char* mask=nullptr) {
int nbColorChannels = nbChannels > 3 ? 3 : nbChannels; int nbColorChannels = nbChannels > 3 ? 3 : nbChannels;
int curWidth = width; int curWidth = width;
int curHeight = height; int curHeight = height;
@ -290,8 +290,8 @@ void seam_carving(unsigned char *source, int width, int height, int nbChannels,
} }
} }
for (auto k = 0; k < width * height; k++) { for (auto k = 0; k < width * height; k++) {
// for (auto i=0; i < nbColorChannels; i++) //* Uncomment if you prefer to //* Uncomment if you prefer to see darkened source image
// see darkened source image // for (auto i=0; i < nbColorChannels; i++)
// output[nbChannels*k+i] = source_img[nbChannels*k+i]/nbChannels; // output[nbChannels*k+i] = source_img[nbChannels*k+i]/nbChannels;
for (auto ch = 0; ch < nbColorChannels; ch++) { for (auto ch = 0; ch < nbColorChannels; ch++) {
@ -347,8 +347,8 @@ void seam_carving(unsigned char *source, int width, int height, int nbChannels,
int main(int argc, char **argv) { int main(int argc, char **argv) {
CLI::App app{"seam-carving"}; CLI::App app{"seam-carving"};
std::string maskImage;
std::string sourceImage; std::string sourceImage;
std::string maskImage = "mask.png";
std::string outputImage = "output.png"; std::string outputImage = "output.png";
int nbSeams = 1; int nbSeams = 1;
bool vertical = false; bool vertical = false;
@ -378,10 +378,39 @@ int main(int argc, char **argv) {
int width, height, nbChannels; int width, height, nbChannels;
unsigned char *source = unsigned char *source =
stbi_load(sourceImage.c_str(), &width, &height, &nbChannels, 0); stbi_load(sourceImage.c_str(), &width, &height, &nbChannels, 0);
nbSeams = std::min(nbSeams, width);
unsigned char* mask = nullptr;
if (!maskImage.empty()) {
int maskWidth, maskHeight, maskChannels;
mask =
stbi_load(maskImage.c_str(), &maskWidth, &maskHeight, &maskChannels, 0);
if (maskWidth != width || maskHeight != height) {
std::cerr << maskImage << " and " << sourceImage
<< " differ in dimension. Please provide a valid mask."
<< std::endl;
exit(1);
}
if (maskChannels < 3) {
std::cerr << maskImage << " needs to be RGB." << std::endl;
exit(1);
}
unsigned char r, g, b;
for (auto i=0; i < width*height; i++) {
r = mask[maskChannels*i];
g = mask[maskChannels*i];
b = mask[maskChannels*i];
mask[2*i] = (r == 0) && (g == 255) && (b == 0);
mask[2*i+1] = (r == 255) && (g == 0) && (b == 0);
}
//* From now on, mask has the same dimensions as source and exactly 2 channels
//* The first channel is positive, the second one negative.
}
nbSeams = std::min(nbSeams, vertical ? width-1 : height-1); // We want to keep at least one row or column
seam_carving(source, width, height, nbChannels, outputImage.c_str(), seam_carving(source, width, height, nbChannels, outputImage.c_str(),
nbSeams, vertical); nbSeams, vertical, mask=mask);
stbi_image_free(source); stbi_image_free(source);
exit(0); exit(0);