Haskell HIP: применение фильтра к изображению

Я пытаюсь добавить фильтр к изображению с помощью пакета HIP для обработки изображений Haskell, я смог прочитать изображение с помощью пакета ByteString и преобразовать изображение в типImage VS YCbCr Word8с помощью HIP. Теперь, как мне конвертировать изImage VS YCbCr Word8 к Border (Pixel cs e) или Pixel cs e? Я все еще изучаю Haskell, поэтому не усложняйте его. см. код ниже:

addFilterJpg :: FilePath -> IO ()
addFilterJpg fc = do
    case validPath fc of 
        Left err -> putStrLn err
        Right img -> do
            case readImage img of
                Left err -> putStrLn err
                Right img -> do
                  -- convert img::(Image VS YCbCr Word8) to Border (Pixel cs e)
                  -- apply filter
                  -- save image
                  putStrLn "Convolution Filter"

1 ответ

Решение

С вашим вопросом есть пара проблем:

  • Во-первых, вам не хватает декларации validPathфункция. Я предполагаю, что он выполняет некоторую проверку пути к файлу, поэтому я просто проигнорирую его в ответе.
  • readImage является IO действие, поэтому вы не можете просто сопоставить шаблон Either, вам нужно сначала выполнить его.
  • Вам также нужно где-то вывести изображение результата, поэтому вам также нужен путь

Еще несколько примечаний к изображению:

  • Применение свертки к изображению в кодировке YCbCr на самом деле не имеет смысла, поэтому вам нужно либо преобразовать в RGB, либо в оттенки серого Y. Я предполагаю, что вам нужен цвет, поэтому мы будем использовать RGB
  • Вы не указали, какой фильтр вам нужен, поэтому просто выберем размытие по Гауссу.
applyFilterJpg :: FilePath -> FilePath -> IO ()
applyFilterJpg fcin fcout = do
  eImg <- readImageExact JPG fcin
  case eImg of
    Left err -> putStrLn err
    Right img -> do
      let imgRGB :: Image VS RGB Double
          imgRGB = convert (img :: Image VS YCbCr Word8)
          gaussianBlurKernel :: Image VS X Double
          gaussianBlurKernel = fromLists $ [ [ 1/16, 1/8, 1/16 ]
                                           , [  1/8, 1/4,  1/8 ]
                                           , [ 1/16, 1/8, 1/16 ] ]
          convRGB = convolve Edge gaussianBlurKernel imgRGB
      writeImage fcout convRGB

Вот что мы получим, когда запустим его:

При этом уже есть встроенные функции, которые упростят вам весь этот процесс:

  • Используйте функции импорта, которые уже выполняют преобразование за вас, поэтому вам не нужно возиться с ручным преобразованием цветовых пространств.
  • Вместо того, чтобы поставлять ядро ​​для фильтра вручную, проверьте, есть ли уже необходимое вам ядро ​​в HIP.
addFilterJpg' :: FilePath -> FilePath -> IO ()
addFilterJpg' fcin fcout = do
  imgRGB <- readImageRGB VS fcin
  let convRGB = applyFilter (gaussianBlur 1) imgRGB
  writeImage fcout convRGB

Это результат вышеуказанной функции:

Другие вопросы по тегам