【发布时间】:2014-01-13 18:41:49
【问题描述】:
我正在通过尝试大量 programming examples 来探索 Haskell repa 库。我的目标是使用repa实现常见的图像处理算法。
重复示例
repa 存储库中有一些helpful code examples。它们都对Array U DIM2 a 或Array 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))
图片文件IO
图片文件IO有两种选择:
- repa-devil 支持 PNG、BMP、JPG、TIF 的包。不幸的是,正如 repa-devil 维护者 here 所证实的那样,它们被解析为不符合上述 repa 示例的数组类型。
- repa-io 包与repa-examples 中图片的数组类型参数更接近,但只支持BMP 文件。
repa-devil(与 repa-examples 不兼容)
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)
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 ()
这一次,一个 BMP 图像文件被解析为一个二维数组,其元素类型为 (Word8,Word8,Word8),大概代表 R、G 和 B 值。即便如此,repa-examples 包中唯一兼容的函数是上面的toGreyScale。所有其他函数都对 Array U DIM2 Float 或 Array DIM2 Float 或 Array U DIM2 Double 类型的值进行操作。
问题
- 除了
toGreyScale,repa-examples 中的所有示例都只适用于灰度图像吗?虽然从类型上看这是有道理的,但令人惊讶的是,没有彩色图像的 repa 示例。例如,为什么blur的类型不是:blur :: Monad m => Int -> Array U DIM2 (Word8, Word8, Word8) -> m (Array U DIM2 (Word8, Word8, Word8)) -
Array U DIM2 Float中捕获的浮点数是什么值?它是 0 到 255 之间的灰度值吗? - 是否在 repa-io 包中添加 JPG/PNG/TIF IO 支持?
【问题讨论】:
-
Juicy Pixels 还有一个 repa 库,相信作者刚刚添加了对过渡 jpgs 的支持
-
@DiegoNolan 谢谢。看起来这个 JuicyPixels repa 库采用了与 repa-devil 相同的类型,而不是 repa-examples 中使用的类型,即使用 DIM3 类型参数 hackage.haskell.org/package/JuicyPixels-repa-0.7/docs/… 。
-
'blur' 示例使用
readImageFromBMP,它返回一个 3D 数组,上面的索引是像素位置,下面的索引是单个通道的值。所以如果有 3 个通道,我想每个 (x,y) 对都有 3 个值。您可能会使用readComponentsFromBMP,它会返回一个三元组数组,每个颜色分量一个,如果这更容易的话。模糊示例简单地使用fromIntegral和truncate来回转换Word8到Double。