0

When I try to use the following function to normalize the dynamic range of an image:

void normalize(uint8_t array[], unsigned int cols, unsigned int rows) {
    uint8_t minValue = min(array, cols, rows);
    uint8_t maxValue = max(array, cols, rows);

    uint8_t MIN_RANGE = 0;
    uint8_t MAX_RANGE = 255;

    uint8_t new_range = MAX_RANGE - MIN_RANGE;
    uint8_t old_range = maxValue - minValue;
    int range = 0;
    double scale = 0;
    for (range = 0; range < rows * cols; range++) {
        scale = (array[range] - minValue) / (old_range);
        array[range] = scale * new_range + MIN_RANGE;
    }

}

All I get is 0, but I can't identify the mistake. min() and max() are functions that work correctly to return the darkest and lightest colors respectively.

Mil3d
  • 31
  • 1
  • 6
  • The division is always done in integer arithmetic (`int` type). The result is then converted to `double`, but it is almost always zero, if not always zero. – Jonathan Leffler Aug 07 '16 at 23:17
  • Thank you! But in the case of variables, I can't just add .00 at the end of the number... – Mil3d Aug 07 '16 at 23:31
  • True, but you could use `double old_range;` or you could add a cast in the arithmetic. – Jonathan Leffler Aug 07 '16 at 23:32
  • Interesting. It works now, but the values are giving 1 less than what it should be. That might be a truncation/rounding problem due to the division? – Mil3d Aug 08 '16 at 02:45
  • It might be due to the division, but it is more likely due to truncation when the computation for `array[range] = scale * new_range + MIN_RANGE;` occurs — since `scale` is a `double`, the computation occurs in `double`, but the assignment converts from the `double` to `uint8_t`, and at that point the value is truncated, not rounded. You could add `0.5` in the assignment, perhaps (since you're dealing with strictly positive numbers). I'm not immediately sure whether you need to worry about rounding with values above 255 (but less than 256). – Jonathan Leffler Aug 08 '16 at 03:04
  • Sorry for bothering you, but by "you could add 0.5" you mean array[range] = scale * new_range + MIN_RANGE + 0.5; ? How would that solve? Sorry if that sounds stupid, but I'm just trying to understand – Mil3d Aug 08 '16 at 03:13
  • The assignment you wrote is what I meant. Adding `0.5` rounds the calculated value; if the expression `scale * new_range + MIN_RANGE` is a number between, say, 212.00 and 212.49, then the result will still be 212; if it is between 212.50 and 212.99, then the result will be 213. If that's not the problem, then you may need to calculate something else differently. For example, maybe you need `new_range` to be `MAX_VALUE - MIN_VALUE + 1` because there are 256, not 255, values in the new range. Or it might be that the `old_range` needs the `+ 1` term. I'm not sure — it's your problem domain. – Jonathan Leffler Aug 08 '16 at 03:18

0 Answers0