CV-0.3.1.2: CV/ImageOp.hs
module CV.ImageOp where
import Foreign
import CV.Image
import Control.Monad ((>=>))
import Data.Monoid
import Control.Category
import Prelude hiding ((.),id)
-- |ImageOperation is a name for unary operators that mutate images inplace.
newtype ImageOperation c d = ImgOp (Image c d-> IO ())
-- |Compose two image operations
(#>) :: ImageOperation c d-> ImageOperation c d -> ImageOperation c d
(#>) (ImgOp a) (ImgOp b) = ImgOp (\img -> (a img >> b img))
-- |An unit operation for compose
nonOp = ImgOp (\i -> return ())
-- |Apply image operation to a Copy of an image
img <# op = unsafeOperate op img
-- motivating example:
-- >>> hop i = stretchHistogram $ i #- gaussian (5,5)
-- allocates two extra images
-- >>> hop = (gaussian (5,5) &#& id) #> subtract #> stretchHistogram
-- could be implemented in a way that allocates just one extra
fromImageOp (ImgOp f) = IOP $ \i -> (f i >> return i)
newtype IOP a b = IOP (a -> IO b)
instance Category IOP where
id = IOP return
(IOP f) . (IOP g) = IOP $ g >=> (f >>= return)
(&#&) :: IOP (Image c d) e -> IOP (Image c d) f -> IOP (Image c d) (Image c d,Image c d)
(IOP f) &#& (IOP g) = IOP $ op
where
op i = withCloneValue i $ \cl -> (f i >> g cl >> return (i,cl))
unsafeOperate op img = unsafePerformIO $ operate op img
runIOP (IOP f) img = withCloneValue img $ \clone -> f clone
-- |Apply list of image operations to a Copy of an image. (Makes a single copy and is
-- faster than folding over (<#)
img <## [] = img
img <## op = unsafeOperate (foldl1 (#>) op) img
-- runImageOperation :: Image c d -> ImageOperation c d -> IO (Image c d)
operate (ImgOp op) img = withClone img $ \clone ->
op clone >> return clone
operateOn = flip operate
-- |Iterate an operation N times
times n op = foldl (#>) nonOp (replicate n op)
directOp i (ImgOp op) = op i
operateInPlace (ImgOp op) img = op img
unsafeOperateOn img op = unsafePerformIO $ operate op img
operateWithROI pos size (ImgOp op) img = withClone img $ \clone ->
withIOROI pos size clone (op clone)