 
 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
 
-laplaceOp :: Int -> ImageOperation GrayScale D32
-laplaceOp s = ImgOp $ \img ->  withGenImage img $ \image -> 
-                    if s `elem` [1,3,5,7]
-                       then ({#call cvLaplace #} image image (fromIntegral s)) 
-                       else error "Laplace aperture must be 1, 3, 5 or 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
 
--- TODO: Add tests below!
+-- |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 -> 


import C2HSTools

sobelOp :: (Int,Int) -> Int -> ImageOperation GrayScale D32
sobelOp (dx,dy) aperture 
    | dx >=0 && dx <3
    && aperture `elem` [-1,1,3,5,7]
    && not ((aperture == -1) && (dx>1 || dy>1))
    && dy >=0 && dy<3 = ImgOp $ \i -> withGenImage i $ \image ->
                                      ({#call cvSobel#} image image cdx cdy cap)

                               
                            
                             
-- | 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 ->
