如何将图像从 DynamicImage 类型转换为 Image arr cs e?使用 JuicyPixels 和 HIP 库
How to convert an image from DynamicImage type to Image arr cs e? Using JuicyPixels and HIP libraries
我正在使用 JuicyPixels 图像处理库摄取图像并将其转换为 Matrix 类型。我想将图像的分辨率更改为用户指定的尺寸,以便将其输入神经网络。
到目前为止,我的程序读取图像并将图像转换为 Data.Matrix 矩阵。图片类型来自 DynamicImage -> Image Pixel8 ->[[Int]] -> Matrix Int
我尝试使用 Haskell 图像处理 (HIP) 库中的调整大小功能,但它接受并输出一个我不知道如何处理的类型 Image arr cs e
。
到目前为止,这是我的代码:
import Codec.Picture
import Codec.Picture.Types
import Control.Arrow
import Data.Ratio
import Data.Monoid
import Graphics.Image.Processing
import qualified Graphics.Image as I
import qualified Data.Matrix as M
import System.FilePath.Posix (splitExtension)
-- take image input with the filepath given as a DynamicImage type
to2DMatrix :: FilePath -> String -> (Int, Int) -> IO ()
to2DMatrix fp = do
image <- readImage fp
case image of
Left _ -> putStrLn $ "Sorry, not a supported codec for " ++ fp
Right dynimg -> do
-- convert dynamic image to greyscale and then to a 2d matrix
let rle = twoDToMatrix $ pixelToInt $ greyscaleImage $ changeResolution dynimg
let (name, _) = splitExtension fp
writeFile (name ++ ".txt") (show rle)
Right _ -> putStrLn "Unhandled file type"
changeResolution :: DynamicImage -> String -> (Int, Int) -> DynamicImage
changeResolution border (dim1, dim2) img = I.resize border (dim1, dim2) img
-- convert DynamicImage to a Pixel8 image
greyscaleImage :: DynamicImage -> Image Pixel8
greyscaleImage = convertRGB8 >>> pixelMap greyscalePixel
-- convert PixelsRGB8 image to Pixel8 image
greyscalePixel :: PixelRGB8 -> Pixel8
greyscalePixel (PixelRGB8 r g b) = round (wr + wg + wb)
where wr = toRational r * (3 % 10)
wg = toRational g * (59 % 100)
wb = toRational b * (11 % 100)
-- convert Pixel8 image to a 2-d matrix of integers
pixelToInt :: Image Pixel8 -> [[Int]]
pixelToInt =
map reverse . reverse . snd . pixelFold -- because of the direction pixelFold works in, and the direction
(\(lastY, ps:pss) x y p -> -- you add things to lists, reverse and map reverse are necessary
if y == lastY -- to make the output not mirrored horizontaly and vertically
then (y, (fromIntegral p:ps):pss)
else (y, [fromIntegral p]:ps:pss))
(0,[[]])
-- converts list of lists to Data.Matrix type Matrix
twoDToMatrix :: [[Int]] -> M.Matrix Int
twoDToMatrix lists = M.fromLists lists
编辑:
更改程序以删除 changeResolution
函数,因为我意识到我可以使用 convert
函数或使用 readImageY
将图像转换为灰度。这是更新后的代码:
to2DMatrix :: FilePath -> Border(Interface.Pixel I.Y Word8) -> (Int, Int) -> IO ()
to2DMatrix fp bor (dim1, dim2)= do
eimg <- I.readImageExact VS fp
case eimg of
Left _ -> putStrLn $ "Sorry, not a supported codec for " ++ fp
Right img -> do
let imgGray :: Interface.Image VS I.Y Word8
imgGray = convert (img)
let new_res :: Interface.Image VS I.Y Word8
new_res = I.resize imgGray bor (dim1, dim2)
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
let (name, _) = splitExtension fp
writeFile (name ++ ".txt") (show rle)
我收到以下错误。如何从 arr
转换为 VS
?
Couldn't match expected type ‘Interface.Image VS I.Y Word8’
with actual type ‘Interface.Image arr0 I.Y Word8
-> Interface.Image arr0 I.Y Word8’
• In the expression: resize imgGray bor (dim1, dim2)
In an equation for ‘new_res’:
new_res = resize imgGray bor (dim1, dim2)
In the expression:
do let imgGray :: Interface.Image VS I.Y Word8
imgGray = convert (img)
let new_res :: Interface.Image VS I.Y Word8
new_res = resize imgGray bor ...
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
let (name, _) = splitExtension fp
....
|
34 | new_res = I.resize imgGray bor (dim1, dim2)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
resize
function in the Haskell Image Processing (HIP) library 使用 Image arr cs e
类型,所以我发现使用 HIP 库比使用 JuicyPixels 更容易读取图像。
类型从 Image VS Y Double
-> Image VS Y Word8
-> Pixel8
-> [[Int]]
-> Matrix Int
。
使用 HIP 的另一个优点是我们可以读取灰度图像 Pixel Y
而不是稍后进行转换。这是更改后的代码:
import Codec.Picture
import Codec.Picture.Types
import Graphics.Image.Processing
import qualified Graphics.Image as I
import qualified Graphics.Image.Interface as Interface
import Graphics.Image.ColorSpace
import Data.Word (Word8)
import qualified Data.Matrix as M
to2DMatrix :: FilePath -> (Int, Int) -> IO (Maybe (M.Matrix Int))
to2DMatrix fp (dim1, dim2)= do
eimg <- I.readImageY VS fp
let new_res :: Interface.Image VS I.Y Word8
new_res = I.resize Bilinear Edge (dim1, dim2) $ Interface.map conv eimg
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
return $ Just (rle)
conv :: Interface.Pixel I.Y Double -> Interface.Pixel I.Y Word8
conv d = fmap Interface.toWord8 d
pixelToInt :: Image Pixel8 -> [[Int]]
pixelToInt =
map reverse . reverse . snd . pixelFold
(\(lastY, ps:pss) x y p ->
if y == lastY
then (y, (fromIntegral p:ps):pss)
else (y, [fromIntegral p]:ps:pss))
(0,[[]])
twoDToMatrix :: [[Int]] -> M.Matrix Int
twoDToMatrix lists = M.fromLists lists
conv
将每个像素从 Double
转换为 toWord8
。对于 toJPImageY8
函数,图像需要具有 Word8
精度。
我正在使用 JuicyPixels 图像处理库摄取图像并将其转换为 Matrix 类型。我想将图像的分辨率更改为用户指定的尺寸,以便将其输入神经网络。
到目前为止,我的程序读取图像并将图像转换为 Data.Matrix 矩阵。图片类型来自 DynamicImage -> Image Pixel8 ->[[Int]] -> Matrix Int
我尝试使用 Haskell 图像处理 (HIP) 库中的调整大小功能,但它接受并输出一个我不知道如何处理的类型 Image arr cs e
。
到目前为止,这是我的代码:
import Codec.Picture
import Codec.Picture.Types
import Control.Arrow
import Data.Ratio
import Data.Monoid
import Graphics.Image.Processing
import qualified Graphics.Image as I
import qualified Data.Matrix as M
import System.FilePath.Posix (splitExtension)
-- take image input with the filepath given as a DynamicImage type
to2DMatrix :: FilePath -> String -> (Int, Int) -> IO ()
to2DMatrix fp = do
image <- readImage fp
case image of
Left _ -> putStrLn $ "Sorry, not a supported codec for " ++ fp
Right dynimg -> do
-- convert dynamic image to greyscale and then to a 2d matrix
let rle = twoDToMatrix $ pixelToInt $ greyscaleImage $ changeResolution dynimg
let (name, _) = splitExtension fp
writeFile (name ++ ".txt") (show rle)
Right _ -> putStrLn "Unhandled file type"
changeResolution :: DynamicImage -> String -> (Int, Int) -> DynamicImage
changeResolution border (dim1, dim2) img = I.resize border (dim1, dim2) img
-- convert DynamicImage to a Pixel8 image
greyscaleImage :: DynamicImage -> Image Pixel8
greyscaleImage = convertRGB8 >>> pixelMap greyscalePixel
-- convert PixelsRGB8 image to Pixel8 image
greyscalePixel :: PixelRGB8 -> Pixel8
greyscalePixel (PixelRGB8 r g b) = round (wr + wg + wb)
where wr = toRational r * (3 % 10)
wg = toRational g * (59 % 100)
wb = toRational b * (11 % 100)
-- convert Pixel8 image to a 2-d matrix of integers
pixelToInt :: Image Pixel8 -> [[Int]]
pixelToInt =
map reverse . reverse . snd . pixelFold -- because of the direction pixelFold works in, and the direction
(\(lastY, ps:pss) x y p -> -- you add things to lists, reverse and map reverse are necessary
if y == lastY -- to make the output not mirrored horizontaly and vertically
then (y, (fromIntegral p:ps):pss)
else (y, [fromIntegral p]:ps:pss))
(0,[[]])
-- converts list of lists to Data.Matrix type Matrix
twoDToMatrix :: [[Int]] -> M.Matrix Int
twoDToMatrix lists = M.fromLists lists
编辑:
更改程序以删除 changeResolution
函数,因为我意识到我可以使用 convert
函数或使用 readImageY
将图像转换为灰度。这是更新后的代码:
to2DMatrix :: FilePath -> Border(Interface.Pixel I.Y Word8) -> (Int, Int) -> IO ()
to2DMatrix fp bor (dim1, dim2)= do
eimg <- I.readImageExact VS fp
case eimg of
Left _ -> putStrLn $ "Sorry, not a supported codec for " ++ fp
Right img -> do
let imgGray :: Interface.Image VS I.Y Word8
imgGray = convert (img)
let new_res :: Interface.Image VS I.Y Word8
new_res = I.resize imgGray bor (dim1, dim2)
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
let (name, _) = splitExtension fp
writeFile (name ++ ".txt") (show rle)
我收到以下错误。如何从 arr
转换为 VS
?
Couldn't match expected type ‘Interface.Image VS I.Y Word8’
with actual type ‘Interface.Image arr0 I.Y Word8
-> Interface.Image arr0 I.Y Word8’
• In the expression: resize imgGray bor (dim1, dim2)
In an equation for ‘new_res’:
new_res = resize imgGray bor (dim1, dim2)
In the expression:
do let imgGray :: Interface.Image VS I.Y Word8
imgGray = convert (img)
let new_res :: Interface.Image VS I.Y Word8
new_res = resize imgGray bor ...
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
let (name, _) = splitExtension fp
....
|
34 | new_res = I.resize imgGray bor (dim1, dim2)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
resize
function in the Haskell Image Processing (HIP) library 使用 Image arr cs e
类型,所以我发现使用 HIP 库比使用 JuicyPixels 更容易读取图像。
类型从 Image VS Y Double
-> Image VS Y Word8
-> Pixel8
-> [[Int]]
-> Matrix Int
。
使用 HIP 的另一个优点是我们可以读取灰度图像 Pixel Y
而不是稍后进行转换。这是更改后的代码:
import Codec.Picture
import Codec.Picture.Types
import Graphics.Image.Processing
import qualified Graphics.Image as I
import qualified Graphics.Image.Interface as Interface
import Graphics.Image.ColorSpace
import Data.Word (Word8)
import qualified Data.Matrix as M
to2DMatrix :: FilePath -> (Int, Int) -> IO (Maybe (M.Matrix Int))
to2DMatrix fp (dim1, dim2)= do
eimg <- I.readImageY VS fp
let new_res :: Interface.Image VS I.Y Word8
new_res = I.resize Bilinear Edge (dim1, dim2) $ Interface.map conv eimg
let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
return $ Just (rle)
conv :: Interface.Pixel I.Y Double -> Interface.Pixel I.Y Word8
conv d = fmap Interface.toWord8 d
pixelToInt :: Image Pixel8 -> [[Int]]
pixelToInt =
map reverse . reverse . snd . pixelFold
(\(lastY, ps:pss) x y p ->
if y == lastY
then (y, (fromIntegral p:ps):pss)
else (y, [fromIntegral p]:ps:pss))
(0,[[]])
twoDToMatrix :: [[Int]] -> M.Matrix Int
twoDToMatrix lists = M.fromLists lists
conv
将每个像素从 Double
转换为 toWord8
。对于 toJPImageY8
函数,图像需要具有 Word8
精度。