title: What's the right way to normalize a convolution filter?
body: <p>I'm following <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feConvolveMatrix" rel="nofollow noreferrer">these</a> instructions. But my results aren't coming out right. I'm using this kernel:</p>
  
  <pre><code>-1 -1 -1
  -1  8 -1
  -1 -1 -1
  </code></pre>
  
  <p>So that means the sum for a given convolution will be between -8 and 8, assuming I have already normalized my input (0-255 -> 0-1). Then I do the convolution. Then I find the percent my value is between the minimum and maximum values. For example, with this kernel my min is -8 and max is 8. So if the value is 0 that's 50% which works out to 255 * .5 = 127.5. But that's clearly not right and what it gives is a mostly gray image. The parts that aren't gray are still monochrome even though I'm running the kernel on each channel individually. </p>
  
  <p><a href="https://i.stack.imgur.com/KqbE7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KqbE7.png" alt="enter image description here"></a></p>
  
  <pre><code>    static int EvaluateKernelAtPoint(Bitmap bitmap, Matrix&lt;double&gt; kernel, int x, int y, Func&lt;int, int, int&gt; onGetIntensity)
      {
          double sum = 0;
          for (int a = 0; a &lt; kernel.ColumnCount; a++)
          {
              for (int b = 0; b &lt; kernel.RowCount; b++)
              {
                  var xn = x + a - 1;
                  var yn = y + b - 1;
  
                  var intensity = (double)onGetIntensity(xn, yn); // returns R,G, or B color channel at that pixel
                  intensity /= 255; // intensity is 0-1
                  sum += intensity * kernel.At(a, b);
              }
          }
  
          var result = (sum - (-8d)) / (8d - (-8d)); // find the % between the min and max of -8 and 8
          result *= 255; // bring it back to 0-255
      }
  </code></pre>