# Why do convolution kernels such as Gaussian, Laplacian, LoG almost always seem to be expressed in integers?

I'm a total newb in search of some deeper understanding, but I'm not able to read the maths behind these on Wikipedia.

If I understand correctly, you get the new value for each pixel by multiplying each of its neighbours' values by the corresponding member of the convolution kernel/matrix. For Laplacian there seem to be two commonly used such kernels:

 0 -1  0
-1  4 -1
0 -1  0


and:

-1 -1 -1
-1  8 -1
-1 -1 -1


But why do they use only integers? I believe modern devices have floating point as fast as faster integer math these days.

Is this just a leftover from the past when floating point was slow and now it's become a kind of tradition? Perhaps people just re-using the old info they find from those days without deeper understanding? Or is there an actual reason why integers are used?

In fact, won't the use of integers here result in artefacting? What am I missing?

• related Sep 11, 2019 at 7:02
• Do you have enough information to validate an answer? Oct 3, 2019 at 20:28
• @LaurentDuval: No. I don't. I couldn't get my Android project to work when I tried to add LoG to it and got no answers on SO. I couldn't gain enough understanding in whether I should be able to use both floating point and integer matrices if I used appropriate values and don't know where to ask for help. I also don't understand how I might break Laplacian into two one-dimensional passes though I do for Gaussian. Also for Laplacian I don't know if I can in both float and int, or if it makes sense in int. \-: Oct 4, 2019 at 6:55

The Laplacian kernel with the 4 in the middle results from summing second derivatives along the two axes ([1,-2,1]). Those are the right values to use, you can show this by writing out the math for the second derivative and set the distance h to 1 (or search for discrete approximation to derivative). This kernel hasn’t been rounded, the values just happen to be integer.

The other kernel, with 8 in the middle, does not provide correct values for the Laplacian, but uses more input values and hence is a bit more robust against noise (but not by a whole lot).

The assertion "almost always seem to be expressed in integers?" does not seem to be true, in my opinion. However, such kernels are pretty frequent in codes. They are quantized both in support (limited discrete support) and amplitude (signed integer values). $$3\times 3$$ masks with integer coefficients, as you showed, are very familiar, albethey approximations.

Indeed, most (of such linear operators) derive from continuous formulations, combining derivatives and smoothing kernels; the Gaussian being, possibly, the most common of the latter. Sampling in the space or in the value domain result in artifacts, and at the same time in simpler computations (less taps, less bits), this is a fundamental balance.

In 2D, my experience is that sampling has be studied more that quantization, as sampling is way more linear... One example of alternative optimized 2D designs is in:

You image sensor needs to quantize the image information anyways. Typical range of quantization is anywhere between 8 and 16 bits per pixel (per color channel). So your image is already integer, there is no gain in converting it to float.

And yes, integer arithmetic is still much faster than floating point arithmetic. Just check the recent graphic cards, INT8 (or even INT4) computations are experiencing a huge revival because they are so much faster and sometimes enough (inference in machine learning, for instance). Image filtering is a massive-throughput application, you want to squeeze every bit out of it you can.

• Unless I'm missing something, I'm not seeing the connection between not being able to specify something between 0 and -1 and converting the image to float, which it seems like you're saying. The results of some of these filters is a matrix of floats which you may turn back into pixels (quantize) or may do something else with. The something to gain would be the ability to have smooth gradients. This would I suppose also be possible if the integers were spread over a bigger range, but I don't grok the math behind it so there may be a reason for that too. Sep 10, 2019 at 6:56
• @hippietrail You need to explain us why that would be better. Say, I want to do edge detection. My image is integers. I'll use the $[0, -1, 0]$ filter, in two dimensions, it will detect edges. You're saying using a $[0, -0.5, 0]$ would be better? Why? The result is just a scaled version (1/2) of the result you'd get via the integer-valued filter. I cannot see how floating point filter coefficients would give us smooth gradients (or anything else that is not the same as rescaling the integer solution). Can you give an example (edit your question maybe)? Sep 10, 2019 at 15:19
• I'm not saying it would be better. I'm just trying to learn understand. I'm from the 8-bit days where we used to do everything in integer yet I still find it counterintuitive. I'll have to come back when I've gained understanding by other methods. Thanks for your patience. Sep 10, 2019 at 15:59
• @hippietrail: no problem at all. I hope you get my point though: instead of filtering with, say $[0.1, 0.3]$, you can filter with $[1, 3]$ and divide the result by 10. It's the same. Or don't even divide it, since images are typically displayed normalized anyways. If you're worried about overflows, embed your integer into the next bigger integer type. Strictly speaking this only works for rationals, but I don't see why filtering with $\sqrt{2}$ would be a good idea :) Sep 10, 2019 at 16:04
• Not all filtering results are only meant for display. In my work, which is about quantification, it is very important to preserve fractional results and filter with correctly computed kernels. Rounding in the original image can be modeled as uniformly distributed noise. Rounding the kernels and the filtering result leads to additional imprecision in that is sometimes not at all welcome. Sep 15, 2019 at 15:13