使用Haskell語言實現基本影像識別

ttocr、com發表於2024-11-24

Haskell是一種純函數語言程式設計語言,廣泛應用於學術研究和高效能運算領域。它的惰性求值和強型別系統使得它在處理複雜的演算法時非常高效。以下是使用Haskell語言實現Sobel邊緣檢測的程式碼示例。

程式碼實現
為了進行影像處理,Haskell提供了多個影像處理庫,其中JuicyPixels和vector是常用的庫。在這個示例中,我們將使用JuicyPixels來讀取和儲存影像,並使用vector進行矩陣操作。

安裝必要的庫
首先,確保安裝了以下Haskell包:

bash

cabal update
cabal install JuicyPixels vector
Haskell程式碼
haskell
更多內容訪問ttocr.com或聯絡1436423940
import Codec.Picture
import Data.Vector.Storable (fromList, toList)
import qualified Data.Vector.Storable as V
import Control.Monad (forM_)

-- Sobel運算元
sobelX :: [Int]
sobelX = [-1, 0, 1, -2, 0, 2, -1, 0, 1]

sobelY :: [Int]
sobelY = [-1, -2, -1, 0, 0, 0, 1, 2, 1]

-- 影像灰度化
toGray :: Image PixelRGB8 -> Image Pixel8
toGray img = generate (imageWidth img) (imageHeight img) $ \x y ->
let PixelRGB8 r g b = pixelAt img x y
in round (0.299 * fromIntegral r + 0.587 * fromIntegral g + 0.114 * fromIntegral b)

-- 應用卷積運算元
applySobel :: Image Pixel8 -> [Int] -> Image Pixel8
applySobel img kernel = generate (imageWidth img) (imageHeight img) $ \x y ->
let sum = sumKernel x y img kernel
in min 255 (max 0 sum)

-- 計算卷積結果
sumKernel :: Int -> Int -> Image Pixel8 -> [Int] -> Int
sumKernel x y img kernel = sum $ zipWith (*) kernel neighbors
where
neighbors = map ((dx, dy) -> getPixel (x + dx) (y + dy)) [(dx, dy) | dx <- [-1..1], dy <- [-1..1]]
getPixel x' y' | x' < 0 || y' < 0 || x' >= imageWidth img || y' >= imageHeight img = 0
| otherwise = pixelAt img x' y'

-- 載入影像
loadImage :: FilePath -> IO (Image PixelRGB8)
loadImage = readImage >>= \case
Left err -> error err
Right img -> return $ convertRGB8 img

-- 儲存影像
saveImage :: FilePath -> Image Pixel8 -> IO ()
saveImage path img = writePng path img

-- 主函式
main :: IO ()
main = do
-- 載入影像
img <- loadImage "input_image.jpg"

-- 灰度化
let grayImg = toGray img

-- 應用Sobel運算元
let gradX = applySobel grayImg sobelX
let gradY = applySobel grayImg sobelY

-- 儲存結果
saveImage "output_image_x.png" gradX
saveImage "output_image_y.png" gradY

putStrLn "邊緣檢測完成,輸出儲存為 output_image_x.png 和 output_image_y.png"
步驟解析
載入影像
使用readImage從檔案中載入影像,並使用convertRGB8將其轉換為RGB8格式。toGray函式將RGB影像轉換為灰度影像。

應用Sobel運算元
applySobel函式對影像進行卷積操作,使用Sobel運算元分別計算水平和垂直方向的梯度。

儲存影像
使用writePng函式將處理後的影像儲存為PNG檔案。

示例輸出
假設輸入影像是一個灰度圖,程式將計算水平方向(output_image_x.png)和垂直方向(output_image_y.png)的邊緣影像。

執行方式
安裝Haskell開發環境並建立一個新專案。
使用以下命令安裝所需的庫:
bash

cabal install JuicyPixels vector
將程式碼儲存為EdgeDetection.hs。
編譯並執行程式:
bash

ghc -o edge_detection EdgeDetection.hs
./edge_detection

相關文章