toGrayscale :: Image -> ImageGS
toGrayscale img = HIP.makeImage imgDims (cv . HIP.index img)
  where
    imgDims = HIP.dims img
    cv :: Pixel -> PixelGS
    cv p =
        -- https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html
        HIP.PixelY $ saturate $ (fI r / 255) * 0.299 + (fI g / 255) * 0.587 + (fI b / 255) * 0.114
      where
        fI = fromIntegral @Word8 @Double
        r = HIP.getPxC p HIP.RedRGBA
        g = HIP.getPxC p HIP.GreenRGBA
        b = HIP.getPxC p HIP.BlueRGBA
toGrayscale :: Image -> ImageGS
toGrayscale img = HIP.makeImage imgDims (cv . HIP.index img)
  where
    imgDims = HIP.dims img
    cv :: Pixel -> PixelGS
    cv p =
        -- https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html
        HIP.PixelY $ saturate $ (fI r / 255) * 0.299 + (fI g / 255) * 0.587 + (fI b / 255) * 0.114
      where
        fI = fromIntegral @Word8 @Double
        r = HIP.getPxC p HIP.RedRGBA
        g = HIP.getPxC p HIP.GreenRGBA
        b = HIP.getPxC p HIP.BlueRGBA
toGrayscale img = HIP.makeImage imgDims (cv . HIP.index img)
  where
    imgDims = HIP.dims img
    cv :: Pixel -> PixelGS
    cv p =
        -- https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html
        HIP.PixelY $ saturate $ (fI r / 255) * 0.299 + (fI g / 255) * 0.587 + (fI b / 255) * 0.114
      where
        fI = fromIntegral @Word8 @Double
        r = HIP.getPxC p HIP.RedRGBA
        g = HIP.getPxC p HIP.GreenRGBA
        b = HIP.getPxC p HIP.BlueRGBA