SML-Dplab

Dplab

实验背景

本实验介绍了一种快速的横向或者纵向缩放图片的算法,采用了动态规划的思想,即通过找寻一张图中像素相近的一条条“缝”,然后去这条缝上的全部像素,这样的话删除多条缝即可达到缩放的目的。

实验代码

  fun generateGradients ({width, height, data}:image):gradient seq seq = 
    let
    	fun square x = Math.pow (x,2.0)
    	fun delta (p:pixel,q:pixel) = square (#r q - #r p) + square (#g q - #g p) + square (#b q - #b p)
    	fun findPixel (i,j) = nth (nth data i) j
    	val $$ =  findPixel
    	fun sigGre (i,j) = Math.sqrt (delta ($$ (i,j), $$ (i,j+1)) + delta ($$ (i,j), $$ (i+1,j)))
    	fun mapping (i:int,h:pixel seq) =  
    		if i = (height-1) then map (fn _ => 0.0) h
    		 else mapIdx (fn (j,x) => if j = width - 1 then 1000000.0 else sigGre (i,j)) h
    	val res = mapIdx (fn (i,h) => mapping (i,h)) data
    in
    	res
    end

  fun findSeam (G:gradient seq seq) : int seq =     let      val height = length G      val width = length (nth G 0)      fun findGradient T (i,j) = nth (nth T i) j      val $$ = findGradient      fun findMin (x,y,z) = Real.min (x,Real.min(y,z))      fun sigSeam j x T =       if j = 0 then x + Real.min (nth T j,nth T (j+1))       else if j = width - 1 then x + Real.min (nth T (j-1),nth T j)       else x + findMin (nth T (j-1),nth T j,nth T (j+1))      fun findSeam' (G:gradient seq seq) (T:(int*real seq) list) (i:int) : (int*real seq) list=       if i = 0 then T       else        let         val PT = findSeam' G T (i-1)         val tmp = (i,mapIdx (fn (j,x)=> sigSeam j x (#2 (List.nth (PT,0)))) (nth G i))         val T' = tmp::PT        in         T'        end      val seamT = inject (fromList (findSeam' G [(0,nth G 0)] (height - 1))) G      fun Min S = reduce (fn ((i,x),(j,y)) => if x<y then (i,x) else (j,y)) (0,1000000.0) (mapIdx (fn (i,x) => (i,x)) S)      fun generateSeam S G T i (idx,seam) =       if i < 0 then S       else if i = height-1 then generateSeam ((i,#1 (Min (nth T i)))::S) G T (i - 1) (Min (nth T i))       else        let         fun Compare ((i,x,u),(j,y,v),(k,z,w)) =          if Real.== (findMin (x,y,z),x) then (i,x,u)          else if Real.== (findMin (x,y,z),y) then (j,y,v)          else (k,z,w)         val pV = $$ G (i+1,idx)         (*val _ = print (Real.toString ($$ T (i,idx+1)) ^ " ")         val _ = print (Int.toString idx ^ " " ^ Int.toString i ^ " " ^ Int.toString width ^ " " ^Int.toString height ^ " ")*)         val pS = if idx = 0 then ((i,$$ T (i,idx),idx),(i,$$ T (i,idx + 1),idx + 1),(0,10000000000.0,0))           else if idx = width - 1 then ((i,$$ T (i,idx),idx),(i,$$ T (i,idx - 1),idx - 1),(0,100000000000.0,0))           else ((i,$$ T (i,idx - 1),idx - 1),(i,$$ T (i,idx),idx),(i,$$ T (i,idx + 1),idx + 1))            val V = Compare pS         (*val _ = print (Int.toString (length V) ^ "\n")*)         val V' = case V of (i,_,x) => (i,x)        in         generateSeam (V'::S) G T (i-1) (#3 V,#2 V)        end      val injection = fromList (generateSeam ([]) G seamT (height-1) (0,0.0))     in      inject injection (tabulate (fn _ => 0) height)     end



 
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值