【问题标题】:How to convert precision in Image type from Double to Word8 using HIP?如何使用 HIP 将图像类型的精度从 Double 转换为 Word8?
【发布时间】:2020-06-11 18:09:10
【问题描述】:

我有一个 Image VS Y Double 类型的图像(在使用 HIP 库中的函数 readImageY 之后),我想将其转换为 Image VS Y Word8。我该怎么做呢?我需要在这个精度下应用它的下一个函数。

这是相关代码的sn-p:

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 Graphics.Image.IO
import Graphics.Image.IO.Formats
import Graphics.Image.Interface.Vector
import qualified Graphics.Image.Interface as Interface
import Data.Word (Word8)
import qualified Data.Matrix as M
import System.FilePath.Posix (splitExtension)

to2DMatrix :: FilePath -> FilePath -> Border(Interface.Pixel I.Y Word8) -> (Int, Int) -> IO ()
to2DMatrix fp fpout bor (dim1, dim2)= do
    eimg <- I.readImageY VS fp
    let new_res :: Interface.Image VS I.Y Word8
        new_res = I.resize Bilinear bor (dim1, dim2) eimg 
    let rle = twoDToMatrix $ pixelToInt $ toJPImageY8 new_res
    let (name, _) = splitExtension fp
    writeFile (name ++ ".txt") (show rle)
    writeImage fpout rle

这是错误:

Couldn't match type ‘Double’ with ‘Word8’
      Expected type: Interface.Image VS I.Y Word8
        Actual type: Interface.Image VS I.Y Double
    • In the fourth argument of ‘resize’, namely ‘eimg’
      In the expression: resize Bilinear bor (dim1, dim2) eimg
      In an equation for ‘new_res’:
          new_res = resize Bilinear bor (dim1, dim2) eimg
   |
29 |         new_res = I.resize Bilinear bor (dim1, dim2) eimg
   |                                                      ^^^^

编辑: 双精度值是在图像类型中存储为 VS 向量类型的灰度像素值。我遇到的问题是可以访问双打以便能够转换它们。试图解释/找到 HIP 库 here 的方法,但我是 Haskell 的新手,无法弄清楚。

【问题讨论】:

  • 您确定要将Double 转换为Word8 吗?因为 AFAIK Word8 代表 8-bit unsigned integer 而您需要 64 位来代表 Double。因此,您可以使用 doubleToWord :: Double -&gt; Word64 from Data.Serialize.IEEE754
  • 您可以使用roundfloorceiling之类的函数将Double转换为Integral类的编号(会有精度损失),然后使用fromIntegral将其转换为Word8 类似doubleToWord8 = fromIntegral . round
  • 这些双打是什么?可能是零到一范围内的黑/白?如果是这样,请考虑使用 conv d = floor (d * 255) 转换为 0-255
  • 那个操作是map。如果没有看到您的代码,我不确定您的导入,但请尝试 Interface.map conv eimg
  • conv 一个类型,你就会明白为什么错了。初学者经常混淆函数组合和函数应用。简而言之,fromIntegral (floor (d*255))

标签: image haskell juicy-pixels hip


【解决方案1】:

Haskell 图像处理 (HIP) 库中的 Graphics.Image.Interface 中有一个类 Elevator,它允许您将像素精度从/更改为多种精度类型。

这是更改的代码的 sn-p:

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 :: Pixel Y Double -> Pixel Y Word8 
conv d = toWord8 <$> d

&lt;$&gt;fmap 的中缀运算符版本。所以这与:

conv :: Pixel Y Double -> Pixel Y Word8 
conv d = fmap toWord8 d

将输入图像转换为矩阵的额外细节:

pixelToInt 类型从 Pixel8 更改为 [[Int]]

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,[[]])

然后,您可以根据需要使用 Data.Matrix 将 [[Int]] 更改为 Data.Matrix Matrix 类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多