I'm following these instructions. But my results aren't coming out right. I'm using this kernel:
-1 -1 -1
-1 8 -1
-1 -1 -1
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.
static int EvaluateKernelAtPoint(Bitmap bitmap, Matrix<double> kernel, int x, int y, Func<int, int, int> onGetIntensity)
{
double sum = 0;
for (int a = 0; a < kernel.ColumnCount; a++)
{
for (int b = 0; b < 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
}
There is no right way to normalize, because the range is content-dependent.
In good RGB images, the range of values is usually [0, 255], provided the dynamic range is well adjusted.
But the output of this Laplacian filter, which can be seen as the difference between the original image and a smoothed version of it, usually has much smaller amplitude. But this depends on the local variations: an already smooth image will give no response, while noise (especially salt & pepper) can yield huge values.
You also need to decide what to do with negative values: shift so that zero appears as mid-gray, clamp to zero or take the absolute value.
Taking the min-max range and mapping it to 0-255 is an option, but leads to a "floating" zero and uncontrolled gain. I would prefer to set a constant gain for a set of images of the same origin.
Last but not least, histogram equalization is another option.