packages feed

CV-0.3: CV/Edges.chs

{-#LANGUAGE ForeignFunctionInterface#-}
#include "cvWrapLEO.h"
module CV.Edges (sobelOp,sobel
                ,sScharr,s1,s3,s5,s7
                ,l1,l3,l5,l7
                ,laplaceOp,laplace,canny,susan) where
import Foreign.C.Types
import Foreign.C.String
import Foreign.ForeignPtr
import Foreign.Ptr

import CV.ImageOp

import CV.Image 
{#import CV.Image#}

import C2HSTools

-- | Perform Sobel filtering on image. First argument gives order of horizontal and vertical
--   derivative estimates and second one is the aperture. This function can also calculate
--   Scharr filter with aperture specification of sScharr
-- TODO: Type the aperture size and possibly the derivative orders as well
-- TODO: It is possible to define sobel with different target image with other bit depths.
sobelOp :: (Int,Int) -> SobelAperture -> ImageOperation GrayScale D32
sobelOp (dx,dy) (Sb aperture)
    | dx >=0 && dx <3
    && not ((aperture == -1) && (dx>1 || dy>1))
    && dy >=0 && dy<3 = ImgOp $ \i -> withGenImage i $ \image ->
                                      ({#call cvSobel#} image image cdx cdy cap)

   | otherwise = error "Invalid aperture" 
      where [cdx,cdy,cap] = map fromIntegral [dx,dy,aperture]

sobel dd ap im = unsafeOperate (sobelOp dd ap) im

-- | Aperture sizes for sobel operator
newtype SobelAperture = Sb Int
sScharr = Sb (-1)
s1 = Sb 1
s3 = Sb 3
s5 = Sb 5
s7 = Sb 7


-- | Aperture sizes for laplacian operator
newtype LaplacianAperture = L Int
l1 = L 1
l3 = L 3
l5 = L 5
l7 = L 7

-- |Perform laplacian filtering of given aperture to image
laplaceOp :: LaplacianAperture -> ImageOperation GrayScale D32
laplaceOp (L s) = ImgOp $ \img ->  withGenImage img $ \image -> 
                        ({#call cvLaplace #} image image (fromIntegral s)) 

laplace s i = unsafeOperate (laplaceOp s) i

-- |Perform canny thresholding using two threshold values and given aperture
--  Works only on 8-bit images
canny :: Int -> Int -> Int -> Image GrayScale D8 -> Image GrayScale D8
canny t1 t2 aperture src = unsafePerformIO $ do
                           withClone src $ \clone -> 
                            withGenImage src $ \si ->
                             withGenImage clone $ \ci -> do
                               {#call cvCanny#} si ci (fromIntegral t1) 
                                                      (fromIntegral t2) 
                                                      (fromIntegral aperture)
                               return clone
                               
                            
                             
-- | SUSAN edge detection filter, see http://users.fmrib.ox.ac.uk/~steve/susan/susan/susan.html
-- TODO: Should return a binary image
susan :: (Int,Int) -> D32 -> Image GrayScale D32 -> Image GrayScale D8
susan (w,h) t image = unsafePerformIO $ do
                    withGenImage image $ \img ->
                     creatingImage
                      ({#call susanEdge#} img (fromIntegral w) (fromIntegral h) (realToFrac t))