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

事情起因

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

问题描述

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

理论基础

  基于Graph-cu t得出下列能量计算式。
  
  xi为去噪图像的像素点,yi为加噪图像的加噪点。我们的目标是让上式所得的能量最低。

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

函数构思

函数功能
stringToInt :: String -> [Int]将(01)*串变成{+1,-1}的数组
intToString :: [Int] -> String将{+1,-1}串变成(01)*的数组
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)
  n为图像的边长,可见这段代码的效率还有待提高

源代码

 1 import System.IO
 2 import Data.List
 3 
 4 
 5 main = do
 6   noiseString <- readFile "noise.txt"
 7   let numList = stringToInt noiseString
 8       newNumList = deNoise ([], numList) numList
 9       newNoiseString = intToString newNumList
10   writeFile "deNoise.txt" newNoiseString
11 
12 
13 --去噪函数,利用元组输入xs便于迭代更新xs
14 deNoise :: ([Int], [Int]) -> [Int] -> [Int]
15 deNoise (xs, []) ys = xs
16 deNoise (xs1, x:xs2) ys = deNoise (selectLowerEnergy (xs1, [x], xs2) ys) ys
17 
18 
19 --选择低能量xs
20 selectLowerEnergy :: ([Int], [Int], [Int]) -> [Int] -> ([Int], [Int])
21 selectLowerEnergy (xs1, _, xs2) ys
22   | e1 < e2 = (xs1++[1], xs2)
23   | otherwise = (xs1++[-1], xs2)
24   where e1 = evaluateEnergy s1 ys (1, 1, 2)
25         e2 = evaluateEnergy s2 ys (1, 1, 2)
26         s1 = xs1 ++ [1] ++ xs2
27         s2 = xs1 ++ [-1] ++ xs2
28 
29 
30 --默认输入64x64的图像
31 --e2的计算输要将数组转成二维数组,然后对相邻行进行求积求和
32 --翻转之后再求积求和,相加之后就可以得出e2
33 evaluateEnergy :: [Int] -> [Int] -> (Int, Int, Int) -> Int
34 evaluateEnergy xs ys (h, beta, eta) = h * e1 - beta * e2 - eta * e3
35   where e1 = sum xs
36         matrix = toMatrix 64 xs
37         e2 = (sumOfMatrixRow matrix) + (sumOfMatrixRow $ transpose matrix)
38         e3 = sum $ zipWith (*) xs ys
39 
40 
41 --dim为维数,正确的说是每一行的长度
42 --不需要确定行数。
43 toMatrix :: Int -> [Int] -> [[Int]]
44 toMatrix _ [] = []
45 toMatrix dim xs = y:(toMatrix dim ys)
46          where (y,ys) = splitAt dim xs
47 
48 
49 sumOfMatrixRow :: [[Int]] -> Int
50 sumOfMatrixRow (xs:[]) = 0
51 sumOfMatrixRow (xs:ys:xss) = sumOfMatrixRow (ys:xss) + (sum $ zipWith (*) xs ys)
52 
53 
54 stringToInt :: String -> [Int]
55 stringToInt = map checkString
56                where checkString '0' = -1
57                      checkString '1' = 1
58                      checkString _ = 0
59 
60 
61 intToString :: [Int] -> String
62 intToString = map checkInt
63                where checkInt 1 = '1'
64                      checkInt (-1) = '0'
65                      checkInt _ = '2'
66  
Source Code(Haskell)

 

转载于:https://www.cnblogs.com/wu10022/p/4101622.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值