text: Title: [Speed up] Currently Gaussian Noise is not optimized for separate uint8 and float32 treatment
  Body: It could happen, that 
  
  ```python
  @clipped
  def gauss_noise(image: np.ndarray, gauss: np.ndarray) -> np.ndarray:
      image = image.astype("float32")
      return image + gauss
  ```
  
  could be optimized with something like:
  ```python
  def gauss_noise_optimized(image: np.ndarray, gauss: np.ndarray) -> np.ndarray:
      if image.dtype == np.float32:
          gauss = gauss.astype(np.float32)
          noisy_image = cv2.add(image, gauss)
      elif image.dtype == np.uint8:
          gauss = np.clip(gauss, 0, 255).astype(np.uint8)
          noisy_image = cv2.add(image, gauss)
      else:
          raise TypeError("Unsupported image dtype. Expected uint8 or float32.")
      return noisy_image
  ```
  
  requires benchmarking, but technically it is a one function replacement Pull Request, that is good for a first issue.
  
  Althouh more involved process could be done if it makes it even faster:
  
  ```python
  @clipped
  def _shift_rgb_non_uint8(img: np.ndarray, r_shift: float, g_shift: float, b_shift: float) -> np.ndarray:
      if r_shift == g_shift == b_shift:
          return img + r_shift
  
      result_img = np.empty_like(img)
      shifts = [r_shift, g_shift, b_shift]
      for i, shift in enumerate(shifts):
          result_img[..., i] = img[..., i] + shift
  
      return result_img
  
  
  def _shift_image_uint8(img: np.ndarray, value: np.ndarray) -> np.ndarray:
      max_value = MAX_VALUES_BY_DTYPE[img.dtype]
  
      lut = np.arange(0, max_value + 1).astype("float32")
      lut += value
  
      lut = np.clip(lut, 0, max_value).astype(img.dtype)
      return cv2.LUT(img, lut)
  
  
  @preserve_shape
  def _shift_rgb_uint8(img: np.ndarray, r_shift: ScalarType, g_shift: ScalarType, b_shift: ScalarType) -> np.ndarray:
      if r_shift == g_shift == b_shift:
          height, width, channels = img.shape
          img = img.reshape([height, width * channels])
  
          return _shift_image_uint8(img, r_shift)
  
      result_img = np.empty_like(img)
      shifts = [r_shift, g_shift, b_shift]
      for i, shift in enumerate(shifts):
          result_img[..., i] = _shift_image_uint8(img[..., i], shift)
  
      return result_img
  
  
  def shift_rgb(img: np.ndarray, r_shift: ScalarType, g_shift: ScalarType, b_shift: ScalarType) -> np.ndarray:
      if img.dtype == np.uint8:
          return _shift_rgb_uint8(img, r_shift, g_shift, b_shift)
  
      return _shift_rgb_non_uint8(img, r_shift, g_shift, b_shift)
  ```