docs: public static <T extends ImageBase<T>, K extends Kernel2D>
  	void convolveNormalized(K kernel, T input, T output ) {
  		switch (input.getImageType().getFamily()) {
  			case GRAY: {
  				if (input instanceof GrayF32) {
  					ConvolveImageNormalized.convolve((Kernel2D_F32) kernel, (GrayF32) input, (GrayF32) output);
  				} else if (input instanceof GrayF64) {
  					ConvolveImageNormalized.convolve((Kernel2D_F64) kernel, (GrayF64) input, (GrayF64) output);
  				} else if (input instanceof GrayU8) {
  					ConvolveImageNormalized.convolve((Kernel2D_S32) kernel, (GrayU8) input, (GrayI8) output);
  				} else if (input instanceof GrayS16) {
  					ConvolveImageNormalized.convolve((Kernel2D_S32) kernel, (GrayS16) input, (GrayI16) output);
  				} else {
  					throw new IllegalArgumentException("Unknown image type: " + input.getClass().getName());
  				}
  			} break;
  
  			case INTERLEAVED: {
  				if (input instanceof InterleavedF32) {
  					ConvolveImageNormalized.convolve((Kernel2D_F32) kernel, (InterleavedF32) input, (InterleavedF32) output);
  				} else if (input instanceof InterleavedF64) {
  					ConvolveImageNormalized.convolve((Kernel2D_F64) kernel, (InterleavedF64) input, (InterleavedF64) output);
  				} else if (input instanceof InterleavedU8) {
  					ConvolveImageNormalized.convolve((Kernel2D_S32) kernel, (InterleavedU8) input, (InterleavedI8) output);
  				} else if (input instanceof InterleavedS16) {
  					ConvolveImageNormalized.convolve((Kernel2D_S32) kernel, (InterleavedS16) input, (InterleavedI16) output);
  				} else {
  					throw new IllegalArgumentException("Unknown image type: " + input.getClass().getName());
  				}
  			} break;
  
  			case PLANAR: {
  				Planar inp = (Planar) input;
  				Planar outp = (Planar) output;
  
  				for (int i = 0; i < inp.getNumBands(); i++) {
  					convolveNormalized(kernel, inp.getBand(i), outp.getBand(i));
  				}
  			} break;
  
  			default:
  				throw new IllegalArgumentException("Unknown image family");
  		}
  	}