Currently, we search for the watermark range in the C++ embedder like this:
/// Choose an integer r such that 99.5% of the watermark pixels is in [-r:r] for areas of constant color
/// Determine the integer range r so that 99.5 % of |W·s| < r
static int
wm_range (const cv::Mat &W, float strength)
{
// TODO: optimize F (0, strength) == strength
// compute_F(cv::Mat::zeros(1, 1, CV_32F), strength) is actually: max(log2(sqrt(1e-5)), strength)
const float s = compute_F (cv::Mat::zeros (1, 1, CV_32F), strength).at<float> (0, 0);
// TODO: const float s = strength;
cv::Mat abs_scaled = cv::abs (W * s);
const double total = abs_scaled.total();
for (int r = 0; r < 32; r++) {
cv::Mat mask = abs_scaled < r;
int inside = cv::countNonZero (mask);
if (inside / total > 0.995f) // calculates mean
return r;
}
dprintf (2, "imagewmark: error detecting watermark range\n");
return 16;
}
However the return value of this could be determined without actually trying different values for r. For a given strength the return value should be the same (or at least we can reasonably assume that for a given strength, a constant r is "good enough in practice"). So this could simply be a linear interpolated table lookup or some other fast way to get r from strength directly without counting pixels.
Currently, we search for the watermark range in the C++ embedder like this:
However the return value of this could be determined without actually trying different values for r. For a given strength the return value should be the same (or at least we can reasonably assume that for a given strength, a constant r is "good enough in practice"). So this could simply be a linear interpolated table lookup or some other fast way to get r from strength directly without counting pixels.