使用Haskell修复阵列库的彩色图像文件IO

Rob*_*art 5 haskell repa

我正在通过尝试大量的编程示例来探索Haskell修复库.我的目标是使用repa实现常见的图像处理算法.

修理例子

在repa存储库中有一些有用的代码示例.它们都在类型Array U DIM2 aArray DIM2 Float或的图像上运行Array U DIM2 Double.

-- three image types used below
type Image = Array U DIM2 Double
type Image = Array DIM2 Float
type Image = Array U DIM2 (Word8, Word8, Word8)

-- examples/Blur/src-repa/Main.hs
blur :: Monad m => Int -> Array U DIM2 Double -> m (Array U DIM2 Double)

-- examples/Laplace/src-repa/SolverStencil.hs
solveLaplace :: Monad m => Int -> Array U DIM2 Double -> Array U DIM2 Double -> Array U DIM2 Double -> m (Array U DIM2 Double)

-- examples/Sobel/src-repa/SolverSeparated.hs
type Image = Array DIM2 Float
gradientX_sep :: Image -> Image
gradientX1    :: Image -> Image
gradientX2    :: Image -> Image
gradientY_sep :: Image -> Image
gradientY2    :: Image -> Image

-- examples/Canny/src-repa/Main.hs
type Image a = Array U DIM2 a
toGreyScale  :: Image (Word8, Word8, Word8) -> IO (Image Float)
blurSepX     :: Image Float -> IO (Image Float)
blurSepY     :: Image Float -> IO (Image Float)
gradientX    :: Image Float -> IO (Image Float)
gradientY    :: Image Float -> IO (Image Float)
suppress     :: Float -> Float -> Image (Float, Word8) -> IO (Image Word8)
wildfire     :: Image Word8 -> Array U DIM1 Int -> IO (Image Word8)
selectStrong :: Image Word8 -> IO (Array U DIM1 Int)
gradientMagOrient :: Float -> Image Float -> Image Float -> IO (Image (Float, Word8))
Run Code Online (Sandbox Code Playgroud)

图像文件IO

图像文件IO有两种选择:

  1. repa-devil包支持PNG,BMP,JPG,TIF.不幸的是,它们被解析成一个不符合上面的修复示例的数组类型,正如这里的repa-devil维护者所证实的那样.
  2. repa-io包更紧密地对应于repa-examples中图像的数组类型参数,但仅支持BMP文件.

修复魔鬼(与修复示例不兼容)

repa-examples包中的图像是类型Array F DIM3 Word8,或者Array F DIM2 Word8如果它是灰度图像.这意味着不能使用repa-devil来读取要处理的图像,这些示例在repa-examples中,因为repa-examples中的图像是二维数组,而repa-devil中的图像是三维数组.

readImage :: FilePath -> IL Image
writeImage :: FilePath -> Image -> IL ()
data Image = RGBA (Array F DIM3 Word8)
           | RGB  (Array F DIM3 Word8)
           | BGRA (Array F DIM3 Word8)
           | BGR  (Array F DIM3 Word8)
           | Grey (Array F DIM2 Word8)
Run Code Online (Sandbox Code Playgroud)

repa-io(与repa-examples兼容)

在repa-examples和repa-io之间有更密切的对应关系.

readImageFromBMP :: FilePath -> IO (Either Error (Array U DIM2 (Word8,Word8, Word8)))
writeImageToBMP  :: FilePath -> Array U DIM2 (Word8, Word8, Word8) -> IO ()
Run Code Online (Sandbox Code Playgroud)

这次,BMP图像文件被解析为具有类型元素的二维数组(Word8,Word8,Word8),可能表示R,G和B值.即便如此,repa-examples软件包中唯一兼容的功能toGreyScale来自上面.所有其他功能对类型Array U DIM2 FloatArray DIM2 Float或的值进行操作Array U DIM2 Double.

问题

  1. 除了toGreyScale,示例中的所有示例仅适用于灰度图像吗?虽然这对于类型来说是有意义的,但令人惊讶的是,没有彩色图像的修复示例.例如,为什么类型blur不是: blur :: Monad m => Int -> Array U DIM2 (Word8, Word8, Word8) -> m (Array U DIM2 (Word8, Word8, Word8))
  2. 浮动捕获的价值是Array U DIM2 Float多少?它是0到255之间的灰度值吗?
  3. 在repa-io包中添加JPG/PNG/TIF IO支持是否有任何工作?

Ben*_*ier 5

  1. 没理由.您可以将单通道模糊功能应用于彩色图像的每个RGB通道.
  2. 使用表示为Array U DIM2 Float元素的图像通常具有范围0.0 - 1.0.
  3. 我不认为JPG/PNG图像的加载应该放在repa-io包中,因为这会导致对外部编解码器库的依赖.使用其他一个包repa-devil来加载图像.

所述repa-devil封装包装的外部魔鬼库,所以加载的图像的在国外存储器结束-因此F在指数Array F DIM3 Word8.DevIL库本身不知道如何U在Haskell堆中构建一个未装箱的数组.

这些示例仅是示例,我并不打算repa-examples成为功能齐全的图像处理库.一些数组使用外部F表示的事实,有些使用未装箱的U表示只反映了包装外部代码的标准问题.如果你想要一个统一的图像处理API,你需要在边界处更改图像表示(这可能会引入冗余复制),使函数更具多态性(使其类型复杂化),或者隐藏问题某些方法(这会导致成本)模型不明显).无论你选择哪种选择,都会有人抱怨它.