基于Iterated conditional models和Graph-cut的黑白图像去噪(Haskell语言实现)

本文介绍了一种使用Haskell语言实现的基于Iterated conditional models和Graph-cut算法的黑白图像去噪方法。首先讲述了问题背景,即接收并处理(01)*表示的文本文件图像。接着,文章深入探讨了相关理论基础,包括算法的工作原理。随后,作者分享了函数设计思路,并讨论了效率优化。最后,提供了完整的源代码供读者参考。
摘要由CSDN通过智能技术生成

事情起因


同组的队友说他已经把图像转成内容为(01)*的文本文件,要我用除Java以外的语言接收这个文本文件进行去噪,就想用Haskell试试。


问题描述


对于一个二色(用{-1,+1}表示)加噪图像进行去噪处理。


理论基础


基于Graph-cu t得出下列能量计算式。



xi为去噪图像的像素点,yi为加噪图像的加噪点
。我们的目标是让上式所得的能量最低。

基于Iterated conditional models,对于每个i,我们将xi = yi,然后扫描所有xi,将xi置为-1和+1两种情况,将能量更低的情况作为新的去噪图像继续扫描。


函数构思


函数列表:
将(01)*串变成{+1,-1}的数组:stringToInt :: String -> [Int]
同理需要:intToString :: [Int] -> String
去噪总函数:deNoise :: ([Int], [Int]) -> [Int] -> [Int]
选择低能量:selectLowerEnergy :: ([Int], [Int], [Int]) -> [Int] -> ([Int], [Int])
计算能量:evaluateEnergy :: [Int] -> [Int] -> (Int, Int, Int) -> Int


效率


由于每次计算能量都要重算整个图像,计算能量的时间复杂度为O(n*n) + O(n*n*logn ) + O(n*n)
扫描整个图像的时间复杂度为O(n*n)
故总的时间复杂度为O(n^4 * logn)
可见这段代码的效率还有待提高


源代码

import System.IO
import Data.List


main = do
  noiseString <- readFile "noise.txt"
  let numList = stringToInt noiseString
      newNumList = deNoise ([], numList) numList
      newNoiseString = intToString newNumList
  writeFile "deNoise.txt" newNoiseString


--去噪函数,利用元组输入xs便于迭代更新xs
deNoise :: ([Int], [Int]) -> [Int] -> [Int]
deNoise (xs, []) ys = xs
deNoise (xs1, x:xs2) ys = deNoise (selectLowerEnergy (xs1, [x], xs2) ys) ys


--选择低能量xs
selectLowerEnergy :: ([Int], [Int], [Int]) -> [Int] -> ([Int], [Int])
selectLowerEnergy (xs1, _, xs2) ys
  | e1 < e2 = (xs1++[1], xs2)
  | otherwise = (xs1++[-1], xs2)
  where e1 = evaluateEnergy s1 ys (1, 1, 2)
        e2 = evaluateEnergy s2 ys (1, 1, 2)
        s1 = xs1 ++ [1] ++ xs2
        s2 = xs1 ++ [-1] ++ xs2


--默认输入64x64的图像
--e2的计算输要将数组转成二维数组,然后对相邻行进行求积求和
--翻转之后再求积求和,相加之后就可以得出e2
evaluateEnergy :: [Int] -> [Int] -> (Int, Int, Int) -> Int
evaluateEnergy xs ys (h, beta, eta) = h * e1 - beta * e2 - eta * e3
  where e1 = sum xs
        matrix = toMatrix 64 xs
        e2 = (sumOfMatrixRow matrix) + (sumOfMatrixRow $ transpose matrix)
        e3 = sum $ zipWith (*) xs ys


--dim为维数,正确的说是每一行的长度
--不需要确定行数。
toMatrix :: Int -> [Int] -> [[Int]]
toMatrix _ [] = []
toMatrix dim xs = y:(toMatrix dim ys)
         where (y,ys) = splitAt dim xs


sumOfMatrixRow :: [[Int]] -> Int
sumOfMatrixRow (xs:[]) = 0
sumOfMatrixRow (xs:ys:xss) = sumOfMatrixRow (ys:xss) + (sum $ zipWith (*) xs ys)


stringToInt :: String -> [Int]
stringToInt = map checkString
               where checkString '0' = -1
                     checkString '1' = 1
                     checkString _ = 0


intToString :: [Int] -> String
intToString = map checkInt
               where checkInt 1 = '1'
                     checkInt (-1) = '0'
                     checkInt _ = '2'

计算能量:evaluateEnergy :: [Int] -> [Int] -> (Int, Int, Int) -> Int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值