rewrite recompute_energy_along_seam

This commit is contained in:
François Colin de Verdière 2025-04-03 17:46:00 +02:00
parent f6e45e62b2
commit f3cb18d9a0

View File

@ -53,7 +53,20 @@ std::string function = "grad";
? (nbChannels) * (width * (j) + ((i) + 1)) \ ? (nbChannels) * (width * (j) + ((i) + 1)) \
: indexPixel; \ : indexPixel; \
dest = 0; \ dest = 0; \
if (function == "gradnorm") { \ if (function == "grad") { \
for (auto ch = 0; ch < (nbColorChannels); ch++) { \
dest += ((fabs((float)source[indexPixel_up + ch] - \
source[indexPixel + ch])) + \
\
(fabs((float)source[indexPixel_down + ch] - \
source[indexPixel + ch])) + \
\
(fabs((float)source[indexPixel_left + ch] - \
source[indexPixel + ch])) + \
(fabs((float)source[indexPixel_right + ch] - \
source[indexPixel + ch]))); \
} \
} else if (function == "gradnorm") { \
for (auto ch = 0; ch < (nbColorChannels); ch++) { \ for (auto ch = 0; ch < (nbColorChannels); ch++) { \
dest += (std::pow(fabs((float)source[indexPixel_up + ch] - \ dest += (std::pow(fabs((float)source[indexPixel_up + ch] - \
source[indexPixel + ch]), \ source[indexPixel + ch]), \
@ -70,17 +83,20 @@ std::string function = "grad";
source[indexPixel + ch]), \ source[indexPixel + ch]), \
2)); \ 2)); \
} \ } \
} else if (function == "grad") { \ } else if (function == "gradhoriz") { \
/* take the gradient along the horizontal only*/ \
for (auto ch = 0; ch < (nbColorChannels); ch++) { \
dest += ((fabs((float)source[indexPixel_left + ch] - \
source[indexPixel + ch])) + \
(fabs((float)source[indexPixel_right + ch] - \
source[indexPixel + ch]))); \
} \
} else if (function == "gradvertic") { \
/* take the gradient along the vertical only*/ \
for (auto ch = 0; ch < (nbColorChannels); ch++) { \ for (auto ch = 0; ch < (nbColorChannels); ch++) { \
dest += ((fabs((float)source[indexPixel_up + ch] - \ dest += ((fabs((float)source[indexPixel_up + ch] - \
source[indexPixel + ch])) + \ source[indexPixel + ch])) + \
\
(fabs((float)source[indexPixel_down + ch] - \ (fabs((float)source[indexPixel_down + ch] - \
source[indexPixel + ch])) + \
\
(fabs((float)source[indexPixel_left + ch] - \
source[indexPixel + ch])) + \
(fabs((float)source[indexPixel_right + ch] - \
source[indexPixel + ch]))); \ source[indexPixel + ch]))); \
} \ } \
} else if (function == "gradnorminf") { \ } else if (function == "gradnorminf") { \
@ -249,17 +265,22 @@ void recompute_energy_along_seam(std::vector<unsigned char> carved_img,
int newWidth = vertical ? width - 1 : width; int newWidth = vertical ? width - 1 : width;
int newHeight = vertical ? height : height - 1; int newHeight = vertical ? height : height - 1;
for (auto j = 0; j < dim_long; j++) { for (auto j0 = 0; j0 < dim_long; j0++) {
for (auto i = -1; i < 2; i++) { auto i0 = opt_seam[j0];
int x = vertical ? (opt_seam[j] + i) : j; for (auto i_offset = -max_step - 1; i_offset <= max_step + 1; i_offset++) {
int y = vertical ? j : (opt_seam[j] + i); for (auto j_offset = -max_step - 1; j_offset <= max_step + 1;
if ((0 < (opt_seam[j] + i)) && ((opt_seam[j] + i) < dim_large - 1)) { j_offset++) {
int x = vertical ? (i0 + i_offset) : j0 + j_offset;
int y = vertical ? j0 + j_offset : (i0 + i_offset);
if (((0 < (i0 + i_offset)) && ((i0 + i_offset) < dim_large - 1)) &&
(((0 < j0 + j_offset) && (j0 + j_offset < dim_long)))) {
compute_energy_for_pixel(carved_img, newWidth, newHeight, x, y, compute_energy_for_pixel(carved_img, newWidth, newHeight, x, y,
nbChannels, nbColorChannels, nbChannels, nbColorChannels,
output_energy[width * y + x]); output_energy[width * y + x]);
} }
} }
} }
}
} }
void recompute_energy_along_seam( void recompute_energy_along_seam(
@ -267,23 +288,29 @@ void recompute_energy_along_seam(
std::vector<std::pair<int, float>> &output_energy, std::vector<std::pair<int, float>> &output_energy,
std::vector<int> opt_seam, int width, int height, int nbChannels, std::vector<int> opt_seam, int width, int height, int nbChannels,
int nbColorChannels, bool vertical) { int nbColorChannels, bool vertical) {
int dim_large = vertical ? width : height; int dim_large = vertical ? width : height;
int dim_long = vertical ? height : width; int dim_long = vertical ? height : width;
int newWidth = vertical ? width - 1 : width; int newWidth = vertical ? width - 1 : width;
int newHeight = vertical ? height : height - 1; int newHeight = vertical ? height : height - 1;
for (auto j = 0; j < dim_long; j++) { for (auto j0 = 0; j0 < dim_long; j0++) {
for (auto i = -1; i < 2; i++) { auto i0 = opt_seam[j0];
int x = vertical ? (opt_seam[j] + i) : j; for (auto i_offset = -max_step - 1; i_offset <= max_step + 1; i_offset++) {
int y = vertical ? j : (opt_seam[j] + i); for (auto j_offset = -max_step - 1; j_offset <= max_step + 1;
if ((0 < (opt_seam[j] + i)) && ((opt_seam[j] + i) < dim_large - 1)) { j_offset++) {
int x = vertical ? (i0 + i_offset) : j0 + j_offset;
int y = vertical ? j0 + j_offset : (i0 + i_offset);
if (((0 < (i0 + i_offset)) && ((i0 + i_offset) < dim_large - 1)) &&
(((0 < j0 + j_offset) && (j0 + j_offset < dim_long)))) {
compute_energy_for_pixel(carved_img, newWidth, newHeight, x, y, compute_energy_for_pixel(carved_img, newWidth, newHeight, x, y,
nbChannels, nbColorChannels, nbChannels, nbColorChannels,
output_energy[width * y + x].first); output_energy[width * y + x].first);
} }
} }
} }
}
} }
/** Carves an image and its energy by one seam, and recomputes the energy. /** Carves an image and its energy by one seam, and recomputes the energy.
@ -538,7 +565,7 @@ int main(int argc, char **argv) {
mask[i] = positive ? 2 : (negative ? 0 : 1); mask[i] = positive ? 2 : (negative ? 0 : 1);
} }
//* From now on, mask has the same dimensions as source and one single //* From now on, mask has the same dimensions as source and one single
//channel // channel
//* The values are: //* The values are:
//* . (2) we want to keep the pixel //* . (2) we want to keep the pixel
//* . (1) nothing in particular //* . (1) nothing in particular