packages feed

CV 0.3.1.2 → 0.3.4

raw patch · 36 files changed

+4544/−2744 lines, 36 filesdep +bindings-DSLdep +lazysmallcheckdep +vectordep −JYU-Utilsdep ~parallelbinary-added

Dependencies added: bindings-DSL, lazysmallcheck, vector

Dependencies removed: JYU-Utils

Dependency ranges changed: parallel

Files

CV.cabal view
@@ -1,10 +1,11 @@ Name:				 CV-Version:             0.3.1.2+Version:             0.3.4 Description:         OpenCV Bindings License:             GPL License-file:        LICENSE Category:            AI, Graphics, Machine Vision Synopsis:            OpenCV based machine vision library+Homepage:            http://aleator.github.com/CV/ Description:         This is a machine vision package that wraps some functionality                      of OpenCV library. This package has been developed for personal use and                      is not meant to be a complete wrapper. It also includes some things not@@ -14,46 +15,69 @@                      and code clean-up, but is somewhat tested.                      .                      (The scarce) Documentation is available at -                      <http://users.jyu.fi/~aleator/CV-0.3.0.2/html/index.html>+                      <http://http://aleator.github.com/CV/>                      .                      Changelog.+                     0.3.4 - Pixelwise operations, bug fixes and additional documentation+                     .+                     0.3.3.0 - Improvements, including compatablity with opencv 2.3.1 and removal of+                     dependency with deprecated JYU.Utils+                     .+                     Changelog.+                     0.3.2.0 - Improvements, including fancier pixel-wise manipulations +                     .+                     Changelog.                      0.3.0.2 - Workaround for compiling with OS X 10.6 & fixed errors about M_PI                      .  Author:              Ville Tirronen Maintainer:          ville.tirronen@jyu.fi Build-Type:          Simple-Cabal-Version:       >=1.6+Cabal-Version:       >=1.8 Extra-Source-Files:                      examples/*.hs                      examples/shapes/*.png                      examples/shapePhoto.jpg+                     examples/chess.png                      examples/fuse1.png                      examples/fuse2.png                      examples/smallLena.jpg                      examples/elaine.jpg+Flag opencv23+  Description: Compatability for opencv 2.3.1+  Default:     False + Library     Build-Tools:       c2hs >= 0.16.0-    Include-dirs:      CV/  -    Includes:          opencv/cv.h, opencv/cxcore.h, opencv/highgui.h, CV/cvWrapLEO.h-    c-sources:         CV/cvWrapLEO.c-    install-includes:  CV/cvWrapLEO.h+    Include-dirs:      cbits/  +    Includes:          opencv/cv.h, opencv/cxcore.h, opencv/highgui.h, cbits/cvWrapLEO.h+    c-sources:         cbits/cvWrapLEO.c+    install-includes:  cbits/cvWrapLEO.h+    if flag(opencv23)+         cpp-options: -DOpenCV23+         cc-options: -DOpenCV23     cc-options:        --std=c99 -U__BLOCKS__     extra-libraries:   opencv_calib3d,opencv_contrib,opencv_core,opencv_features2d,opencv_highgui,opencv_imgproc,opencv_legacy,opencv_ml,opencv_objdetect,opencv_video      -    Build-Depends:     haskell98, base >= 3 && < 5, parallel > 1.1, unix > 2.3, array >= 0.2.0.0,+    Build-Depends:     haskell98, base >= 3 && < 5, parallel > 3.1, unix > 2.3, array >= 0.2.0.0,                        mtl >= 1.1.0, random >= 1.0.0, carray >= 0.1.5, QuickCheck >= 2.1, -                       containers >= 0.2, JYU-Utils >= 0.1 && < 0.2,-                       storable-complex, binary >= 0.5, deepseq >= 1.1+                       containers >= 0.2, +                       storable-complex, binary >= 0.5, deepseq >= 1.1,+                       bindings-DSL >= 1.0.14 && < 1.1, vector >= 0.7.0.1 && < 1.1,+                       lazysmallcheck >= 0.5 && < 1     Exposed-modules:   CV.Image, CV.ImageOp, CV.ImageMath CV.Sampling, CV.Edges, CV.Filters,                         CV.Morphology, CV.ColourUtils, CV.ImageMathOp, CV.Video,                        CV.Textures,CV.Drawing, CV.Thresholding, CV.Histogram,  CV.LightBalance,                        CV.TemplateMatching, CV.Transforms, CV.Conversions,                        CV.Binary, CV.Marking, CV.FunnyStatistics,                        CV.MultiresolutionSpline,  CV.Gabor,-                       CV.ConnectedComponents, CV.HighGUI-    Other-modules:     C2HSTools, C2HS+                       CV.ConnectedComponents, CV.HighGUI, CV.Calibration+                       CV.Pixelwise, CV.Matrix, CV.Arbitrary+                       Utils.List, Utils.Point, Utils.Rectangle, Utils.Stream, Utils.Function+    Other-modules:     C2HSTools, C2HS, CV.Bindings.Matrix, CV.Bindings.Calibrate+    Extensions: CPP+  source-repository head   type:     git
+ CV/Arbitrary.hs view
@@ -0,0 +1,42 @@+-- | This module provides QuickCheck generators for images.+module CV.Arbitrary (smallImage,constImage, noisyImage,smoothImage,blockNoise) where++import Control.Applicative +import CV.Image+import CV.Pixelwise+import CV.Filters+import Test.QuickCheck+import Test.QuickCheck.Gen+import Control.Monad++newtype ZeroOne = ZO {unZo :: Float}+instance Arbitrary ZeroOne where+    arbitrary = ZO <$> choose (0,1)++-- | Generate a random small image, that might be constant, noisy or smoothly varying+--   Range of values is [0,1]+smallImage :: Gen (Image GrayScale D32)+smallImage = oneof [constImage, noisyImage,smoothImage]++-- | Generate 10x10 constant image+constImage :: Gen (Image GrayScale D32)+constImage = do+              ZO f <- arbitrary+              return $ toImage $ MkP {sizeOf = (10,10), eltOf = const f} ++-- | Generate 10x10 noisy image+noisyImage :: Gen (Image GrayScale D32)+noisyImage = do+              f <- arbitrary+              return $ toImage $ MkP {sizeOf = (10,10), eltOf = unZo . f} ++-- | Generate 10x10 smoothly varying image+smoothImage :: Gen (Image GrayScale D32)+smoothImage = gaussian (5,5) <$> noisyImage++blockNoise1  = montage (2,2) 0 <$> replicateM 4 smallImage++-- | Generate a (10m x 10m) sized noisy image.+blockNoise :: Int -> Gen (Image GrayScale D32)+blockNoise m = montage (m,m) 0 . replicate (m*m) <$> blockNoise1+
+ CV/Bindings/Calibrate.hsc view
@@ -0,0 +1,53 @@+{-# LANGUAGE ForeignFunctionInterface #-}++#include <bindings.dsl.h>+#include "cvWrapLEO.h"++module CV.Bindings.Calibrate where+import Data.Word+import Foreign.C.Types+import CV.Bindings.Matrix+import CV.Image++#strict_import++-- typedef struct+-- {+--     int width;+--     int height;+-- }+-- CvSize;++#starttype CvSize+#field width , CInt+#field height , CInt+#stoptype++#starttype CvPoint2D32f+#field x , Float+#field y , Float+#stoptype++ +#ccall wrapCalibrateCamera2 , Ptr <CvMat> -> Ptr <CvMat> -> Ptr <CvMat> -> Ptr <CvSize> -> Ptr <CvMat> -> Ptr <CvMat> -> Ptr <CvMat> ->  Ptr <CvMat> -> CInt -> IO Double++#ccall wrapFindCornerSubPix , Ptr BareImage -> Ptr <CvPoint2D32f> -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Double -> IO ()++#num CV_TERMCRIT_ITER+#num CV_TERMCRIT_EPS+++#num CV_CALIB_USE_INTRINSIC_GUESS  +#num CV_CALIB_FIX_ASPECT_RATIO     +#num CV_CALIB_FIX_PRINCIPAL_POINT  +#num CV_CALIB_ZERO_TANGENT_DIST    +#num CV_CALIB_FIX_FOCAL_LENGTH +#num CV_CALIB_FIX_K1  +#num CV_CALIB_FIX_K2  +#num CV_CALIB_FIX_K3  +#num CV_CALIB_FIX_K4  +#num CV_CALIB_FIX_K5  +#num CV_CALIB_FIX_K6  +#num CV_CALIB_RATIONAL_MODEL ++
+ CV/Bindings/Matrix.hsc view
@@ -0,0 +1,90 @@+{-# LANGUAGE ForeignFunctionInterface #-}++#include <bindings.dsl.h>+#include "cvWrapLEO.h"++module CV.Bindings.Matrix where+import Data.Word+import Foreign.C.Types++#strict_import++#starttype CvMat+#field type , CInt +#field step , CInt+#field refcount , Ptr CInt +#union_field data.ptr , Ptr CUChar +#union_field data.s   , Ptr CShort +#union_field data.i   , Ptr CInt +#union_field data.fl  , Ptr CFloat +#union_field data.db  , Ptr CDouble +#field rows , CInt+#field cols , CInt+#stoptype++#ccall cvCreateMat  , Int -> Int -> Int -> IO (Ptr <CvMat>) +#ccall cvReleaseMat , Ptr (Ptr <CvMat>) -> IO ()++#ccall cvTranspose  , Ptr <CvMat> -> Ptr <CvMat> -> IO ()+#ccall cvGEMM       , Ptr <CvMat> -> Ptr <CvMat> -> Double -> Ptr <CvMat> -> Double -> Ptr <CvMat> -> Int -> IO ()++#ccall cvRodrigues2  , Ptr <CvMat> -> Ptr <CvMat> -> Ptr <CvMat> -> IO Int++#num CV_GEMM_A_T+#num CV_GEMM_B_T+#num CV_GEMM_C_T++#num CV_8UC1 +#num CV_8UC2 +#num CV_8UC3 +#num CV_8UC4 ++#num CV_8SC1 +#num CV_8SC2 +#num CV_8SC3 +#num CV_8SC4 ++#num CV_16UC1 +#num CV_16UC2 +#num CV_16UC3 +#num CV_16UC4 ++#num CV_16SC1 +#num CV_16SC2 +#num CV_16SC3 +#num CV_16SC4 ++#num CV_32SC1 +#num CV_32SC2 +#num CV_32SC3 +#num CV_32SC4 ++#num CV_32FC1 +#num CV_32FC2 +#num CV_32FC3 +#num CV_32FC4 ++#num CV_64FC1 +#num CV_64FC2 +#num CV_64FC3 +#num CV_64FC4 +++-- typedef struct CvMat+-- {+--     int type;+--     int step;+--     int* refcount;+--     union+--     {+--         uchar* ptr;+--         short* s;+--         int* i;+--         float* fl;+--         double* db;+--     } data;+--     int rows;+--     int cols;+-- } CvMat;++
+ CV/Calibration.chs view
@@ -0,0 +1,173 @@+{-#LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+#include "cvWrapLEO.h"+-- | This module exposes opencv functions for camera calibration using a chessboard rig. This module follows opencv quite closely and the best documentation+--   is probably found there. As quick example however, the following program detects and draws chessboard corners from an image.+--+-- @+-- module Main where+-- import CV.Image+-- import CV.Calibration+-- +-- main = do+--     Just i <- loadColorImage \"chess.png\"+--     let corners = findChessboardCorners (unsafeImageTo8Bit i) (4,5) (FastCheck:defaultFlags)+--     let y = drawChessboardCorners (unsafeImageTo8Bit i) (4,5) corners+--     mapM_ print (corners)+--     saveImage \"found_chessboard.png\" y+-- @+module CV.Calibration +    (+     -- * Finding chessboard calibration rig+     FindFlags(..)+    ,defaultFlags+    ,findChessboardCorners+    ,refineChessboardCorners+    -- * Visualization+    ,drawChessboardCorners+    -- * Camera calibration+    ,calibrateCamera2) where+{-#OPTIONS-GHC -fwarn-unused-imports #-}+import Foreign.C.Types+import Foreign.C.String+import Foreign.ForeignPtr+import Foreign.Storable+import Foreign.Marshal.Array+import Foreign.Ptr+import Data.Bits++import CV.Image ++import C2HSTools+import Utils.Point+import Control.Applicative++import CV.Matrix+import CV.Bindings.Calibrate++{#import CV.Image#}++#c+enum FindFlags {+     AdaptiveThresh  = CV_CALIB_CB_ADAPTIVE_THRESH+    ,NormalizeImage  = CV_CALIB_CB_NORMALIZE_IMAGE+    ,FilterQuads     = CV_CALIB_CB_FILTER_QUADS+    ,FastCheck       = CV_CALIB_CB_FAST_CHECK+    };+#endc++-- | Flags for the chessboard corner detector. See opencv documentation for cvFindChessboardCorners.+{#enum FindFlags {}#}++flagsToNum fs = foldl (.|.) 0 $ map (fromIntegral . fromEnum) fs++-- |Default flags for finding corners+defaultFlags :: [FindFlags]+defaultFlags = [AdaptiveThresh]++-- | Find the inner corners of a chessboard in a given image. +findChessboardCorners :: CV.Image.Image RGB D8 -> (Int, Int) -> [FindFlags] -> [(Float,Float)]+findChessboardCorners image (w,h) flags =+   unsafePerformIO $ +    with 1 $ \(c_corner_count::Ptr CInt) -> +     allocaArray len $ \(c_corners :: Ptr CvPoint )-> +      withGenImage image $ \c_image -> do+        r <- {#call wrapFindChessBoardCorners#} c_image (fromIntegral w) (fromIntegral h)+                                           (castPtr c_corners) c_corner_count +                                           (flagsToNum flags)+        count <- peek c_corner_count+        arr <- peekArray (fromIntegral count) c_corners+        return (map cvPt2Pt arr) +  where len = w*h++-- |Given an estimate of chessboard corners, provide a subpixel estimation of actual corners.+refineChessboardCorners :: Image GrayScale D8 -> [(Float,Float)] -> (Int,Int) -> (Int,Int) -> [(Float,Float)]+refineChessboardCorners img pts (winW,winH) (zeroW,zeroH) = unsafePerformIO $ do+    with 1 $ \(c_corner_count::Ptr CInt) -> +      withImage img $ \c_img ->+      withArray (map mkPt pts) $ \(c_corners :: Ptr C'CvPoint2D32f ) -> do +        c'wrapFindCornerSubPix c_img c_corners (length pts) winW winH zeroW zeroH tType maxIter epsilon +        map fromPt `fmap` peekArray (length pts) c_corners+ where+    mkPt (x,y) = C'CvPoint2D32f x y+    fromPt (C'CvPoint2D32f x y) = (x,y)+    tType = c'CV_TERMCRIT_ITER+    maxIter = 100+    epsilon = 0.01++-- | Draw the found chessboard corners to an image+drawChessboardCorners :: CV.Image.Image RGB D8 -> (Int, Int) -> [(Float,Float)] -> CV.Image.Image RGB D8+drawChessboardCorners image (w,h) corners =+   unsafePerformIO $ +    withCloneValue image $ \clone -> +     withArray (map pt2CvPt corners) $ \(c_corners :: Ptr CvPoint )-> +      withGenImage clone$ \c_image -> do+        r <- {#call wrapDrawChessBoardCorners#} c_image (fromIntegral w) (fromIntegral h)+                                           (castPtr c_corners) (fromIntegral $ length corners) +                                           (found)+        return clone+  where +    len = w*h+    found | (w*h) == length corners = 1+          | otherwise = 0 +    +newtype CvPoint = CvPt (CFloat,CFloat) deriving (Show)+cvPt2Pt (CvPt (a,b)) = (realToFrac a , realToFrac b)+pt2CvPt (a,b) = CvPt (realToFrac a , realToFrac b)++instance Storable CvPoint where+  sizeOf _ = {#sizeof CvPoint #}+  alignment _ = {#alignof CvPoint2D32f #}+  peek p = CvPt <$> ((,) +    <$> {#get CvPoint2D32f->x #} p+    <*> {#get CvPoint2D32f->y #} p)+  poke p (CvPt (hx,hy)) = do+    {#set CvPoint2D32f.x #} p (hx)+    {#set CvPoint2D32f.y #} p (hy)++-- | See opencv function cvCalibrateCamera2. This function takes a list of world-screen coordinate pairs acquired with find-chessboard corners+--   and attempts to find the camera parameters for the system. It returns the fitting error, the camera matrix, list of distortion co-efficients+--   and rotation and translation vectors for each coordinate pair. +calibrateCamera2 ::+     [[((Float, Float, Float), (Float, Float))]]+     -> (Int, Int)+     -> IO (Double, Matrix Float, [[Float]], [[Float]], [[Float]])+calibrateCamera2 views (w,h) = do+    let +        pointCounts :: Matrix Int+        pointCounts  = fromList (1,length views) (map (length) views)+        m = length views+        totalPts = length (concat views)+        objectPoints :: Matrix Float+        objectPoints = fromList (3,totalPts) $ concat [[x,y,z] | ((x,y,z),_) <- concat views]+        imagePoints :: Matrix Float+        imagePoints  = fromList (2,totalPts) $ concat [[x,y]   | (_,(x,y))   <- concat views]+        flags = c'CV_CALIB_FIX_K1+                .|.  c'CV_CALIB_FIX_K1+                .|.  c'CV_CALIB_FIX_K2+                .|.  c'CV_CALIB_FIX_K3+                .|.  c'CV_CALIB_FIX_K4+                .|.  c'CV_CALIB_FIX_K5+                .|.  c'CV_CALIB_FIX_K6+                .|.  c'CV_CALIB_ZERO_TANGENT_DIST++        size = C'CvSize (fromIntegral w) (fromIntegral h)+        cameraMatrix,distCoeffs,rvecs,tvecs :: Matrix Float+        cameraMatrix = emptyMatrix (3,3)+        distCoeffs   = emptyMatrix (1,8)+        rvecs        = emptyMatrix (m,3)+        tvecs        = emptyMatrix (m,3)++    err <- with size $ \c_size ->+     withMatPtr objectPoints $ \c_objectPoints ->+     withMatPtr imagePoints $ \c_imagePoints ->+     withMatPtr pointCounts $ \c_pointCounts ->+     withMatPtr cameraMatrix $ \c_cameraMatrix ->+     withMatPtr distCoeffs $ \c_distCoeffs ->+     withMatPtr rvecs $ \c_rvecs ->+     withMatPtr tvecs $ \c_tvecs ->+      c'wrapCalibrateCamera2 c_objectPoints c_imagePoints c_pointCounts c_size +                             c_cameraMatrix c_distCoeffs c_rvecs c_tvecs flags++    -- print ( objectPoints, imagePoints, pointCounts,cameraMatrix, distCoeffs, rvecs, tvecs )+    return (err, transpose cameraMatrix, toCols distCoeffs, toCols rvecs, toCols tvecs)+
CV/ConnectedComponents.chs view
@@ -44,7 +44,7 @@      {#call blobCount#} i  -- |Remove all connected components that fall outside of given size range from the image.-selectSizedComponents :: Double -> CDouble -> Image GrayScale D8 -> Image GrayScale D8+selectSizedComponents :: Double -> Double -> Image GrayScale D8 -> Image GrayScale D8 selectSizedComponents minSize maxSize image = unsafePerformIO $ do     withGenImage image $ \i ->      creatingImage ({#call sizeFilter#} i (realToFrac minSize) (realToFrac maxSize))
CV/Conversions.hs view
@@ -4,6 +4,7 @@ module CV.Conversions (      -- Arrays of Double      copyCArrayToImage+    ,copy8UCArrayToImage     ,copyImageToCArray      -- Arrays of Float     ,copyFCArrayToImage@@ -14,7 +15,8 @@     -- * Copying     ,copyImageToExistingCArray     -- * Acquiring images from pointers-    ,unsafe8UC3FromPtr+    ,unsafe8UC_RGBFromPtr+    ,unsafe8UC_BGRFromPtr     ,acquireImageSlowF'     ,acquireImageSlow'     ,acquireImageSlow8URGB'@@ -33,10 +35,20 @@ import Foreign.Storable.Complex import System.IO.Unsafe -unsafe8UC3FromPtr :: (Int,Int) -> Ptr Word8 -> IO (Image RGB D8)-unsafe8UC3FromPtr (w,h) ptr = S `fmap`  creatingBareImage (acquireImageSlow8URGB' w h ptr)+unsafe8UC_RGBFromPtr :: (Int,Int) -> Ptr Word8 -> IO (Image RGB D8)+unsafe8UC_RGBFromPtr (w,h) ptr = S `fmap`  creatingBareImage (acquireImageSlow8URGB' w h ptr) +unsafe8UC_BGRFromPtr :: (Int,Int) -> Ptr Word8 -> IO (Image RGB D8)+unsafe8UC_BGRFromPtr (w,h) ptr = S `fmap`  creatingBareImage (acquireImageSlow8UBGR' w h ptr)+ -- |Copy the contents of a CArray into CV.Image type.+copy8UCArrayToImage :: CArray (Int,Int) Word8 -> Image GrayScale D8+copy8UCArrayToImage carr = S $ unsafePerformIO $+                          creatingBareImage (withCArray carr (acquireImageSlow8U' w h))+    where+     ((sx,sy),(ex,ey)) = bounds carr+     (w,h) = (fromIntegral $ ex-sx+1, fromIntegral $ ey-sy+1)+-- |Copy the contents of a CArray into CV.Image type. copyCArrayToImage :: CArray (Int,Int) Double -> Image GrayScale D32 copyCArrayToImage carr = S $ unsafePerformIO $                           creatingBareImage (withCArray carr (acquireImageSlow' w h))@@ -111,6 +123,12 @@  foreign import ccall safe "CV/cvWrapLeo.h acquireImageSlow8URGB"   acquireImageSlow8URGB' :: (Int -> (Int -> ((Ptr Word8) -> (IO (Ptr (BareImage))))))++foreign import ccall safe "CV/cvWrapLeo.h acquireImageSlow8UBGR"+  acquireImageSlow8UBGR' :: (Int -> (Int -> ((Ptr Word8) -> (IO (Ptr (BareImage))))))++foreign import ccall safe "CV/cvWrapLeo.h acquireImageSlow8U"+  acquireImageSlow8U' :: (Int -> (Int -> ((Ptr Word8) -> (IO (Ptr (BareImage))))))  foreign import ccall safe "CV/cvWrapLeo.h acquireImageSlowComplex"   acquireImageSlowComplex' :: (Int -> (Int -> ((Ptr (Complex Double)) -> (IO (Ptr (BareImage))))))
CV/Edges.chs view
@@ -68,7 +68,7 @@ --  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 -> +                           withCloneValue src $ \clone ->                              withGenImage src $ \si ->                              withGenImage clone $ \ci -> do                                {#call cvCanny#} si ci (fromIntegral t1) 
CV/Filters.chs view
@@ -1,9 +1,9 @@-{-#LANGUAGE ForeignFunctionInterface, TypeFamilies#-}+{-#LANGUAGE ForeignFunctionInterface, TypeFamilies, FlexibleInstances#-} #include "cvWrapLEO.h" -- | This module is a collection of various image filters module CV.Filters(gaussian,gaussianOp               ,blurOp,blur,blurNS-              ,median+              ,HasMedianFiltering,median               ,susan,getCentralMoment,getAbsCentralMoment               ,getMoment,secondMomentBinarize,secondMomentBinarizeOp               ,secondMomentAdaptiveBinarize,secondMomentAdaptiveBinarizeOp@@ -115,9 +115,20 @@                         (fromIntegral colorS) (fromIntegral spaceS) 0 0  +-- TODO: The type is not exactly correct++class HasMedianFiltering a where+    median :: (Int,Int) -> a -> a++instance HasMedianFiltering (Image GrayScale D8) where+    median = median'++instance HasMedianFiltering (Image RGB D8) where+    median = median'+ -- | Perform median filtering on an eight bit image.-median :: (Int,Int) -> Image GrayScale D8 -> Image GrayScale D8-median (w,h) img +median' :: (Int,Int) -> Image c D8 -> Image c D8+median' (w,h) img    | maskIsOk (w,h) = unsafePerformIO $ do                     clone2 <- cloneImage img                     withGenImage img $ \c1 -> @@ -162,7 +173,8 @@ --   above and left of it. Such images are used for significantly accelerating the calculation of --   area averages.  newtype IntegralImage = IntegralImage (Image GrayScale D64)-instance IntSized IntegralImage where+instance Sized IntegralImage where+    type Size IntegralImage = (Int,Int)     getSize (IntegralImage i) = getSize i  instance GetPixel IntegralImage where
CV/Histogram.chs view
@@ -142,17 +142,6 @@                          cbins = fromIntegral bins  ---getHistgramHS bins image =  calcHistogram bins $ getAllPixels image-------- Calculate image histogram from _Floating Point_ Image---calcHistogram :: Int -> [CDouble] -> HistogramData Int Double---calcHistogram bins pixels = HGD $ map (\(a,b) -> (realToFrac a, b/l)) $ assocs $ accumArray (+) 0 (0,bins) binned ---                    where---                     l = fromIntegral $ length pixels---                     bin :: CDouble -> (Int,Double)---                     bin d = (floor $ (fromIntegral bins) * d,1.0)---                     binned = map bin pixels--- ---- Low level interaface:  {#pointer *CvHistogram as Histogram foreign newtype#}
CV/Image.chs view
@@ -1,13 +1,102 @@-{-#LANGUAGE ForeignFunctionInterface, ViewPatterns,ParallelListComp, FlexibleInstances, FlexibleContexts, TypeFamilies, EmptyDataDecls #-}+{-#LANGUAGE ForeignFunctionInterface, ViewPatterns,ParallelListComp, FlexibleInstances, FlexibleContexts, TypeFamilies, EmptyDataDecls, ScopedTypeVariables, StandaloneDeriving #-} #include "cvWrapLEO.h"-module CV.Image where+module CV.Image (+-- * Basic types + Image(..) +, create+, empty +, emptyCopy +, emptyCopy' +, cloneImage+, withClone +, withCloneValue +, CreateImage  +-- * Colour spaces+, ChannelOf +, GrayScale+, RGB+, RGBA+, RGB_Channel(..) +, LAB+, LAB_Channel(..) +, D32 +, D64 +, D8 +, Tag +, lab +, rgba +, rgb +, composeMultichannelImage ++-- * IO operations+, Loadable(..) +, saveImage +, loadColorImage +, loadImage ++-- * Pixel level access +, GetPixel(..)+, getAllPixels +, getAllPixelsRowMajor +, setPixel +, setPixel8U +, mapImageInplace ++-- * Image information+, ImageDepth+, Sized(..)+, getArea +, getChannel+, getImageChannels +, getImageDepth +, getImageInfo ++-- * ROI's, COI's and subregions+, setCOI +, setROI +, resetROI +, getRegion +, withIOROI +, withROI ++-- * Blitting+, blendBlit +, blit +, blitM +, subPixelBlit +, safeBlit +, montage +, tileImages ++-- * Conversions+, rgbToGray +, rgbToLab +, unsafeImageTo32F +, unsafeImageTo8Bit ++-- * Low level access operations+, BareImage(..)+, creatingImage +, unImage +, unS +, withGenBareImage +, withBareImage +, creatingBareImage+, withGenImage +, withImage +, ensure32F++) where+ import System.Posix.Files import System.Mem  import Foreign.C.Types import Foreign.C.String-import Foreign.ForeignPtr+import Foreign.Marshal.Utils+import Foreign.ForeignPtr hiding (newForeignPtr)+import Foreign.Concurrent import Foreign.Ptr import Control.Parallel.Strategies import Control.DeepSeq@@ -22,6 +111,7 @@ import Foreign.Storable import System.IO.Unsafe import Data.Word+import Control.Monad   @@ -47,10 +137,10 @@  withImage :: Image c d -> (Ptr BareImage ->IO a) -> IO a withImage (S i) op = withBareImage i op---withGenNewImage (S i) op = withGenImage i op +--withGenNewImage (S i) op = withGenImage i op  -- Ok. this is just the example why I need image types-withUniPtr with x fun = with x $ \y -> +withUniPtr with x fun = with x $ \y ->                     fun (castPtr y)  withGenImage = withUniPtr withImage@@ -58,8 +148,10 @@  {#pointer *IplImage as BareImage foreign newtype#} -foreign import ccall "& wrapReleaseImage" releaseImage :: FinalizerPtr BareImage+freeBareImage ptr = with ptr {#call cvReleaseImage#} +--foreign import ccall "& wrapReleaseImage" releaseImage :: FinalizerPtr BareImage+ instance NFData (Image a b) where     rnf a@(S (BareImage fptr)) = (unsafeForeignPtrToPtr) fptr `seq` a `seq` ()-- This might also need peek? @@ -67,13 +159,13 @@ creatingImage fun = do               iptr <- fun --              {#call incrImageC#} -- Uncomment this line to get statistics of number of images allocated by ghc-              fptr <- newForeignPtr releaseImage iptr+              fptr <- newForeignPtr iptr (freeBareImage iptr)               return . S . BareImage $ fptr  creatingBareImage fun = do               iptr <- fun --              {#call incrImageC#} -- Uncomment this line to get statistics of number of images allocated by ghc-              fptr <- newForeignPtr releaseImage iptr+              fptr <- newForeignPtr iptr (freeBareImage iptr)               return . BareImage $ fptr  unImage (S (BareImage fptr)) = fptr@@ -85,17 +177,17 @@   composeMultichannelImage :: (CreateImage (Image tp a)) => Maybe (Image GrayScale a) -> Maybe (Image GrayScale a) -> Maybe (Image GrayScale a) -> Maybe (Image GrayScale a) -> Tag tp -> Image tp a-composeMultichannelImage (c1) +composeMultichannelImage (c1)                          (c2)                          (c3)                          (c4)                          totag     = unsafePerformIO $ do         res <- create (size) -- TODO: Check channel count -- This is NOT correct-        withMaybe c1 $ \cc1 -> -         withMaybe c2 $ \cc2 -> -          withMaybe c3 $ \cc3 -> -           withMaybe c4 $ \cc4 -> +        withMaybe c1 $ \cc1 ->+         withMaybe c2 $ \cc2 ->+          withMaybe c3 $ \cc3 ->+           withMaybe c4 $ \cc4 ->             withGenImage res $ \cres -> {#call cvMerge#} cc1 cc2 cc3 cc4 cres         return res     where@@ -109,42 +201,79 @@ --              exists <- fileExist n --              if not exists then return Nothing --                            else do---                              i <- withCString n $ \name -> +--                              i <- withCString n $ \name -> --                                     creatingImage ({#call cvLoadImage #} name (0)) --                              bw <- imageTo32F i --                              return $ Just bw -loadImage :: FilePath -> IO (Maybe (Image GrayScale D32))-loadImage n = do+class Loadable a where+    readFromFile :: FilePath -> IO a+++instance Loadable ((Image GrayScale D32)) where+    readFromFile fp = do+        e <- loadImage fp+        case e of+         Just i -> return i+         Nothing -> fail $ "Could not load "++fp++instance Loadable ((Image RGB D32)) where+    readFromFile fp = do+        e <- loadColorImage fp+        case e of+         Just i -> return i+         Nothing -> fail $ "Could not load "++fp++instance Loadable ((Image RGB D8)) where+    readFromFile fp = do+        e <- loadColorImage8 fp+        case e of+         Just i -> return i+         Nothing -> fail $ "Could not load "++fp++instance Loadable ((Image GrayScale D8)) where+    readFromFile fp = do+        e <- loadImage8 fp+        case e of+         Just i -> return i+         Nothing -> fail $ "Could not load "++fp+++-- | This function loads and converts image to an arbitrary format. Notice that it is+--   polymorphic enough to cause run time errors if the declared and actual types of the+--   images do not match. Use with care.+unsafeloadUsing x p n = do               exists <- fileExist n               if not exists then return Nothing                             else do-                              i <- withCString n $ \name -> -                                     creatingBareImage ({#call cvLoadImage #} name (0))-                              bw <- imageTo32F i+                              i <- withCString n $ \name ->+                                     creatingBareImage ({#call cvLoadImage #} name p)+                              bw <- x i                               return . Just . S $ bw +loadImage :: FilePath -> IO (Maybe (Image GrayScale D32))+loadImage = unsafeloadUsing imageTo32F 0+loadImage8 :: FilePath -> IO (Maybe (Image GrayScale D8))+loadImage8 = unsafeloadUsing imageTo8Bit 0 loadColorImage :: FilePath -> IO (Maybe (Image RGB D32))-loadColorImage n = do-              exists <- fileExist n-              if not exists then return Nothing-                            else do-                              i <- withCString n $ \name -> -                                     creatingBareImage ({#call cvLoadImage #} name 1)-                              bw <- imageTo32F i-                              return . Just . S  $ bw+loadColorImage = unsafeloadUsing imageTo32F 1+loadColorImage8 :: FilePath -> IO (Maybe (Image RGB D8))+loadColorImage8 = unsafeloadUsing imageTo8Bit 1 -class IntSized a where-    getSize :: a -> (Int,Int)+class Sized a where+    type Size a :: *+    getSize :: a -> Size a -instance IntSized BareImage where+instance Sized BareImage where+    type Size BareImage = (Int,Int)    -- getSize :: (Integral a, Integral b) => Image c d -> (a,b)     getSize image = unsafePerformIO $ withBareImage image $ \i -> do                  w <- {#call getImageWidth#} i                  h <- {#call getImageHeight#} i                  return (fromIntegral w,fromIntegral h) -instance IntSized (Image c d) where+instance Sized (Image c d) where+    type Size (Image c d) = (Int,Int)     getSize = getSize . unS  @@ -161,41 +290,83 @@  class GetPixel a where     type P a :: *-    getPixel   :: (Integral i) => (i,i) -> a -> P a+    getPixel   :: (Int,Int) -> a -> P a +-- #define FGET(img,x,y) (((float *)((img)->imageData + (y)*(img)->widthStep))[(x)]) instance GetPixel (Image GrayScale D32) where-    type P (Image GrayScale D32) = D32 -    getPixel (fromIntegral -> x, fromIntegral -> y) image = realToFrac $ unsafePerformIO $-             withGenImage image $ \img -> {#call wrapGet32F2D#} img y x+    type P (Image GrayScale D32) = D32+    {-#INLINE getPixel#-}+    getPixel (x,y) i = unsafePerformIO $+                        withGenImage i $ \c_i -> do+                                         d <- {#get IplImage->imageData#} c_i+                                         s <- {#get IplImage->widthStep#} c_i+                                         peek (castPtr (d`plusPtr` (y*(fromIntegral s) +x*sizeOf (0::Float))):: Ptr Float) -instance  GetPixel (Image RGB D32) where-    type P (Image RGB D32) = (D32,D32,D32) -    getPixel (fromIntegral -> x, fromIntegral -> y) image -        = unsafePerformIO $ do +{-#INLINE getPixelOld#-}+getPixelOld (fromIntegral -> x, fromIntegral -> y) image = realToFrac $ unsafePerformIO $+         withGenImage image $ \img -> {#call wrapGet32F2D#} img y x++-- #define UGETC(img,color,x,y) (((uint8_t *)((img)->imageData + (y)*(img)->widthStep))[(x)*3+(color)])+instance GetPixel (Image RGB D32) where+    type P (Image RGB D32) = (D32,D32,D32)+    {-#INLINE getPixel#-}+    getPixel (x,y) i = unsafePerformIO $+                        withGenImage i $ \c_i -> do+                                         d <- {#get IplImage->imageData#} c_i+                                         s <- {#get IplImage->widthStep#} c_i+                                         let cs = fromIntegral s+                                             fs = sizeOf (undefined :: Float)+                                         r <- peek (castPtr (d`plusPtr` (y*cs +x*3*fs)))+                                         g <- peek (castPtr (d`plusPtr` (y*cs +(x*3+1)*fs)))+                                         b <- peek (castPtr (d`plusPtr` (y*cs +(x*3+2)*fs)))+                                         return (r,g,b)++getPixelOldRGB (fromIntegral -> x, fromIntegral -> y) image+        = unsafePerformIO $ do                      withGenImage image $ \img -> do                               r <- {#call wrapGet32F2DC#} img y x 0                               g <- {#call wrapGet32F2DC#} img y x 1                               b <- {#call wrapGet32F2DC#} img y x 2                               return (realToFrac r,realToFrac g, realToFrac b) +-- | Perform (a destructive) inplace map of the image. This should be wrapped inside+-- withClone or an image operation+mapImageInplace :: (P (Image GrayScale D32) -> P (Image GrayScale D32))+            -> Image GrayScale D32+            -> IO ()+mapImageInplace f image = withGenImage image $ \c_i -> do+             d <- {#get IplImage->imageData#} c_i+             s <- {#get IplImage->widthStep#} c_i+             let (w,h) = getSize image+                 cs = fromIntegral s+                 fs = sizeOf (undefined :: Float)+             forM_ [(x,y) | x<-[0..w-1], y <- [0..h-1]] $ \(x,y) -> do+                   v <- peek (castPtr (d `plusPtr` (y*cs+x*fs)))+                   poke (castPtr (d `plusPtr` (y*cs+x*fs))) (f v)++ instance  GetPixel (Image RGB D8) where-    type P (Image RGB D8) = (D8,D8,D8) -    getPixel (fromIntegral -> x, fromIntegral -> y) image -        = unsafePerformIO $ do -                     withGenImage image $ \img -> do-                              r <- {#call wrapGet8U2DC#} img y x 0-                              g <- {#call wrapGet8U2DC#} img y x 1-                              b <- {#call wrapGet8U2DC#} img y x 2-                              return (fromIntegral r,fromIntegral g, fromIntegral b)+    type P (Image RGB D8) = (D8,D8,D8)+    {-#INLINE getPixel#-}+    getPixel (x,y) i = unsafePerformIO $+                        withGenImage i $ \c_i -> do+                                         d <- {#get IplImage->imageData#} c_i+                                         s <- {#get IplImage->widthStep#} c_i+                                         let cs = fromIntegral s+                                             fs = sizeOf (undefined :: D8)+                                         r <- peek (castPtr (d`plusPtr` (y*cs +x*3*fs)))+                                         g <- peek (castPtr (d`plusPtr` (y*cs +(x*3+1)*fs)))+                                         b <- peek (castPtr (d`plusPtr` (y*cs +(x*3+2)*fs)))+                                         return (r,g,b)   convertTo :: CInt -> CInt -> BareImage -> BareImage convertTo code channels img = unsafePerformIO $ creatingBareImage $ do     res <- {#call wrapCreateImage32F#} w h channels-    withBareImage img $ \cimg -> +    withBareImage img $ \cimg ->         {#call cvCvtColor#} (castPtr cimg) (castPtr res) code     return res- where    + where     (fromIntegral -> w,fromIntegral -> h) = getSize img  class CreateImage a where@@ -232,38 +403,38 @@   empty :: (CreateImage (Image a b)) => (Int,Int) -> (Image a b)-empty size = unsafePerformIO $ create size +empty size = unsafePerformIO $ create size  emptyCopy :: (CreateImage (Image a b)) => Image a b -> IO (Image a b)-emptyCopy img = create (getSize img) +emptyCopy img = create (getSize img)  emptyCopy' :: (CreateImage (Image a b)) => Image a b -> (Image a b)-emptyCopy' img = unsafePerformIO $ create (getSize img) +emptyCopy' img = unsafePerformIO $ create (getSize img)  -- | Save image. This will convert the image to 8 bit one before saving saveImage :: FilePath -> Image c d -> IO () saveImage filename image = do                            fpi <- imageTo8Bit $ unS image-                           withCString  filename $ \name  -> +                           withCString  filename $ \name  ->                             withGenBareImage fpi    $ \cvArr -> 							 alloca (\defs -> poke defs 0 >> {#call cvSaveImage #} name cvArr defs >> return ())  -getArea :: (IntSized a) => a -> Int+getArea :: (Sized a,Num b, Size a ~ (b,b)) => a -> b getArea = uncurry (*).getSize  getRegion :: (Int,Int) -> (Int,Int) -> Image c d -> Image c d-getRegion (fromIntegral -> x,fromIntegral -> y) (fromIntegral -> w,fromIntegral -> h) image +getRegion (fromIntegral -> x,fromIntegral -> y) (fromIntegral -> w,fromIntegral -> h) image     | x+w <= width && y+h <= height = S . getRegion' (x,y) (w,h) $ unS image     | otherwise                   = error $ "Region outside image:"                                             ++ show (getSize image) ++                                             "/"++show (x+w,y+h)  where   (fromIntegral -> width,fromIntegral -> height) = getSize image-    + getRegion' (x,y) (w,h) image = unsafePerformIO $                                withBareImage image $ \i ->-                                 creatingBareImage ({#call getSubImage#} +                                 creatingBareImage ({#call getSubImage#}                                                 i x y w h)  @@ -271,16 +442,16 @@ tileImages image1 image2 (x,y) = unsafePerformIO $                                withImage image1 $ \i1 ->                                 withImage image2 $ \i2 ->-                                 creatingImage ({#call simpleMergeImages#} +                                 creatingImage ({#call simpleMergeImages#}                                                 i1 i2 x y)--- | Blit image2 onto image1. +-- | Blit image2 onto image1. blitFix = blit-blit image1 image2 (x,y) -    | badSizes  = error $ "Bad blit sizes: " ++ show [(w1,h1),(w2,h2)]++"<-"++show (x,y) +blit image1 image2 (x,y)+    | badSizes  = error $ "Bad blit sizes: " ++ show [(w1,h1),(w2,h2)]++"<-"++show (x,y)     | otherwise = withImage image1 $ \i1 ->                    withImage image2 $ \i2 ->                     ({#call plainBlit#} i1 i2 (fromIntegral y) (fromIntegral x))-    where +    where      ((w1,h1),(w2,h2)) = (getSize image1,getSize image2)      badSizes = x+w2>w1 || y+h2>h1 || x<0 || y<0 @@ -288,8 +459,8 @@ blitM (rw,rh) imgs = resultPic     where      resultPic = unsafePerformIO $ do-                    r <- create (fromIntegral rw,fromIntegral rh) -                    sequence_ [blit r i (fromIntegral x, fromIntegral y) +                    r <- create (fromIntegral rw,fromIntegral rh)+                    sequence_ [blit r i (fromIntegral x, fromIntegral y)                               | ((x,y),i) <- imgs ]                     return r @@ -297,12 +468,12 @@ subPixelBlit   :: Image c d -> Image c d -> (CDouble, CDouble) -> IO () -subPixelBlit (image1) (image2) (x,y) -    | badSizes  = error $ "Bad blit sizes: " ++ show [(w1,h1),(w2,h2)]++"<-"++show (x,y) +subPixelBlit (image1) (image2) (x,y)+    | badSizes  = error $ "Bad blit sizes: " ++ show [(w1,h1),(w2,h2)]++"<-"++show (x,y)     | otherwise = withImage image1 $ \i1 ->                    withImage image2 $ \i2 ->                     ({#call subpixel_blit#} i1 i2 y x)-    where +    where      ((w1,h1),(w2,h2)) = (getSize image1,getSize image2)      badSizes = ceiling x+w2>w1 || ceiling y+h2>h1 || x<0 || y<0 @@ -311,10 +482,10 @@                   blit res i2 (x,y)                   return res --- | Blit image2 onto image1. ---   This uses an alpha channel bitmap for determining the regions where the image should be "blended" with +-- | Blit image2 onto image1.+--   This uses an alpha channel bitmap for determining the regions where the image should be "blended" with --   the base image.-blendBlit image1 image1Alpha image2 image2Alpha (x,y) = +blendBlit image1 image1Alpha image2 image2Alpha (x,y) =                                withImage image1 $ \i1 ->                                 withImage image1Alpha $ \i1a ->                                  withImage image2Alpha $ \i2a ->@@ -322,61 +493,81 @@                                    ({#call alphaBlit#} i1 i1a i2 i2a x y)  -cloneImage img = withGenImage img $ \image ->  +cloneImage img = withGenImage img $ \image ->                     creatingImage ({#call cvCloneImage #} image) -withClone img fun = do +withClone+  :: Image channels depth+     -> (Image channels depth -> IO ())+     -> IO (Image channels depth)+withClone img fun = do                 result <- cloneImage img                 fun result                 return result -withCloneValue img fun = do +withCloneValue+  :: Image channels depth+     -> (Image channels depth -> IO a)+     -> IO a+withCloneValue img fun = do                 result <- cloneImage img                 r <- fun result                 return r -unsafeImageTo32F img = unsafePerformIO $ withGenImage img $ \image -> -                creatingImage +unsafeImageTo32F :: Image c d -> Image c D32+unsafeImageTo32F img = unsafePerformIO $ withGenImage img $ \image ->+                creatingImage                  ({#call ensure32F #} image)  unsafeImageTo8Bit :: Image cspace a -> Image cspace D8-unsafeImageTo8Bit img = unsafePerformIO $ withGenImage img $ \image -> -                creatingImage +unsafeImageTo8Bit img = unsafePerformIO $ withGenImage img $ \image ->+                creatingImage                  ({#call ensure8U #} image) -imageTo32F img = withGenBareImage img $ \image -> -                creatingBareImage +imageTo32F img = withGenBareImage img $ \image ->+                creatingBareImage                  ({#call ensure32F #} image) -imageTo8Bit img = withGenBareImage img $ \image -> -                creatingBareImage +imageTo8Bit img = withGenBareImage img $ \image ->+                creatingBareImage                  ({#call ensure8U #} image) #c enum ImageDepth {      Depth32F = IPL_DEPTH_32F,      Depth64F = IPL_DEPTH_64F,-     Depth8U  = IPL_DEPTH_8U, -     Depth8S  = IPL_DEPTH_8S, -     Depth16U  = IPL_DEPTH_16U, +     Depth8U  = IPL_DEPTH_8U,+     Depth8S  = IPL_DEPTH_8S,+     Depth16U  = IPL_DEPTH_16U,      Depth16S  = IPL_DEPTH_16S,      Depth32S  = IPL_DEPTH_32S      }; #endc- + {#enum ImageDepth {}#} -getImageDepth i = withImage i $ \c_img -> {#get IplImage->depth #} c_img+deriving instance Show ImageDepth +getImageDepth :: Image c d -> IO ImageDepth+getImageDepth i = withImage i $ \c_img -> {#get IplImage->depth #} c_img >>= return.toEnum.fromIntegral+getImageChannels i = withImage i $ \c_img -> {#get IplImage->nChannels #} c_img++getImageInfo x = do+    let s = getSize x+    d <- getImageDepth x+    c <- getImageChannels x+    return (s,d,c)++ -- Manipulating regions of interest:-setROI (fromIntegral -> x,fromIntegral -> y) -       (fromIntegral -> w,fromIntegral -> h) -       image = withImage image $ \i -> +setROI (fromIntegral -> x,fromIntegral -> y)+       (fromIntegral -> w,fromIntegral -> h)+       image = withImage image $ \i ->                             {#call wrapSetImageROI#} i x y w h  resetROI image = withImage image $ \i ->                   {#call cvResetImageROI#} i -setCOI chnl image = withImage image $ \i -> +setCOI chnl image = withImage image $ \i ->                             {#call cvSetImageCOI#} i (fromIntegral chnl) resetCOI image = withImage image $ \i ->                   {#call cvSetImageCOI#} i 0@@ -406,43 +597,63 @@                         resetROI image                         return x --- Manipulating image pixels++-- | Manipulate image pixels. This is slow, ugly and should be avoided --setPixel :: (CInt,CInt) -> CDouble -> Image c d -> IO ()-setPixel :: (Int,Int) -> D32 -> Image GrayScale D32 -> IO ()-setPixel (x,y) v image = withGenImage image $ \img ->+{-#INLINE setPixelOld#-}+setPixelOld :: (Int,Int) -> D32 -> Image GrayScale D32 -> IO ()+setPixelOld (x,y) v image = withGenImage image $ \img ->                           {#call wrapSet32F2D#} img (fromIntegral y) (fromIntegral x) (realToFrac v) +{-#INLINE setPixel#-}+setPixel :: (Int,Int) -> D32 -> Image GrayScale D32 -> IO ()+setPixel (x,y) v image = withGenImage image $ \c_i -> do+                                         d <- {#get IplImage->imageData#} c_i+                                         s <- {#get IplImage->widthStep#} c_i+                                         poke (castPtr (d`plusPtr` (y*(fromIntegral s)+                                              + x*sizeOf (0::Float))):: Ptr Float)+                                              v -getAllPixels image =  [getPixel (i,j) image +{-#INLINE setPixel8U#-}+setPixel8U :: (Int,Int) -> Word8 -> Image GrayScale D8 -> IO ()+setPixel8U (x,y) v image = withGenImage image $ \c_i -> do+                                         d <- {#get IplImage->imageData#} c_i+                                         s <- {#get IplImage->widthStep#} c_i+                                         poke (castPtr (d`plusPtr` (y*(fromIntegral s)+                                              + x*sizeOf (0::Word8))):: Ptr Word8)+                                              v+++getAllPixels image =  [getPixel (i,j) image                       | i <- [0..width-1 ]-                      , j <- [0..height-1]]                          +                      , j <- [0..height-1]]                     where                      (width,height) = getSize image -getAllPixelsRowMajor image =  [getPixel (i,j) image +getAllPixelsRowMajor image =  [getPixel (i,j) image                               | j <- [0..height-1]                               , i <- [0..width-1]-                              ]                          +                              ]                     where                      (width,height) = getSize image  -- |Create a montage form given images (u,v) determines the layout and space the spacing --  between images. Images are assumed to be the same size (determined by the first image) montage :: (CreateImage (Image c d)) => (Int,Int) -> Int -> [Image c d] -> Image c d-montage (u',v') space' imgs +montage (u',v') space' imgs     | u'*v' /= (length imgs) = error ("Montage mismatch: "++show (u,v, length imgs))     | otherwise              = resultPic     where      space = fromIntegral space'      (u,v) = (fromIntegral u', fromIntegral v')-     (rw,rh) = (u*xstep,v*ystep) +     (rw,rh) = (u*xstep,v*ystep)      (w,h) = getSize (head imgs)      (xstep,ystep) = (fromIntegral space + w,fromIntegral space + h)      edge = space`div`2      resultPic = unsafePerformIO $ do                     r <- create (rw,rh)-                    sequence_ [blit r i (edge +  x*xstep, edge + y*ystep) -                               | y <- [0..v-1] , x <- [0..u-1] +                    sequence_ [blit r i (edge +  x*xstep, edge + y*ystep)+                               | y <- [0..v-1] , x <- [0..u-1]                                | i <- imgs ]                     return r 
CV/ImageMath.chs view
@@ -21,15 +21,21 @@ mkBinaryImageOpIO f = \a -> \b ->            withGenImage a $ \ia ->            withGenImage b $ \ib ->-          withClone a    $ \clone ->+          withCloneValue a    $ \clone ->           withGenImage clone $ \cl -> do             f ia ib cl              return clone  +mkBinaryImageOp+  :: (Ptr () -> Ptr () -> Ptr () -> IO a)+     -> CV.Image.Image c1 d1+     -> CV.Image.Image c1 d1+     -> CV.Image.Image c1 d1+ mkBinaryImageOp f = \a -> \b -> unsafePerformIO $           withGenImage a $ \ia ->            withGenImage b $ \ib ->-          withClone a    $ \clone ->+          withCloneValue a    $ \clone ->           withGenImage clone $ \cl -> do             f ia ib cl              return clone@@ -76,6 +82,7 @@  absDiff = mkBinaryImageOp {#call cvAbsDiff#} +atan :: Image GrayScale D32 -> Image GrayScale D32 atan i = unsafePerformIO $ do                     let (w,h) = getSize i                     res <- create (w,h) @@ -209,7 +216,7 @@  -- | Sum the pixels in the image. Notice that OpenCV automatically casts the --   result to double sum :: Image GrayScale D32 -> D32-sum :: Image GrayScale a -> Double+sum :: Image GrayScale D32 -> D32 sum img = realToFrac $ unsafePerformIO $ withGenImage img $ \image ->                     {#call wrapSum#} image 
CV/ImageOp.hs view
@@ -48,8 +48,8 @@ img <## op = unsafeOperate (foldl1 (#>) op) img  --- runImageOperation :: Image c d -> ImageOperation c d -> IO (Image c d)-operate (ImgOp op) img = withClone img $ \clone -> +operate ::ImageOperation c d -> Image c d -> IO (Image c d)+operate (ImgOp op) img = withCloneValue img $ \clone ->                                      op clone >> return clone  operateOn = flip operate
+ CV/Matrix.hs view
@@ -0,0 +1,207 @@+{-#LANGUAGE ParallelListComp, TypeFamilies, FlexibleInstances, FlexibleContexts, ScopedTypeVariables#-}+-- | This module provides wrappers for CvMat type. This is still preliminary as the type of the+--   matrix isn't coded in the haskell type.+module CV.Matrix +    (+    Exists,Exists(..),+    Matrix, emptyMatrix ,fromList,toList,toRows,toCols,get,put,withMatPtr+    , transpose, mxm, rodrigues2+    )where++{-#OPTIONS_GHC -fwarn-unused-imports#-}++import System.Posix.Files+import System.Mem++import Foreign.C.Types+import Foreign.C.String+import Foreign.Marshal.Utils+import Foreign.ForeignPtr hiding (newForeignPtr)+import Foreign.Concurrent +import Foreign.Ptr+import Control.Parallel.Strategies+import Control.DeepSeq++-- import C2HSTools++import Data.Maybe(catMaybes)+import Data.List(genericLength)+import Foreign.Marshal.Array+import Foreign.Marshal.Alloc+import Foreign.Ptr+import Foreign.Storable+import System.IO.Unsafe+import Data.Word+import Control.Monad++import CV.Bindings.Matrix+import CV.Image hiding (create)++-- #define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size )  \+--    (assert( (unsigned)(row) < (unsigned)(mat).rows &&   \+--             (unsigned)(col) < (unsigned)(mat).cols ),   \+--     (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))++-- | Haskell reflection of CvMat type+newtype Matrix a = Matrix (ForeignPtr C'CvMat)++instance (Show t, Storable t, (Size (Matrix t))~(Int,Int)) => Show (Matrix t) where+    show m = "fromList "++show (getSize m)++" "++show (toList m)++matrixFinalizer ptr = with ptr c'cvReleaseMat++class Exists a where+    type Args a :: *+    create :: Args a -> a++instance Exists (Matrix Float) where+    type Args (Matrix Float) = (Int,Int)+    create (r,c) = unsafePerformIO $ creatingMat (c'cvCreateMat r c c'CV_32FC1) ++instance Exists (Matrix Int) where+    type Args (Matrix Int) = (Int,Int)+    create (r,c) = unsafePerformIO $ creatingMat (c'cvCreateMat r c c'CV_32SC1) ++instance Exists (Matrix Double) where+    type Args (Matrix Double) = (Int,Int)+    create (r,c) = unsafePerformIO $ creatingMat (c'cvCreateMat r c c'CV_64FC1) ++instance Sized (Matrix a) where+    type Size (Matrix a) = (Int,Int)+    getSize (Matrix e) = unsafePerformIO $ withForeignPtr e $ \mat -> do+                         mat' <- peek mat+                         return (fromIntegral $ c'CvMat'rows mat', +                                fromIntegral $ c'CvMat'cols mat')++-- | Create an empty matrix of given dimensions+emptyMatrix :: Exists (Matrix a) => Args (Matrix a) -> Matrix a+emptyMatrix a = create a++identity :: (Num a, Sized (Matrix a), Args (Matrix a) ~ (Int,Int),  Size (Matrix a) ~ (Int,Int),  Storable a, Exists (Matrix a)) => +             (Matrix a) -> Matrix a+identity a = unsafePerformIO $ do+             let res = create (getSize a) +                 (rows,cols) = getSize a+             sequence_ [put res row col 1 +                       | row <- [0..rows-1]+                       | col <- [0..cols-1]]+             return res++-- | Transpose a matrix. Does not do complex conjugation for complex matrices  +transpose :: (Exists (Matrix a), Args (Matrix a) ~ Size (Matrix a)) => Matrix a -> Matrix a+transpose m@(Matrix f_m) = unsafePerformIO $ do+                 let res@(Matrix f_c) = create (getSize m)+                 withForeignPtr f_m $ \c_m ->+                  withForeignPtr f_c $ c'cvTranspose c_m +                 return res++-- | Convert a rotation vector to a rotation matrix (1x3 -> 3x3)+rodrigues2 :: (Exists (Matrix a), Args (Matrix a) ~ Size (Matrix a)) => Matrix a -> Matrix a+rodrigues2 m@(Matrix f_m) = unsafePerformIO $ do+                 let res@(Matrix f_c) = create (3,3)+                 withForeignPtr f_m $ \c_m ->+                  withForeignPtr f_c $ \c_c -> c'cvRodrigues2 c_m c_c nullPtr+                 return res+++-- | Ordinary matrix multiplication+mxm :: (Exists (Matrix a), Args (Matrix a) ~ Size (Matrix a)) => Matrix a -> Matrix a -> Matrix a+mxm m1@(Matrix a_m) m2@(Matrix b_m) = unsafePerformIO $ do+                 let (w1,h1) = getSize m1+                     (w2,h2) = getSize m2+                     res@(Matrix f_c) = create (w1,h2)+                 when (h1 /= w2) . error  $ +                    "Matrix dimensions do not match for multiplication: "+                    ++show (w1,h1)+                    ++" vs. "+                    ++ show (w2,h2)+                 withForeignPtr a_m $ \c_a ->+                  withForeignPtr b_m $ \c_b ->+                  withForeignPtr f_c $ \c_res -> c'cvGEMM c_a c_b 1 nullPtr 1 c_res 0+                 return res++withMatPtr :: Matrix x -> (Ptr C'CvMat -> IO a) -> IO a+withMatPtr (Matrix m) op = withForeignPtr m op ++-- | Convert a list of floats into Matrix+fromList :: forall t . (Storable t, Exists (Matrix t), Args (Matrix t) ~ (Int,Int)) +                        => (Int,Int) -> [t] -> Matrix t+fromList (w,h) lst = unsafePerformIO $ do+                let m@(Matrix e) = emptyMatrix (w,h)+                withForeignPtr e $ \mat -> do+                         mat' <- peek mat+                         let d :: Ptr t+                             d = castPtr $ c'CvMat'data'ptr mat'+                             s = c'CvMat'step mat'+                         sequence_ [putRaw d s row col v +                                   | (row,col) <- [(r,c) | c <- [0..h-1], r <- [0..w-1]]+                                   | v <- lst ]+                return $ m+++-- | Convert a matrix to flat list (row major order)+toList :: (Storable a) => Matrix a -> [a] +toList =  concat . toRows++-- | Convert matrix to rows represented as nested lists+toRows :: forall t . (Storable t) => Matrix t -> [[t]] +toRows (Matrix e) = unsafePerformIO $ do+                withForeignPtr e $ \mat -> do+                         mat' <- peek mat+                         let d = castPtr (c'CvMat'data'ptr mat') :: Ptr t+                             s = c'CvMat'step mat'+                             rows = fromIntegral $ c'CvMat'rows mat'+                             cols = fromIntegral $ c'CvMat'cols mat'+                         sequence [sequence [getRaw d (fromIntegral s) row col | row <- [0..rows-1]]+                                   | col <- [0..cols-1]+                                   ]++-- | Convert matrix to cols represented as nested lists+toCols :: forall t . (Storable t) => Matrix t -> [[t]] +toCols (Matrix e) = unsafePerformIO $ do+                withForeignPtr e $ \mat -> do+                         mat' <- peek mat+                         let d = castPtr (c'CvMat'data'ptr mat') :: Ptr t+                             s = c'CvMat'step mat'+                             rows = fromIntegral $ c'CvMat'rows mat'+                             cols = fromIntegral $ c'CvMat'cols mat'+                         sequence [sequence [getRaw d (fromIntegral s) row col | col <- [0..cols-1]]+                                   | row <- [0..rows-1]+                                   ]++creatingMat fun = do+              iptr <- fun+              fptr <- newForeignPtr iptr (matrixFinalizer iptr)+              return . Matrix $ fptr++{-#INLINE get#-}+-- | Get an element of the matrix+get :: forall t . (Storable t) => (Matrix t) -> Int -> Int -> IO t+get (Matrix m) row col = withForeignPtr m $ \mat -> do+         mat' <- peek mat+         let d = c'CvMat'data'ptr mat'+         let s = c'CvMat'step mat'+         getRaw (castPtr d:: Ptr t) (fromIntegral s) (fromIntegral row) (fromIntegral col)++{-#INLINE getRaw#-}+getRaw :: forall t . (Storable t) => Ptr t -> Int -> Int -> Int -> IO t+getRaw d s col row = +         peek (castPtr (d `plusPtr` (col*s+row*sizeOf (undefined::t))):: Ptr t)++{-#INLINE put#-}+-- | Write an element to a matrix+put :: forall t . (Storable t) => (Matrix t) -> Int -> Int -> t -> IO ()+put (Matrix m) row col v = withForeignPtr m $ \mat -> do+         mat' <- peek mat+         let +            d :: Ptr t+            d = castPtr $ c'CvMat'data'ptr mat'+            s = c'CvMat'step mat'+         putRaw d s row col v++{-#INLINE putRaw#-}+putRaw :: forall t. (Storable t) => Ptr t -> CInt -> Int -> Int -> t -> IO ()+putRaw d s col row v = +         poke (castPtr (d `plusPtr` (col*(fromIntegral s)+row*sizeOf (undefined::t))):: Ptr t)+              v+
CV/Morphology.chs view
@@ -1,4 +1,4 @@-{-#LANGUAGE ForeignFunctionInterface, ScopedTypeVariables, UnicodeSyntax#-}+{-#LANGUAGE ForeignFunctionInterface, ScopedTypeVariables, UnicodeSyntax, ViewPatterns#-} #include "cvWrapLEO.h" module CV.Morphology (StructuringElement                   ,structuringElement@@ -122,13 +122,13 @@     ,`Int'} -> `()' #}  -erodeOp se count = ImgOp $ \(S img)  -> erosion img img se count-dilateOp se count = ImgOp $ \(S img) -> dilation img img se count+erodeOp se count = ImgOp $ \(unS -> img)  -> erosion img img se count+dilateOp se count = ImgOp $ \(unS -> img) -> dilation img img se count  erode se count  i = unsafeOperate (erodeOp se count)  i dilate se count i = unsafeOperate (dilateOp se count) i -a ⊕ b = erode b 1 a+a ⊕ b = dilate b 1 a a ⊖ b = erode b 1 a                         erode' se count img = withImage img $ \image ->
CV/MultiresolutionSpline.hs view
@@ -1,3 +1,5 @@+-- | This module provides the elementary image splining (seamless merging) using the burt-adelson multiresolution splines+-- introduced in "A multiresolution spline with application to image mosaics", Burt, P.J. and Adelson, E.H., ACM Transactions on Graphics,1983. module CV.MultiresolutionSpline where  import CV.Image@@ -7,14 +9,13 @@ import CV.Filters  --- stitchHalfAndHalf i1 i2 = montage (2,1) 0 [getRegion (0,0) (hw,dh) i1,getRegion (hw,0) (hw,dh) i2]---     where---      dh = h---      (w,h) = getSize i1---      (hw,hh) = (w`div`2,h`div`2) --- | Do a burt-adelson multiresolution splining for two images.---   Notice, that the mask should contain a tiny blurred region between images +-- | This function merges two images based on given mask, the first image dominates on areas where the mask+--   is 1 and the second where the mask is 0. The merging should be relatively seamless and is controlled by+--   the `levels` parameter, which adjusts the accuracy. Usually, decent results can be obtained with 4 pyramid +--   levels.+--   +--   Note that the mask should contain a tiny blurred region between images for optimal result. burtAdelsonMerge :: Int -> Image GrayScale D8 -> Image GrayScale D32 -> Image GrayScale D32                          -> Image GrayScale D32 burtAdelsonMerge levels mask img1 img2 
+ CV/Pixelwise.hs view
@@ -0,0 +1,63 @@+-- | This module is an applicative wrapper for images. It introduces Pixelwise type that+--   can be converted from and to grayscale images and which has an applicative and functor+--   instances.+{-#LANGUAGE TypeFamilies#-}+module CV.Pixelwise (Pixelwise(..), fromImage, toImage, remap, (<$$>),(<+>)) where+import Control.Applicative +import CV.Image+import System.IO.Unsafe+import Control.Parallel.Strategies++-- | A wrapper for allowing functor and applicative instances for non-polymorphic image types.+data Pixelwise x = MkP {sizeOf :: (Int,Int)+                       ,eltOf :: (Int,Int) -> x}++instance GetPixel (Pixelwise x) where+    type P (Pixelwise x) = x+    getPixel p (MkP s e) = e p++instance Sized (Pixelwise a) where+    type Size (Pixelwise a) = (Int,Int)+    getSize (MkP s _) = s ++instance Functor Pixelwise where+    fmap f (MkP s e) = MkP s (fmap f e)++instance Applicative Pixelwise where+  pure x               = MkP maxBound  (pure x)+  MkP i f <*> MkP j g  = MkP (min i j) (f <*> g)++-- | Re-arrange pixel positions and values+remap :: (((Int,Int) -> b) -> ((Int,Int) -> x)) -> Pixelwise b -> Pixelwise x+remap f (MkP s e) = MkP s (f e)++-- | Convert a pixelwise construct into an image.+fromImage :: (GetPixel b, Sized b, Size b ~ Size (Pixelwise (P b))) => b -> Pixelwise (P b)+fromImage i = MkP (getSize i) (flip getPixel $ i)++-- | Convert an image to pixelwise construct.+toImage :: Pixelwise D32 -> Image GrayScale D32+toImage (MkP (w,h) e) = unsafePerformIO $ do+        img <- create (w,h)+        sequence_ [setPixel (i,j) (e (i,j)) img+                  | i <- [0..w-1]+                  , j <- [0..h-1]+                  ]+        return img++toImageP :: Pixelwise D32 -> Image GrayScale D32+toImageP (MkP (w,h) e) = unsafePerformIO $ do+        img <- create (w,h)+        let rs = parMap rdeepseq (\j -> unsafePerformIO (+                                          sequence_ [setPixel (i,j) (e (i,j)) img | i <- [0..w-1]]+                                          >> return True))+                                 [0..h-1]+        all (==True) rs `seq` return img++-- | Shorthand for `a <$> fromImage b`+(<$$>) :: (Size b1 ~ (Int, Int), Sized b1, GetPixel b1) => (P b1 -> b) -> b1 -> Pixelwise b+a <$$> b = a <$> fromImage b++-- | Shorthand for `a <*> fromImage b`+(<+>) :: (Size b1 ~ (Int, Int), Sized b1, GetPixel b1) => Pixelwise (P b1 -> b) -> b1 -> Pixelwise b+a <+> b = a <*> fromImage b
CV/Textures.chs view
@@ -1,6 +1,9 @@-{-#LANGUAGE ForeignFunctionInterface#-}+{-#LANGUAGE ForeignFunctionInterface, ParallelListComp#-} #include "cvWrapLEO.h"-module CV.Textures where+-- |This module provides implementations for basic versions of Local Binary Pattern texture features introduced in+-- T. Ojala, M. Pietikäinen, and D. Harwood (1994), "Performance evaluation of texture measures with classification+--  based on Kullback discrimination of distributions", Proceedings of the 12th IAPR International Conference on Pattern Recognition (ICPR 1994).+module CV.Textures (rotationInvariant,lbp,lbp5,weightedLBP) where  import Foreign.C.Types import Foreign.C.String@@ -11,36 +14,81 @@ import CV.Image  import CV.ImageOp +import Data.List import C2HSTools+import qualified Data.Vector as V+import Data.Vector (Vector)+import Data.Maybe (fromMaybe) {#import CV.Image#}  --- | Various simple Local Binary Pattern operators+-- * Rotation invariance -lbp = broilerPlate ({#call localBinaryPattern#})+-- |Normalize Word8 according to lbp-logic.+normalize :: Word8 -> Word8+normalize x = minimum [rotateL x i | i<-[0..8] ] -lbp3 = broilerPlate ({#call localBinaryPattern3#})-lbp5 = broilerPlate ({#call localBinaryPattern5#})-lbpHorizontal = broilerPlate +-- |Make an lbp table element rotation invariant+rotationInvariantE :: Word8 -> Word8 +rotationInvariantE a =  fromIntegral+                      . fromMaybe (error "Unthinkable happened(RI)") +                      . V.findIndex (==normalize a) $ keywords+keywords = V.fromList . nub . sort . map normalize $ allWords+allWords = [minBound .. maxBound]++-- | Convert an LBP histogram into rotation invariant form+rotationInvariant :: [Double] -> Vector Double+rotationInvariant es = V.accum (+) (V.replicate 36 0) +                         [(fromIntegral . rotationInvariantE $ i, e) +                         | i <- [minBound .. maxBound]+                         | e <- es]+            ++-- * Various simple Local Binary Pattern operators++-- | The most basic 3x3 lbp operator+lbp :: Image GrayScale D32 -> [Double] +lbp   = broilerPlate256 ({#call localBinaryPattern#})++-- lbp3 :: Image GrayScale D32 -> [Double] +-- lbp3 = broilerPlate256 ({#call localBinaryPattern3#})++-- | The larger radius basic 5x5 lbp operator+lbp5 :: Image GrayScale D32 -> [Double] +lbp5 = broilerPlate256 ({#call localBinaryPattern5#})++lbpHorizontal :: Image GrayScale D32 -> [Double] +lbpHorizontal = broilerPlate256      ({#call localHorizontalBinaryPattern#})-lbpVertical = broilerPlate ++lbpVertical :: Image GrayScale D32 -> [Double] +lbpVertical = broilerPlate256      ({#call localVerticalBinaryPattern#}) --- LBP with weights and adjustable sampling points+-- | A variant of LBP which is weighted. This can be used to select only parts of the+-- image by using binary masks, or to give higher weight for some areas of the image.+weightedLBP :: (Integral a, Integral a1) =>+     a+     -> a1+     -> CV.Image.Image GrayScale D32+     -> CV.Image.Image GrayScale D32+     -> [Double]+ weightedLBP offsetX offsetXY weights image = unsafePerformIO $ do              withGenImage image $ \img ->               withGenImage weights $ \ws ->                   withArray (replicate 256 0) $ \ptrn -> do-                    {#call weighted_localBinaryPattern#} img (fromIntegral offsetX) (fromIntegral offsetXY) ws ptrn +                    {#call weighted_localBinaryPattern#} img +                        (fromIntegral offsetX) +                        (fromIntegral offsetXY) ws ptrn                      p <- peekArray 256 ptrn-                    return p+                    return $ map realToFrac p -emptyPattern :: [CInt]-emptyPattern = replicate 256 0-broilerPlate op image = unsafePerformIO $ do+broilerPlate256  = broilerPlate' 256+broilerPlate' l op image = unsafePerformIO $ do              withGenImage image $ \img ->-              withArray emptyPattern $ \ptrn -> do+              withArray (replicate l 0 :: [CInt]) $ \ptrn -> do                 (op img ptrn )-                p <- peekArray 256 ptrn+                p <- peekArray l ptrn                 let !maximum = fromIntegral $ sum p                 return $ map (\x -> fromIntegral x / maximum) p
CV/Transforms.chs view
@@ -22,6 +22,7 @@              | otherwise = 2  -- |Perform Discrete Cosine Transform+dct :: Image GrayScale d -> Image GrayScale d dct img | (x,y) <- getSize img, even x && even y          = unsafePerformIO $             withGenImage img $ \i -> @@ -31,6 +32,7 @@         | otherwise = error "DCT needs even sized image"  -- |Perform Inverse Discrete Cosine Transform+idct :: Image GrayScale d -> Image GrayScale d idct img | (x,y) <- getSize img, even x && even y          = unsafePerformIO $             withGenImage img $ \i -> @@ -42,6 +44,7 @@ data MirrorAxis = Vertical | Horizontal deriving (Show,Eq)  -- |Mirror an image over a cardinal axis+flip :: CreateImage (Image c d) => MirrorAxis -> Image c d -> Image c d flip axis img = unsafePerformIO $ do                  cl <- emptyCopy img                  withGenImage img $ \cimg -> @@ -50,7 +53,8 @@                  return cl  -- |Rotate `img` `angle` radians.-rotate angle img = unsafePerformIO $+rotate :: Double -> Image c d -> Image c d+rotate (realToFrac -> angle) img = unsafePerformIO $                     withImage img $ \i ->                          creatingImage                           ({#call rotateImage#} i 1 angle)@@ -73,7 +77,7 @@   -- |Scale an image with different ratios for axes-scale :: (RealFloat a) => Interpolation -> (a,a) -> Image GrayScale D32 -> Image GrayScale D32+scale :: (CreateImage (Image c D32), RealFloat a) => Interpolation -> (a,a) -> Image c D32 -> Image c D32 scale tpe (x,y) img = unsafePerformIO $ do                     target <- create (w',h')                      withGenImage img $ \i -> @@ -87,7 +91,8 @@                        ,round $ fromIntegral h*x)  -- |Scale an image to a given size-scaleToSize :: Interpolation -> Bool -> (Int,Int) -> Image GrayScale D32 -> Image GrayScale D32+scaleToSize :: (CreateImage (Image c D32)) => +    Interpolation -> Bool -> (Int,Int) -> Image c D32 -> Image c D32 scaleToSize tpe retainRatio (w,h) img = unsafePerformIO $ do                     target <- create (w',h')                      withGenImage img $ \i -> @@ -103,13 +108,9 @@              ratio  = max (fromIntegral w/fromIntegral ow)                           (fromIntegral h/fromIntegral oh) --- | DEPRECATED: A simple one parameter shrinking of the image-oneParamPerspective img k-    = unsafePerformIO $ -       withImage img $ \cimg -> creatingImage $ {#call simplePerspective#} k cimg- -- |Apply a perspective transform to the image. The transformation 3x3 matrix is supplied as --  a row ordered, flat, list.+perspectiveTransform :: Real a => Image c d -> [a] -> Image c d perspectiveTransform img (map realToFrac -> [a1,a2,a3,a4,a5,a6,a7,a8,a9])     = unsafePerformIO $         withImage img $ \cimg -> creatingImage $ {#call wrapPerspective#} cimg a1 a2 a3 a4 a5 a6 a7 a8 a9@@ -130,6 +131,7 @@  --- Pyramid transforms -- |Return a copy of an image with an even size+evenize :: Image channels depth -> Image channels depth evenize img = if (odd w || odd h)               then                   unsafePerformIO $     @@ -140,6 +142,7 @@      (w,h)  = getSize img  -- |Return a copy of an image with an odd size+oddize :: Image channels depth -> Image channels depth oddize img = if (even w || even h)               then                   unsafePerformIO $     @@ -152,6 +155,7 @@      (w,h)  = getSize img  -- |Pad images to same size+sameSizePad :: Image channels depth -> Image c d -> Image channels depth sameSizePad img img2 = if (size1 /= size2)               then unsafePerformIO $ do                 r <- creatingImage $
CV/Video.chs view
@@ -1,4 +1,4 @@-{-#LANGUAGE ForeignFunctionInterface, ViewPatterns#-}+{-#LANGUAGE ForeignFunctionInterface, ViewPatterns, CPP#-} #include "cvWrapLEO.h" module CV.Video where {#import CV.Image#}@@ -77,11 +77,17 @@     , CAP_PROP_GAIN           =  CV_CAP_PROP_GAIN              , CAP_PROP_EXPOSURE       =  CV_CAP_PROP_EXPOSURE          , CAP_PROP_CONVERT_RGB    =  CV_CAP_PROP_CONVERT_RGB  -    , CAP_PROP_WHITE_BALANCE  =  CV_CAP_PROP_WHITE_BALANCE+#ifdef OpenCV23+    , CAP_PROP_WHITE_BALANCE_BLUE_U = CV_CAP_PROP_WHITE_BALANCE_BLUE_U +    , CAP_PROP_WHITE_BALANCE_RED_V  = CV_CAP_PROP_WHITE_BALANCE_RED_V+#else+    , CAP_PROP_WHITE_BALANCE  = CV_CAP_PROP_WHITE_BALANCE+#endif     , CAP_PROP_RECTIFICATION  =  CV_CAP_PROP_RECTIFICATION      , CAP_PROP_MONOCROME      =  CV_CAP_PROP_MONOCROME     }; #endc+ {#enum CapProp {}#}  fromProp = fromIntegral . fromEnum
− CV/cvWrapLEO.c
@@ -1,2286 +0,0 @@-//@+leo-ver=4-thin-//@+node:aleator.20050908100314:@thin cvWrapLEO.c-//@@language c--//@+all-//@+node:aleator.20050908100314.1:Includes-#include "cvWrapLEO.h"-#include <stdio.h>-#include <complex.h>--//@-node:aleator.20050908100314.1:Includes-//@+node:aleator.20050908100314.2:Wrappers--#define FGET(img,x,y) (((float *)((img)->imageData + (y)*(img)->widthStep))[(x)])-#define UGETC(img,color,x,y) (((uint8_t *)((img)->imageData + (y)*(img)->widthStep))[(x)*3+(color)])--size_t images;--void incrImageC(void)-{- images++;-}--void wrapReleaseImage(IplImage *t)-{- // printf("%d ",images);- cvReleaseImage(&t);- images--;-}--void wrapReleaseCapture(CvCapture *t)-{- cvReleaseCapture(&t);-}--void wrapReleaseVideoWriter(CvCapture *t)-{- cvReleaseCapture(&t);-}--void wrapReleaseStructuringElement(IplConvKernel *t)-{- cvReleaseStructuringElement(&t);-}--IplImage* wrapLaplace(IplImage *src,int size)-{-IplImage *res;-IplImage *tmp;-tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,1);-res = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);-cvLaplace(src,tmp,size);-cvConvertScale(tmp,res,1,0);-return res;-}--IplImage* wrapSobel(IplImage *src,int dx-                   ,int dy,int size)-{-IplImage *res;-IplImage *tmp;-tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,1);-res = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);-cvSobel(src,tmp,dx,dy,size);-cvConvertScale(tmp,res,1,0);-cvReleaseImage(&tmp);-return res;-}--IplImage* wrapCreateImage32F(const int width-                         ,const int height-                         ,const int channels)-{- CvSize s;- IplImage *r;- s.width = width; s.height = height;- r = cvCreateImage(s,IPL_DEPTH_32F,channels);- cvSetZero(r);- return r;-}--IplImage* wrapCreateImage64F(const int width-                         ,const int height-                         ,const int channels)-{- CvSize s;- IplImage *r;- s.width = width; s.height = height;- r = cvCreateImage(s,IPL_DEPTH_64F,channels);- cvSetZero(r);- return r;-}---IplImage* wrapCreateImage8U(const int width-                         ,const int height-                         ,const int channels)-{- CvSize s;- IplImage *r;- s.width = width; s.height = height;- r = cvCreateImage(s,IPL_DEPTH_8U,channels);- cvSetZero(r);- return r;-}--IplImage* composeMultiChannel(IplImage* img0-                             ,IplImage* img1-                             ,IplImage* img2-                             ,IplImage* img3-                             ,const int channels)-{- CvSize s;- IplImage *r;- s = cvGetSize(img0);- r = cvCreateImage(s,img0->depth,channels);- cvSetZero(r);- cvMerge(img0,img1,img2,img3,r);- return r;-}-void wrapSubRS(const CvArr *src, double s, CvArr *dst)-{- cvSubRS(src,cvRealScalar(s),dst,0);-}--void wrapSubS(const CvArr *src, double s, CvArr *dst)-{- cvSubS(src,cvRealScalar(s),dst,0);-}--void wrapAddS(const CvArr *src, double s, CvArr *dst)-{- cvAddS(src,cvRealScalar(s),dst,0);-}--void wrapAbsDiffS(const CvArr *src, double s, CvArr *dst)-{- cvAbsDiffS(src,dst,cvScalarAll(s));-}--double wrapAvg(const CvArr *src)-{- CvScalar avg = cvAvg(src,0);- return avg.val[0];-}--double wrapStdDev(const CvArr *src)-{- CvScalar dev;- cvAvgSdv(src,0,&dev,0);- return dev.val[0];-}--double wrapStdDevMask(const CvArr *src,const CvArr *mask)-{- CvScalar dev;- IplImage *mask8 = ensure8U(mask);- cvAvgSdv(src,0,&dev,mask8);- cvReleaseImage(&mask8); - return dev.val[0];-}-double wrapMeanMask(const CvArr *src,const CvArr *mask)-{- CvScalar mean;- IplImage *mask8 = ensure8U(mask);- cvAvgSdv(src,&mean,0,mask8);- cvReleaseImage(&mask8); - return mean.val[0];-}--double wrapSum(const CvArr *src)-{- CvScalar sum = cvSum(src);- return sum.val[0];-}--void wrapMinMax(const CvArr *src,const CvArr *mask-               ,double *minVal, double *maxVal)-{- //cvMinMaxLoc(src,minVal,maxVal,NULL,NULL,NULL);- int i,j;- int minx,miny,maxx,maxy;- double pixel;- double maskP;- int t;- double min=100000,max=-100000; // Some problem with DBL_MIN.-- CvSize s = cvGetSize(src);- for(i=0; i<s.width; i++)-  for(j=0; j<s.height; j++)-   {-   pixel = cvGetReal2D(src,j,i);-   maskP = mask != 0 ? cvGetReal2D(mask,j,i) : 1;-   // TODO: Fix below.. -   min   = (maskP >0.5 ) && (pixel < min) ? pixel : min; -   max   = (maskP >0.5 ) && (pixel > max) ? pixel : max; -   }- (*minVal) = min; (*maxVal) = max; -}--void wrapSetImageROI(IplImage *i,int x, int y, int w, int h)-{- CvRect r = cvRect(x,y,w,h);- cvSetImageROI(i,r);-}---// Return image that is IPL_DEPTH_8U version of -// given src-IplImage* ensure8U(const IplImage *src)-{- CvSize size;- IplImage *result;- int channels = src->nChannels;- int dstDepth = IPL_DEPTH_8U;- size = cvGetSize(src);- result = cvCreateImage(size,dstDepth,channels);-- switch(src->depth) {-  case IPL_DEPTH_32F:-  case IPL_DEPTH_64F:-   cvConvertScale(src,result,255.0,0); // Scale the values to [0,255]-   return result;-  case IPL_DEPTH_8U:-   cvConvertScale(src,result,1,0);-   return result;-  default:-   printf("Cannot convert to floating image");-   abort();-   - }-}--// Return image that is IPL_DEPTH_32F version of -// given src-IplImage* ensure32F(const IplImage *src)-{- CvSize size;- IplImage *result;- int channels = src->nChannels;- int dstDepth = IPL_DEPTH_32F;- size = cvGetSize(src);- result = cvCreateImage(size,dstDepth,channels);-- switch(src->depth) {-  case IPL_DEPTH_32F:-  case IPL_DEPTH_64F:-   cvConvertScale(src,result,1,0); // Scale the values to [0,255]-   return result;-  case IPL_DEPTH_8U:-  case IPL_DEPTH_8S:-   cvConvertScale(src,result,1.0/255.0,0);-   return result;-  case IPL_DEPTH_16S:-   cvConvertScale(src,result,1.0/65535.0,0);-   return result;-  case IPL_DEPTH_32S:-   cvConvertScale(src,result,1.0/4294967295.0,0);-   return result;-  default:-   printf("Cannot convert to floating image");-   abort();-   - }-}--void wrapSet32F2D(CvArr *arr, int x, int y, double value)-{ - cvSet2D(arr,x,y,cvRealScalar(value)); -}---double wrapGet32F2D(CvArr *arr, int x, int y)-{ - CvScalar r;- r = cvGet2D(arr,x,y); - return r.val[0];-}--double wrapGet32F2DC(CvArr *arr, int x, int y,int c)-{ - CvScalar r;- r = cvGet2D(arr,x,y); - return r.val[c];-}--uint8_t wrapGet8U2DC(IplImage *arr, int x, int y,int c)-{ - return UGETC(arr,c,y,x);-}---void wrapDrawCircle(CvArr *img, int x, int y, int radius, float r,float g,float b, int thickness)-{- cvCircle(img,cvPoint(x,y),radius,CV_RGB(r,g,b),thickness,8,0);-}--void wrapDrawText(CvArr *img, char *text, float s, int x, int y,float r,float g,float b)-{-CvFont font; //?-cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, s, s, 0, 2, 8);-cvPutText(img, text, cvPoint(x,y), &font, CV_RGB(r,g,b));-}--void wrapDrawRectangle(CvArr *img, int x1, int y1, -                       int x2, int y2, float r, float g, float b,-                       int thickness)-{- cvRectangle(img,cvPoint(x1,y1),cvPoint(x2,y2),CV_RGB(r,g,b),thickness,8,0);-}---void wrapDrawLine(CvArr *img, int x, int y, int x1, int y1, double r, double g, double b, int thickness)-{- cvLine(img,cvPoint(x,y),cvPoint(x1,y1),CV_RGB(r,g,b),thickness,4,0);-}--void wrapFillPolygon(IplImage *img, int pc, int *xs, int *ys, float r, float g, float b)-{ - int i=0;- int pSizes[] = {pc};- CvPoint *pts = (CvPoint*)malloc(pc*sizeof(CvPoint));- for (i=0; i<pc; ++i)-    {pts[i].x = xs[i]; -     pts[i].y = ys[i]; -     }- cvFillPoly(img, &pts, pSizes, 1, CV_RGB(r,g,b), 8, 0 );- free(pts);-}----int getImageWidth(IplImage *img)-{- return cvGetSize(img).width;-}-int getImageHeight(IplImage *img)-{- return cvGetSize(img).height;-}--IplImage* getSubImage(IplImage *img, int sx,int sy,int w,int h)-{- CvRect r;- CvSize s;- IplImage *newImage;- - r.x = sx; r.y = sy;- r.width = w; r.height = h;- s.width = w; s.height = h;- - cvSetImageROI(img,r);- newImage = cvCreateImage(s,img->depth,img->nChannels);- cvCopy(img, newImage,0);- cvResetImageROI(img);- return newImage;-}--IplImage* simpleMergeImages(IplImage *a, IplImage *b,int offset_x, int offset_y)-{- CvSize aSize = cvGetSize(a);- CvSize bSize = cvGetSize(b);- int startx = 0 < offset_x ? 0 : offset_x;- int endx = aSize.width > bSize.width+offset_x ? aSize.width : bSize.width+offset_x ;-- int starty = 0 < offset_y ? 0 : offset_y;- int endy = aSize.height > bSize.height+offset_y ? aSize.height : bSize.height+offset_y ;-- CvSize size;- size.width  = endx-startx;- size.height = endy-starty;-- CvRect aPos = cvRect(offset_x<0?-offset_x:0-                     ,offset_y<0?-offset_y:0-                     ,aSize.width-                     ,aSize.height);-- CvRect bPos = cvRect(offset_x<0?0:offset_x-                     ,offset_y<0?0:offset_y-                     ,bSize.width-                     ,bSize.height);-- IplImage *resultImage = cvCreateImage(size,a->depth,a->nChannels);-- // Blit the images into bigger result image using cvCopy- cvSetImageROI(resultImage,aPos);- cvCopy(a,resultImage,NULL);- cvSetImageROI(resultImage,bPos);- cvCopy(b,resultImage,NULL);- cvResetImageROI(resultImage);- return resultImage;-}--void blitImg(IplImage *a, IplImage *b,int offset_x, int offset_y)-{- CvSize bSize = cvGetSize(b);- CvRect pos = cvRect(offset_x-                    ,offset_y-                    ,bSize.width-                    ,bSize.height);-- // Blit the images b into a using cvCopy- printf("Doing a blit\n"); fflush(stdout);- cvSetImageROI(a,pos);- cvCopy(b,a,NULL);- cvResetImageROI(a);- printf("Done!\n"); fflush(stdout);-}--IplImage* makeEvenDown(IplImage *src)-{- CvSize size = cvGetSize(src);- int w = size.width-(size.width % 2);- int h = size.height-(size.height % 2);- IplImage *result = wrapCreateImage32F(w,h,1);    - CvRect pos = cvRect(0-                    ,0-                    ,size.width-                    ,size.height);- // Blit the images b into a using cvCopy- cvSetImageROI(src,pos);- cvCopy(src,result,NULL);- cvResetImageROI(result);- return result;-}--IplImage* makeEvenUp(IplImage *src)-{- CvSize size = cvGetSize(src);- int w = size.width+(size.width % 2);- int h = size.height+(size.height % 2);- int j;- IplImage *result = wrapCreateImage32F(w,h,1);    - CvRect pos = cvRect(0-                    ,0-                    ,size.width-                    ,size.height);- // Blit the images b into a using cvCopy- cvSetImageROI(result,pos);- cvCopy(src,result,NULL);- cvResetImageROI(result);- if (size.width % 2 == 1)-      {for (j=0; j<=size.height; j++) {-          FGET(result,size.width,j) = FGET(result,size.width-1,j); } }- if (size.width % 2 == 1)-      {for (j=0; j<=size.width; j++) {-          FGET(result,j,(size.height)) = FGET(result,j,(size.height-1)); } }- return result;-}--IplImage* padUp(IplImage *src,int right, int bottom)-{- CvSize size = cvGetSize(src);- int w = size.width + (right  ? 1 : 0);- int h = size.height+ (bottom ? 1 : 0);- int j;- IplImage *result = wrapCreateImage32F(w,h,1);    - CvRect pos = cvRect(0-                    ,0-                    ,size.width-                    ,size.height);- // Blit the images b into a using cvCopy- cvSetImageROI(result,pos);- cvCopy(src,result,NULL);- cvResetImageROI(result);- if (right)-      {for (j=0; j<=size.height; j++) {-          FGET(result,size.width,j) = 2*FGET(result,size.width-1,j)-                                       -FGET(result,size.width-2,j); } }- if (bottom)-      {for (j=0; j<=size.width; j++) {--          FGET(result,j,(size.height)) = 2*FGET(result,j,(size.height-1))-                                          -FGET(result,j,(size.height-2)); -                                          } }- return result;-}--void masked_merge(IplImage *src1, IplImage *mask, IplImage *src2, IplImage *dst)-{- int i,j;- CvSize size = cvGetSize(dst);- for (i=0; i<size.width; i++)-    for (j=0; j<size.height; j++) {-       FGET(dst,i,j) =  FGET(src1,i,j)*FGET(mask,i,j) -                        +FGET(src2,i,j)*(1-FGET(mask,i,j));-     }-}--void vertical_average(IplImage *src, IplImage *dst)-{- int i,j;- double avg;- CvSize size = cvGetSize(dst);- for (i=0; i<size.width; i++) {-    avg = 0;-    for (j=0; j<size.height; j++) { avg += FGET(src,i,j); }-    avg = avg / size.height;-    for (j=0; j<size.height; j++) { FGET(dst,i,j) = avg; }-    }-}---IplImage* fadedEdges(int w, int h, int edgeW) {-    IplImage *result;-    int i,j;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-           float dx = i < (h/2.0) ? i : h-i ;-           float dy = j < (w/2.0) ? j : w-j ;-           float x = dx > edgeW ? 1 : dx/edgeW;-           float y = dy > edgeW ? 1 : dy/edgeW;-           FGET(result,j,i) = x*y;-           }-    return result;-}--IplImage* rectangularDistance(int w, int h) {-    IplImage *result;-    int i,j;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-           float dx = i < (h/2.0) ? i/(h*1.0) : (h-i)/(h*1.0) ;-           float dy = j < (w/2.0) ? j/(w*1.0) : (w-j)/(w*1.0) ;-           FGET(result,j,i) = dx<dy?dx:dy;-           }-    return result;-}-IplImage* vignettingModelCos4(int w, int h) {-    IplImage *result;-    int i,j;-    double nx,ny;-    double r;-    const double x0 = w/2.0;-    const double y0 = h/2.0;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-            nx = (y0-i)/h;-            ny = (x0-j)/w;-            r = sqrt(nx*nx+ny*ny);-            FGET(result,j,i) = pow(cos (r),4);-           }-    return result;-}--IplImage* vignettingModelCos4XCyl(int w, int h) {-    IplImage *result;-    int i,j;-    double r;-    const double x0 = w/2.0;-    const double y0 = h/2.0;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-            r = fabs((i-y0)/y0) ;-            FGET(result,j,i) = pow(cos (r),4);-           }-    return result;-}--IplImage* vignettingModelX2Cyl(int w, int h,double m, double s, double c) {-    IplImage *result;-    int i,j;-    double r;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-            FGET(result,j,i) = -((i-c)*s)*((i-c)*s)-m;-           }-    return result;-}-inline double eucNorm(CvPoint2D64f p) {return (p.x*p.x+p.y*p.y);}--IplImage* vignettingModelB3(int w, int h,double b1, double b2, double b3) {-    IplImage *result;-    int i,j;-    double r;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-            CvPoint2D64f nor = toNormalizedCoords(cvSize(w,h),cvPoint(j,i));-            r = eucNorm(nor);-            FGET(result,j,i) = b3*pow(r,6)+b2*pow(r,4)+b3*pow(r,2)+1;-           }-    return result;-}-IplImage* vignettingModelP(int w, int h,double scalex, double scaley, double max) {-    IplImage *result;-    int i,j;-    double r;-    double mx = w/2.0;-    double my = w/2.0;-    result = wrapCreateImage32F(w,h,1);    -    for (i=0; i<h; i++)-       for (j=0; j<w; j++) {-            FGET(result,j,i) =-((i-my)*scaley)*((i-my)*scaley)*((j-mx)*scalex)*((j-mx)*scalex)-max ;-           }-    return result;-}--IplImage* simplePerspective(double k,IplImage *src) {-    IplImage *result;-    int i,j;-    double r;-    result = cvCloneImage(src);    -    int h = cvGetSize(src).height;-    int w = cvGetSize(src).width;-    CvPoint2D32f srcPts[4] = {{0,0},{w-1,0},{w-1,h-1},{0,h-1}};-    CvPoint2D32f dstPts[4] = {{-k,0},{w-1+k,0},{w-1,h-1},{0,h-1}};-    CvMat* M = cvCreateMat(3,3,CV_32FC1);-    cvGetPerspectiveTransform(srcPts, dstPts, M);-    cvWarpPerspective(src, result, M, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));-    cvReleaseMat(&M);-    return result;-}--IplImage* wrapPerspective(IplImage* src, double a1, double a2, double a3-                                       , double a4, double a5, double a6-                                       , double a7, double a8, double a9)-{-    IplImage *res = cvCloneImage(src);-    double a[] = { a1,a2,a3,-                   a4,a5,a6,-                   a7,a8,a9};--    CvMat M = cvMat(3,3,CV_64FC1,a);-    cvWarpPerspective(src, res, &M, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));-    return res;-}--void findHomography(double* srcPts, double *dstPts, int noPts, double *homography)-{-CvMat src = cvMat(noPts, 2, CV_64FC1, srcPts);-CvMat dst = cvMat(noPts, 2, CV_64FC1, dstPts);-CvMat *hmg = cvCreateMat(3,3,CV_32FC1);-int i;-cvFindHomography(&src, &dst, hmg, 0, 0, 0);-for (i=0;i<3*3;++i)-        homography[i] = cvmGet(hmg,i/3,i%3);-cvReleaseMat(&hmg);-}--inline CvPoint2D64f toNormalizedCoords(CvSize area, CvPoint from)-{-    CvPoint2D64f res;-    res.x = (from.x-area.width/2.0)/area.width;-    res.y = (from.y-area.height/2.0)/area.height;   -    return res;-}--inline CvPoint fromNormalizedCoords(CvSize area, CvPoint2D64f from)-{-    CvPoint res;-    res.x = (from.x+0.5)*area.width;-    res.y = (from.y+0.5)*area.height;   -    return res;-}--inline CvPoint2D64f fromNormalizedCoords64f(CvSize area, CvPoint2D64f from)-{-    CvPoint2D64f res;-    res.x = (from.x+0.5)*area.width;-    res.y = (from.y+0.5)*area.height;   -    return res;-}--void alphaBlit(IplImage *a, IplImage *aAlpha, IplImage *b, IplImage *bAlpha, int offset_y, int offset_x)-{-    // TODO: Add checks for image type and size- int i,j;- CvSize bSize = cvGetSize(b);- CvSize aSize = cvGetSize(a);- CvRect pos = cvRect(offset_x-                    ,offset_y-                    ,bSize.width-                    ,bSize.height);- for (i=0; i<bSize.height; i++)-    for (j=0; j<bSize.width; j++) {-       float aA, bA,fV;-       if (j+offset_x>=aSize.width || i+offset_y>=aSize.height || i+offset_y < 0 || j+offset_x<0) continue;--       aA = FGET(aAlpha,j+offset_x,i+offset_y);-       bA = FGET(bAlpha,j,i);-       fV = aA+bA > 0 ? (FGET(b,j,i)*bA+FGET(a,j+offset_x,i+offset_y)*aA)/(aA+bA) : FGET(b,j,i) ;-       FGET(a,j+offset_x,i+offset_y) =fV;-       FGET(aAlpha,j+offset_x,i+offset_y) =aA+bA;-    }-}---void plainBlit(IplImage *a, IplImage *b, int offset_y, int offset_x)-{-    // TODO: Add checks for image type and size- int i,j;- CvSize aSize = cvGetSize(a);- CvSize bSize = cvGetSize(b);- for (i=0; i<bSize.height; i++) {-    for (j=0; j<bSize.width; j++) {-       if (j+offset_x<0 || j+offset_x>=aSize.width || i+offset_y<0 || i+offset_y>=aSize.height ) continue;-       if (a->nChannels == 1) -            {FGET(a,j+offset_x,i+offset_y) =FGET(b,j,i);}-        else if (a->nChannels ==3) -            {-             int dx = j+offset_x; int dy = i+offset_y;-             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 0] =-              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 0] ; // B-             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 1] =-              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 1] ; // G-             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 2] =-              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 2] ; // R-            }-             else {printf("Can't blit this - pic weird number of channels\n"); abort();}--    }}-}--void subpixel_blit(IplImage *a, IplImage *b, double offset_y, double offset_x)-{-    // TODO: Add checks for image type and size- int i,j;- CvSize aSize = cvGetSize(a);- CvSize bSize = cvGetSize(b);- for (i=0; i<aSize.height; i++)-    for (j=0; j<aSize.width; j++) {-       double x_at_b=j-offset_x;-       double y_at_b=i-offset_y;-       if (x_at_b <0 || x_at_b >= bSize.width-           || y_at_b <0 || y_at_b >= bSize.height) continue;-       FGET(a,j,i) =bilinearInterp(b,x_at_b,y_at_b);-        // TODO: Check boundaries! #SAFETY--    }-}---// Histograms.-void wrapReleaseHist(CvHistogram *hist)-{- cvReleaseHist(&hist);-}--CvHistogram* calculateHistogram(IplImage *img,int bins)-{- float st_range[] = {-1,1};- float *ranges[]  = {st_range};- int hist_size[] = {bins};- CvHistogram *result = cvCreateHist(1,hist_size,CV_HIST_ARRAY,ranges,1);- cvCalcHist(&img,result,0,0);- return result;-}--void get_histogram(IplImage *img,IplImage *mask-                 ,float a, float b,int isCumulative-                 ,int binCount-                 ,double *values)-{- int i=0;- float st_range[] = {a,b};- float *ranges[]  = {st_range};- int hist_size[] = {binCount};- CvHistogram *result = cvCreateHist(1,hist_size,CV_HIST_ARRAY-                                   ,ranges,1);- cvCalcHist(&img,result,isCumulative,mask);- for (i=0;i<binCount;++i)-    {-     *values = cvQueryHistValue_1D(result,i); values++;-    }- cvReleaseHist(&result);- return;-}---double getHistValue(CvHistogram *h,int bin)-{- return *cvGetHistValue_1D(h,bin);-}--// Convolutions-IplImage* wrapFilter2D(IplImage *src, int ax,int ay, -                    int w, int h, double *kernel){-int i,j;-IplImage *target = cvCloneImage(src);-CvMat *kernelMat = cvCreateMat(w,h,CV_32FC1);-for(i=0;i<w*h;i++)-  cvSetReal2D(kernelMat,i%w,i/w,kernel[i]); -cvFilter2D(src,target,kernelMat,cvPoint(ay,ax));-cvReleaseMat(&kernelMat);-return target;-}--IplImage* wrapFilter2DImg(IplImage *src-                         ,IplImage *mask-                         ,int ax,int ay)-{-int i,j;-IplImage *target = cvCloneImage(src);-CvSize size = cvGetSize(mask);-CvMat *kernelMat = cvCreateMat(size.width,size.height,CV_32FC1);-for(i=0;i<size.width;i++)- for(j=0;j<size.height;j++)-  cvSetReal2D(kernelMat,i,j,cvGetReal2D(mask,j,i)); -cvFilter2D(src,target,kernelMat,cvPoint(ay,ax));-cvReleaseMat(&kernelMat);-return target;-}--// Connected components--void wrapFloodFill(IplImage *i, int x, int y, double c-                  ,double low, double high,int fixed)-{- int flag = 8 | (fixed ? CV_FLOODFILL_FIXED_RANGE : 0);- cvFloodFill(i,cvPoint(x,y),cvRealScalar(c),cvRealScalar(low)-            ,cvRealScalar(high),NULL,flag,NULL);-}-                  -// hough-lines--void wrapProbHoughLines(IplImage *img, double rho, double theta-                       , int threshold, double minLength-                       , double gapLength-                       , int *maxLines-                       , int *xs, int *ys-                       , int *xs1, int *ys1)-{- IplImage *tmp;- CvSeq *lines = 0;- int i;- CvMemStorage *storage = cvCreateMemStorage(0); - - tmp = ensure8U(img);-- lines = cvHoughLines2(tmp,storage,CV_HOUGH_PROBABILISTIC-                     ,rho,theta,threshold,minLength,gapLength);- for( i = 0; i < MIN(lines->total,*maxLines); i++ )-        {-            CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);-            xs[i] = line[0].x; xs1[i] = line[1].x;-            ys[i] = line[0].y; ys1[i] = line[1].y; -        }- *maxLines = MIN(lines->total,*maxLines);-- cvReleaseImage(&tmp);- cvReleaseMemStorage(&storage);- -}-                       ---//@-node:aleator.20050908100314.2:Wrappers-//@+node:aleator.20050908100314.3:Utilities-/* These are utilities that operate on opencv primitives but-  are not really wrappers.. Due to the fact that I seem to-  be incapable to link multiple objects including openCV-  headers this seems to be the next best solution.--  Watch out for name collisions!--*/-//@+node:aleator.20070906153003:Trigonometric operations--void calculateAtan(IplImage *src, IplImage *dst)-{-  CvSize imageSize = cvGetSize(dst);-  double r=0; int i; int j;-  for(i=0; i<imageSize.width; ++i)-    for(j=0; j<imageSize.height; ++j) {-          r = cvGetReal2D(src,j,i);-          cvSet2D(dst,j,i,cvScalarAll(atan(r)));-    }-}--void calculateAtan2(IplImage *src1,IplImage *src2, IplImage *dst)-{-  CvSize imageSize = cvGetSize(dst);-  for(int i=0; i<imageSize.width; ++i)-    for(int j=0; j<imageSize.height; ++j) {-          double a = FGET(src1,j,i);-          double b = FGET(src2,j,i);-          FGET(dst,j,i) = atan2(a,b);-    }-}--//@nonl-//@-node:aleator.20070906153003:Trigonometric operations-//@+node:aleator.20051109111547:Pixel accessors-// All these will work only on grayscale.-inline int imax(int x, int y) {return (x>y) ? x:y;}-inline int imin(int x, int y) {return (x<y) ? x:y;}-inline double blurGet2D(IplImage *img,int x, int y)-{- CvSize size = cvGetSize(img);- x = imax(0,imin(x,size.width-1));- y = imax(0,imin(y,size.height-1));-- return cvGetReal2D(img,y,x);-}--//@-node:aleator.20051109111547:Pixel accessors-//@+node:aleator.20070827150608:Haar Filters--// Simple routines for calculating pixelwise-// haar responses--void haarFilter(IplImage *intImg, -                int x1, int y1, int x2, int y2,-                IplImage *target)-{-  int i,j;-  double s = 0;-  double ratio = 1;-  double desArea = (x2-x1)*(y1-y2);-  double area = 0;-  int rx1,rx2,ry1,ry2;-  CvSize imageSize = cvGetSize(target);  -  for(i=0; i<imageSize.width; ++i)-    for(j=0; j<imageSize.height; ++j) {-         rx1 = imax(0,imin(i+x1,imageSize.width-1));  -         ry1 = imax(0,imin(j+y1,imageSize.height-1));-         rx2 = imax(0,imin(i+x2,imageSize.width-1)); -         ry2 = imax(0,imin(j+y2,imageSize.height-1));-         area = (float)((rx2-rx1)*(ry2-ry1));-        // if (area > 0) ratio = fabs(desArea/area);-        // else ratio=1;-         //printf("Ratio(%d,%d) is %lf\n",rx1,ry1,ratio);-         s = blurGet2D(intImg,rx1,ry1)-             -blurGet2D(intImg,rx1,ry2)-             -blurGet2D(intImg,rx2,ry1)-             +blurGet2D(intImg,rx2,ry2);-          cvSet2D(target,j,i,cvScalarAll(s/area));-    }-}--double haar_at(IplImage *intImg, -                int x1, int y1, int w, int h)-{-  int i,j;-  double s = 0;-  s = blurGet2D(intImg,x1,y1)-     -blurGet2D(intImg,x1,y1+h)-     -blurGet2D(intImg,x1+w,y1)-     +blurGet2D(intImg,x1+w,y1+h);-  return s;-}-                -//@nonl-//@-node:aleator.20070827150608:Haar Filters-//@+node:aleator.20070130144337:Statistics along a line-#define SWAP(a,b) { \-        int c = (a);    \-        (a) = (b);      \-        (b) = c;        \-    }---double average_of_line(int x0, int y0-                     ,int x1, int y1-                     ,IplImage *src) {-     int steep = abs(y1 - y0) > abs(x1 - x0);-     int deltax=0; int deltay=0;-     int error=0;-     int ystep=0;-     int x=0; int y=0;-     float sum=0; int len=0;--     if (steep)   { SWAP(x0, y0); SWAP(x1, y1); }-     if (x0 > x1) { SWAP(x0, x1); SWAP(y0, y1); }-     deltax = x1 - x0;-     deltay = abs(y1 - y0);-     error  = 0;-     y = y0;-     if (y0 < y1) {ystep = 1;} else {ystep = -1;}-     for (x=x0; x<x1; ++x) {-         if (steep) {sum+=blurGet2D(src,y,x);-                     ++len;} -                    // _plot(y,x);} -         else       {sum+=blurGet2D(src,x,y);-                     ++len; } -                    //_plot(x,y);}-         error = error + deltay;-         if (2*error >= deltax) {-             y = y + ystep;-             error = error - deltax; }-         }-         return (sum/len);-}--//@-node:aleator.20070130144337:Statistics along a line-//@+node:aleator.20051130130836:Taking square roots of images--void sqrtImage(IplImage *src,IplImage *dst)-{-int i;int j;-double result;-CvSize size = cvGetSize(src);--for(i=0;i<size.width;++i)- for(j=0;j<size.height;++j)-    {-     result = cvSqrt(cvGetReal2D(src,j,i));-     cvSetReal2D(dst,j,i,result);-    }-}-//@-node:aleator.20051130130836:Taking square roots of images-//@+node:aleator.20050930104348:Histogram Features-#define HISTOGRAMSIZE 10--double calculateMoment(int i,double arr[], int l)-{-int j=0;-double result = 0;-for(j=0; j<l; j++)-  {  result += pow((j*1.0)/HISTOGRAMSIZE,i)*arr[j]; }-return result;-}--double calculateAbsCentralMoment(int i,double arr[], int l)-{-int j=0;-double m1 = calculateMoment(1,arr,l);-double result = 0;-for(j=0; j<l; j++)- {-  result += pow(fabs(((j*1.0)/HISTOGRAMSIZE)-m1),i)*arr[j];}-return result;-}--double calculateCentralMoment(int i,double arr[], int l)-{-int j=0;-double m1 = calculateMoment(1,arr, l);-double result = 0;-for(j=0; j<l; j++)- {  -    result += pow(((j*1.0)/HISTOGRAMSIZE)-m1,i)*arr[j];-- }-return result;-}-//@+node:aleator.20050930104348.1:Central Moments--IplImage* getNthCentralMoment(IplImage *src,int n, int w, int h)-{--CvSize size = cvGetSize(src);-int iw = size.width-w;-int ih = size.height-h;-IplImage *target = wrapCreateImage32F(iw,ih,1);-int x = 0;-int y = 0;-int i = 0;-int j = 0;-double histogram[HISTOGRAMSIZE]; -for (x=0; x<ih; x++)- for (y=0; y<iw; y++)- {-memset(histogram,0,HISTOGRAMSIZE*sizeof(double));-double result = 0;--// Calculate the local histogram-for (i=0; i<w; i++)- for (j=0; j<h; j++)-    {-     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];-     histogram[slot] += 1.0/(w*h*1.0);-    }---result = calculateCentralMoment(n,histogram,HISTOGRAMSIZE); -cvSet2D(target,x,y,cvScalarAll(result));- }--return target;-}--IplImage* getNthAbsCentralMoment(IplImage *src,int n, int w, int h)-{--CvSize size = cvGetSize(src);-int iw = size.width-w;-int ih = size.height-h;-IplImage *target = wrapCreateImage32F(iw,ih,1);-int x = 0;-int y = 0;-int i = 0;-int j = 0;-double histogram[HISTOGRAMSIZE]; -for (x=0; x<ih; x++)- for (y=0; y<iw; y++)- {-memset(histogram,0,HISTOGRAMSIZE*sizeof(double));-double result = 0;--// Calculate the local histogram-for (i=0; i<w; i++)- for (j=0; j<h; j++)-    {-     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];-     histogram[slot] += 1.0/(w*h*1.0);-    }---result = calculateAbsCentralMoment(n,histogram,HISTOGRAMSIZE); -cvSet2D(target,x,y,cvScalarAll(result));- }--return target;-}--IplImage* getNthMoment(IplImage *src,int n, int w, int h)-{--CvSize size = cvGetSize(src);-int iw = size.width-w;-int ih = size.height-h;-IplImage *target = wrapCreateImage32F(iw,ih,1);-int x = 0;-int y = 0;-int i = 0;-int j = 0;-double histogram[HISTOGRAMSIZE]; -for (x=0; x<ih; x++)- for (y=0; y<iw; y++)- {-memset(histogram,0,HISTOGRAMSIZE*sizeof(double));-double result = 0;--// Calculate the local histogram-for (i=0; i<w; i++)- for (j=0; j<h; j++)-    {-     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];-     histogram[slot] += 1.0/(w*h*1.0);-    }--result = calculateMoment(n,histogram,HISTOGRAMSIZE); -cvSet2D(target,x,y,cvScalarAll(result));- }--return target;-}--//@-node:aleator.20050930104348.1:Central Moments-//@+node:aleator.20051103110155:SMAB-   -// Perform second moment adaptive binarization for a single pixel `x`-// using given histogram.-double max(double x,double y) {if (x<y) return y; else return x;}-double min(double x,double y) {if (x>y) return y; else return x;}-int SMABx(double x, CvHistogram *h,int binCount,double t)-{- int binnedX;  double leftSM=0;- double rightSM=0;- int i=0;- binnedX = round(min(1,max(x,0))*(binCount-1));-- // Calculate left second moment:- for(i=0; i<binnedX; i++)-  { leftSM += pow(x - ((1.0*i)/(1.0*binCount)),2) * getHistValue(h,i); }- for(i=binnedX; i<binCount; i++)-  { rightSM += pow(x - ((1.0*i)/(1.0*binCount)),2) * getHistValue(h,i); }- return (leftSM - (rightSM * t));-}--// Perform SMAB for image-void smb(IplImage *image,double t)-{-int i;int j;-double result;-CvSize size = cvGetSize(image);-CvHistogram *h = calculateHistogram(image,255);-for(i=0;i<size.width;++i)- for(j=0;j<size.height;++j)- {-     result = SMABx(cvGet2D(image,j,i).val[0],h,255,t);-     cvSet2D(image,j,i,cvScalarAll(result));- }-}--void smab(IplImage *image,int w, int h,double t)-{-int i;int j;-int wi;int wj;-double result;-CvHistogram *histogram;-CvRect roi;-CvSize size = cvGetSize(image);-roi.width = w;-roi.height = h;--for(i=0;i<size.width;++i)- for(j=0;j<size.height;++j)- {-     roi.x = i-(w/2);-     roi.y = j-(h/2);-     cvSetImageROI(image,roi);-     histogram = calculateHistogram(image,50);-     cvResetImageROI(image);-     result = SMABx(cvGetReal2D(image,j,i),histogram,50,t);-     cvReleaseHist(&histogram);-     cvSet2D(image,j,i,cvScalarAll(result));- }-}-//@-node:aleator.20051103110155:SMAB-//@+node:aleator.20051108093248:Skewness--//@-node:aleator.20051108093248:Skewness-//@-node:aleator.20050930104348:Histogram Features-//@+node:aleator.20050926095227:Susan-/* - Susan (Smallest Univalue Segmenting Nucleus) is - family of image processing methods, including- edge preserving noise reduction.-*/-//@+node:aleator.20050926095227.1:Susan Smoothing Function--/* - Calculate susan smoothing for `src` around `x`,`y` coordinates.- `t` determines brightness treshold and sigma controls scale of- spatial smoothing. `w` and `h` determine window size.-*/--inline double calcSusanSmooth(IplImage* src, int x, int y-                      ,double t,double sigma,int w, int h)-{--int i = 0;-int j = 0;--long double numerator = 0;-long double denominator = 0;-for (i = 0; i<w; i++)- for (j = 0; j<h; j++)-    {-    if (i==w/2 && j==h/2) continue;-    double r2 = i*i+j*j;-    double expFrac = (cvGet2D(src,x+i,y+j).val[0] -                     - cvGet2D(src,x,y).val[0]);-    expFrac *= expFrac;--    double exponential = exp(  (-r2/(2*sigma*sigma)) - (expFrac/(t*t))  );--    numerator   += cvGet2D(src,x+i,y+j).val[0] * exponential;-    denominator += exponential;-    }-return numerator/denominator;-}-//@-node:aleator.20050926095227.1:Susan Smoothing Function-//@+node:aleator.20050926100856:Susan Smoothing--IplImage* susanSmooth(IplImage *src, int w, int h-                     ,double t, double sigma)--{--CvSize size = cvGetSize(src);-int iw = size.width-w;-int ih = size.height-h;-IplImage *target = wrapCreateImage32F(iw,ih,1);-int x = 0;-int y = 0;-double result = 0;---for (x=0; x<iw; x++)- for (y=0; y<ih; y++)- {-  result = calcSusanSmooth(src,y,x,t,sigma,h,w);-  cvSet2D(target,y,x,cvScalarAll(result));- }-return target;-}-//@-node:aleator.20050926100856:Susan Smoothing-//@+node:aleator.20050927083244:Susan Edge-/* - Susan Edge Detector.-*/--// susan threshold function-inline double susanC(double r, double r0,double t)-{- return exp(-((r-r0)/t));-}--inline double susanValue(IplImage *src,int x, int y-                        ,int w, int h, double t)-{-int i; int j;-double geometricTreshold = (3*(w*h)) / 4;-double sum = 0;--for (i = 0; i<w; i++)- for (j = 0; j<h; j++)-    {-     sum += susanC(cvGet2D(src,x+i,y+j).val[0]-                  ,cvGet2D(src,x,y).val[0]-                  ,t);-    }-if (sum < geometricTreshold)-    return geometricTreshold - sum;-else return 0;-}--IplImage* susanEdge(IplImage *src,int w,int h,double t)-{-CvSize size = cvGetSize(src);-int iw = size.width-w;-int ih = size.height-h;-IplImage *target = wrapCreateImage32F(iw,ih,1);-int x = 0;-int y = 0;-double result = 0;---for (x=0; x<iw; x++)- for (y=0; y<ih; y++)- {-  result = susanValue(src,y,x,h,w,t);-  cvSet2D(target,y,x,cvScalarAll(result));- }-return target;--}-//@-node:aleator.20050927083244:Susan Edge-//@-node:aleator.20050926095227:Susan-//@+node:aleator.20050908112008:Gabors-/* - Gabor functions are modulated gaussians which bear some resemblance- to human visual cortex neurons. */-//@+node:aleator.20050908104238:gabor function in C-/* This function calculates value of simple gabor function-  at given x,y coordinates. Parameters for the gabor are:-  -  stdX  - standard deviation in oscillation direction-  stdY  - standard deviation tangential to stdX-  theta - angle (in radians) of the gabor-  phase - phase of the gabor---*/-double calcGabor(double x, double y-                ,double stdX, double stdY-                ,double theta, double phase-                ,double cycles)-{- double xth = x*cos(theta)  - y*sin(theta);- double yth = x*sin(theta)  + y*cos(theta);- double oscillationPart = cos(2*M_PI*xth/cycles+phase);- double gaussianPart    = exp((-0.5*xth*xth)/(stdX*stdX))-                         *exp((-0.5*yth*yth)/(stdY*stdY));- - return gaussianPart * oscillationPart;-}--double calc1DGabor(double x-                ,double sigma-                ,double phase, double center-                ,double cycles)-{- double oscillationPart = cos(2*M_PI*(x-center)/cycles+phase);- double gaussianPart    = exp((-0.5*(x-center)*(x-center))-                              /(sigma*sigma));- - return gaussianPart * oscillationPart;-}---//@-node:aleator.20050908104238:gabor function in C-//@+node:aleator.20050908112116:rendering gabors to arrays-void renderGabor(CvArr *dst,int width, int height-                ,double dx, double dy-                ,double stdX, double stdY-                ,double theta, double phase-                ,double cycles)--{- int i,j;- int mx = width/2;- int my = height/2;- for (i=0; i<width; i++)-  for (j=0; j<height; j++) // TODO: This might be a bug-   cvSet2D(dst,i,j,cvScalarAll(calcGabor(i-dx,j-dy,stdX,stdY-                                        ,theta,phase,cycles)));-}--void render_gaussian(IplImage *dst-                   ,double stdX, double stdY)--{- int i,j;- double distX;- double distY;- CvSize size = cvGetSize(dst);- double centerX = size.width/2.0;- double centerY = size.height/2.0;- for (i=0; i<size.width-1; i++)-  for (j=0; j<size.height-1; j++)-   { distX = ((centerX-i*1.0)*(centerX-i*1.0)) / (2*stdX*stdX);-     distY = ((centerY-j*1.0)*(centerY-j*1.0)) / (2*stdY*stdY);-  //   printf("w: %d, h: %d, i: %d, j:%d,dx: %e,dy: %e,exp:%e\n",size.width,size.height,i,j,distX,distY,exp(-distX-distY));-     fflush(stdout);-     cvSet2D(dst,j,i,cvScalarAll( exp(-distX-distY) ));-  }-}---void renderRadialGabor(CvArr *dst,int width, int height-                ,double sigma-                ,double phase, double center-                ,double cycles)--{- int i,j;- int mx = width/2;- int my = height/2;- double rad = 0;- for (i=0; i<width; i++)-  for (j=0; j<width; j++)-   {-   rad = sqrt((i-mx)*(i-mx)+(j-my)*(j-my));-   cvSet2D(dst,i,j,cvScalarAll(calc1DGabor(rad,sigma-                                          ,phase,center,cycles)));-   }-}--void wrapMinMaxLoc(const IplImage* target, int* minx, int* miny, int* maxx, int* maxy, double *minval, double *maxval)-{-	CvPoint maxPoint;-	CvPoint minPoint;-	cvMinMaxLoc(target,minval,maxval,&minPoint, &maxPoint, NULL);-    *maxx = maxPoint.x ;-    *maxy = maxPoint.y ;-    *minx = minPoint.x ;-    *miny = minPoint.y ;-} --void simpleMatchTemplate(const IplImage* target, const IplImage* template, int* x, int* y, double *val,int type)-{-	int rw = cvGetSize(target).width-cvGetSize(template).width+1;-	int rh = cvGetSize(target).height-cvGetSize(template).height+1;-	IplImage* result = wrapCreateImage32F(rw,rh,1);-	cvMatchTemplate(target,template,result,type);-	double min,max;-	CvPoint maxPoint;-	maxPoint.x=-1;-	maxPoint.y=-1;-	min =0;-	max =0;-	cvMinMaxLoc(result,&min,&max,NULL, &maxPoint, NULL);-	*x = maxPoint.x;+rw/2;-	*y = maxPoint.y;+rh/2;-	*val = max;-	cvReleaseImage(&result);-	} --IplImage* templateImage(const IplImage* target, const IplImage* template)-{-	int rw = cvGetSize(target).width-cvGetSize(template).width+1;-	int rh = cvGetSize(target).height-cvGetSize(template).height+1;-	IplImage* result = wrapCreateImage32F(rw,rh,1);-	cvMatchTemplate(target,template,result,CV_TM_CCORR);-	return result;-	} ---//@-node:aleator.20050908112116:rendering gabors to arrays-//@+node:aleator.20050908101148:gabor filter using cvFilter2D-void gaborFilter(const CvArr *src, CvArr *dst-                ,int maskWidth, int maskHeight-                ,double stdX, double stdY-                ,double theta,double phase-                ,double cycles)--{- int mx = maskWidth/2;- int my = maskHeight/2;- CvMat *kernel = cvCreateMat(maskWidth,maskHeight,CV_32F);- renderGabor(kernel,maskWidth,maskHeight,mx,my,stdX,stdY-             ,theta,phase,cycles);- cvFilter2D(src,dst,kernel,cvPoint(-1,-1));-}--void radialGaborFilter(const CvArr *src, CvArr *dst-                ,int maskWidth, int maskHeight-                ,double sigma-                ,double phase,double center-                ,double cycles)--{- CvMat *kernel = cvCreateMat(maskWidth,maskHeight,CV_32F);- renderRadialGabor(kernel,maskWidth,maskHeight,sigma-               ,phase,center,cycles);- cvFilter2D(src,dst,kernel,cvPoint(-1,-1));-}---//@-node:aleator.20050908101148:gabor filter using cvFilter2D-//@-node:aleator.20050908112008:Gabors-//@+node:aleator.20070511142414:Adaboost Learning-// This doesn't really work properly yet.. No-// time to do anything about it really.-//@nonl-//@+node:aleator.20070511142414.1:Fitness-// In the following the class is encoded bit-// differently. 0 is one class and +1 is another.-// if target is gray it is considered null area.--double adaFitness1(IplImage *target-                 ,IplImage *weigths-                 ,IplImage *test)-{-CvSize size = cvGetSize(target);-int i,j;-int width  = size.width;-int height = size.height;-double result=0;-double tij=0,wij=0,testij=0,rij=0; -for (i=0; i<width; i++)- for (j=0; j<height; j++)- { -   tij = cvGetReal2D(target,j,i);-   wij = cvGetReal2D(weigths,j,i);-   testij = cvGetReal2D(test,j,i);-   rij=wij;-   if (((tij < 0.2) && (testij < 0.2)) || ((tij > 0.8) && (testij > 0.8))) -    {rij=0;} -   result += rij;- }- -return result;-}-//@-node:aleator.20070511142414.1:Fitness-//@+node:aleator.20070511145251:Updating distributions--// This function is used to update distribution.-// Notice that alpha_t must be calculated separately-// and normalization is not applied.-IplImage* adaUpdateDistrImage(IplImage *target-                          ,IplImage *weigths-                          ,IplImage *test-                          ,double at)-{-CvSize size = cvGetSize(target);-int i,j;-int width  = size.width;-int height = size.height;-double tij=0,wij=0,testij=0,rij=0; -IplImage *result = wrapCreateImage32F(width,height,1);-for (i=0; i<width; i++)- for (j=0; j<height; j++)- { -   tij = cvGetReal2D(target,j,i);-   wij = cvGetReal2D(weigths,j,i);-   testij = cvGetReal2D(test,j,i);-   if ( (tij>0.2) && (tij<0.8) ) continue;-   if (((tij < 0.2) && (testij < 0.2)) -      || ((tij > 0.8) && (testij > 0.8))) -    {rij = wij*exp(-at);-     cvSetReal2D(result,j,i,rij); }-   else -    {rij = wij*exp(at);-     cvSetReal2D(result,j,i,rij); }- }- -return result;-}--//@-node:aleator.20070511145251:Updating distributions-//@-node:aleator.20070511142414:Adaboost Learning-//@+node:aleator.20051207074905:LBP--void get_weighted_histogram(IplImage *src, IplImage *weights, -                       double start, double end, -                       int bins, double *histo)-{-  int i,j,index;-  double value,weight;-  CvSize imageSize = cvGetSize(src);  -  for(i=0;i<bins;++i) histo[i]=0;-  for(i=0; i<imageSize.width-1; ++i)-    for(j=0; j<imageSize.height-1; ++j)-        {-         value = cvGetReal2D(src,j,i);-         weight = cvGetReal2D(weights,j,i);-         index = floor(bins*((value - start)/(end - start)));-         //printf("Adding weight %e to index %d\n",weight,index);-         if (index<0 || index>=bins) continue;-         histo[index] += weight;-        }-  -}--// Calculate local binary pattern for image. -// LBP is outgoing array-// of (preallocated) 256 bytes that are assumed to be 0.-void localBinaryPattern(IplImage *src, int *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=1; i<imageSize.width-1; ++i)-    for(j=1; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);--         pattern += (blurGet2D(src,i-1,j-1) > center) *1;-         pattern += (blurGet2D(src,i,j-1)   > center) *2;-         pattern += (blurGet2D(src,i+1,j-1) > center) *4;-         -         pattern += (blurGet2D(src,i-1,j)   > center) *8;-         pattern += (blurGet2D(src,i+1,j)   > center) *16;-         -         pattern += (blurGet2D(src,i-1,j+1) > center) *32;-         pattern += (blurGet2D(src,i,j+1)   > center) *64;-         pattern += (blurGet2D(src,i+1,j+1) > center) *128;-         LBP[pattern]++;-         pattern = 0;-        }-}--void localBinaryPattern3(IplImage *src, int *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=1; i<imageSize.width-1; ++i)-    for(j=1; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);--         pattern += (blurGet2D(src,i-2,j-2) > center) *1;-         pattern += (blurGet2D(src,i,j-3)   > center) *2;-         pattern += (blurGet2D(src,i+2,j-2) > center) *4;-         -         pattern += (blurGet2D(src,i-3,j)   > center) *8;-         pattern += (blurGet2D(src,i+3,j)   > center) *16;-         -         pattern += (blurGet2D(src,i-2,j+2) > center) *32;-         pattern += (blurGet2D(src,i,j+3)   > center) *64;-         pattern += (blurGet2D(src,i+2,j+2) > center) *128;-         LBP[pattern]++;-         pattern = 0;-        }-}-void localBinaryPattern5(IplImage *src, int *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=1; i<imageSize.width-1; ++i)-    for(j=1; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);--         pattern += (blurGet2D(src,i-4,j-4) > center) *1;-         pattern += (blurGet2D(src,i,j-5)   > center) *2;-         pattern += (blurGet2D(src,i+4,j-4) > center) *4;-         -         pattern += (blurGet2D(src,i-5,j)   > center) *8;-         pattern += (blurGet2D(src,i+5,j)   > center) *16;-         -         pattern += (blurGet2D(src,i-4,j+4) > center) *32;-         pattern += (blurGet2D(src,i,j+5)   > center) *64;-         pattern += (blurGet2D(src,i+4,j+4) > center) *128;-         LBP[pattern]++;-         pattern = 0;-        }-}--void weighted_localBinaryPattern(IplImage *src,int offsetX,int offsetXY-                                , IplImage* weights, double *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  double weight = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=1; i<imageSize.width-1; ++i)-    for(j=1; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);-         weight = cvGetReal2D(weights,j,i);--         pattern += (blurGet2D(src,i-offsetXY,j-offsetXY) > center) *1;-         pattern += (blurGet2D(src,i,j-offsetX)   > center) *2;-         pattern += (blurGet2D(src,i+offsetXY,j-offsetXY) > center) *4;-         -         pattern += (blurGet2D(src,i-offsetX,j)   > center) *8;-         pattern += (blurGet2D(src,i+offsetX,j)   > center) *16;-         -         pattern += (blurGet2D(src,i-offsetXY,j+offsetXY) > center) *32;-         pattern += (blurGet2D(src,i,j+offsetX)   > center) *64;-         pattern += (blurGet2D(src,i+offsetXY,j+offsetXY) > center) *128;-         LBP[pattern] += weight;-         pattern = 0;-        }-}--void localHorizontalBinaryPattern(IplImage *src, int *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=0; i<imageSize.width-1; ++i)-    for(j=0; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);--         pattern += (blurGet2D(src,i-4,j) > center) *1;-         pattern += (blurGet2D(src,i-3,j) > center) *2;-         pattern += (blurGet2D(src,i-2,j) > center) *4;-         pattern += (blurGet2D(src,i-1,j) > center) *8;-         pattern += (blurGet2D(src,i+1,j) > center) *16;-         pattern += (blurGet2D(src,i+2,j) > center) *32;-         pattern += (blurGet2D(src,i+3,j) > center) *64;-         pattern += (blurGet2D(src,i+4,j) > center) *128;-         LBP[pattern]++;-         pattern = 0;-        }-}--void localVerticalBinaryPattern(IplImage *src, int *LBP)-{-  int i,j;-  int pattern = 0;-  double center = 0;-  CvSize imageSize = cvGetSize(src);  -  for(i=0; i<imageSize.width-1; ++i)-    for(j=0; j<imageSize.height-1; ++j)-        {-         center = cvGetReal2D(src,j,i);--         pattern += (blurGet2D(src,i,j-4) > center) *1;-         pattern += (blurGet2D(src,i,j-3) > center) *2;-         pattern += (blurGet2D(src,i,j-2) > center) *4;-         pattern += (blurGet2D(src,i,j-1) > center) *8;-         pattern += (blurGet2D(src,i,j+1) > center) *16;-         pattern += (blurGet2D(src,i,j+2) > center) *32;-         pattern += (blurGet2D(src,i,j+3) > center) *64;-         pattern += (blurGet2D(src,i,j+4) > center) *128;-         LBP[pattern]++;-         pattern = 0;-        }-}---//@-node:aleator.20051207074905:LBP-//@+node:aleator.20051109102750:Selective Average-// Assuming grayscale image calculate local selective average of point x y -inline double calcSelectiveAvg(IplImage *img,double t-                                   ,int x, int y-                                   ,int wwidth, int wheight)-{-int i,j;-double accum=0; -double count=0;-double centerValue; double processed=0;-CvSize size = cvGetSize(img);-centerValue = blurGet2D(img,x,y);--for (i=-wwidth; i<wwidth;++i)- for (j=-wheight; j<wheight;++j)-  { -   if (  x+i<0 || x+i>=size.width-      || y+j<0 || y+j>=size.height)-      continue;-      -   processed = blurGet2D(img,x+i,y+j);-   if (fabs(processed-centerValue)<t)-        {accum+=processed;++count;}-  }-return accum/count;-}---IplImage* selectiveAvgFilter(IplImage *src,double t-                            ,int wwidth, int wheight)-{-CvSize size = cvGetSize(src);-int i,j;-int width  = size.width;-int height = size.height;-double result;--IplImage *target = wrapCreateImage32F(width,height,1);-for (i=0; i<width; i++)- for (j=0; j<height; j++)- {-  result = calcSelectiveAvg(src,t,i,j,wwidth,wheight);-  cvSetReal2D(target,j,i,result);- }- -return target;-}--//@-node:aleator.20051109102750:Selective Average-//@+node:aleator.20060104154125:AcquireImage--// Copy array into single channel iplImage-IplImage *acquireImageSlow(int w, int h, double *d)-{- IplImage *img;- int i,j;- img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);- for (i=0; i<h; i++) {-   for (j=0; j<w; j++) { -         //printf("(%d,%d) => %d is %f\n",j,i,(i+j*h),d[i+j*h]);-         FGET(img,j,i) = d[j*h+i]; -         }-    }- return img;-}--IplImage *acquireImageSlowF(int w, int h, float *d)-{- IplImage *img;- int i,j;- img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);- for (i=0; i<h; i++) {-   for (j=0; j<w; j++) { -         //printf("(%d,%d) => %d is %f\n",j,i,(i+j*h),d[i+j*h]);-         FGET(img,j,i) = d[j*h+i]; -         }-    }- return img;-}--#define BLUE = 0-#define GREEN = 1-#define RED = 2----IplImage *acquireImageSlow8URGB(int w, int h, uint8_t *d)-{- IplImage *img;- int i,j;- img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U,3);- for (i=0; i<h; i++) {-   for (j=0; j<w; j++) { -         UGETC(img,0,j,i) = *d; d++; -         UGETC(img,1,j,i) = *d; d++; -         UGETC(img,2,j,i) = *d; d++; -         }-    }- return img;-}--IplImage *acquireImageSlowComplex(int w, int h, complex double *d)-{- IplImage *img;- int i,j;- img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);- for (i=0; i<h; i++) {-   for (j=0; j<w; j++) { -         FGET(img,j,i) = (float)(creal(d[j*h+i])); -         }-    }- return img;-}--void exportImageSlowComplex(IplImage *img, complex double *d)-{- int i,j;- CvSize s= cvGetSize(img);- for (i=0; i<s.height; i++) {-   for (j=0; j<s.width; j++) { -         d[j*s.height+i] = (complex float)(FGET(img,j,i) + 0*I); -         }-    }-}--void exportImageSlow(IplImage *img, double *d)-{- int i,j;- CvSize s= cvGetSize(img);- for (i=0; i<s.height; i++) {-   for (j=0; j<s.width; j++) { -         d[j*s.height+i] = FGET(img,j,i); -         }-    }-}-void exportImageSlowF(IplImage *img, float *d)-{- int i,j;- CvSize s= cvGetSize(img);- for (i=0; i<s.height; i++) {-   for (j=0; j<s.width; j++) { -         d[j*s.height+i] = FGET(img,j,i); -         }-    }-}-//@-node:aleator.20060104154125:AcquireImage-//@-node:aleator.20050908100314.3:Utilities-//@+node:aleator.20060413093124:Connected components-//@+node:aleator.20071016114634:Contours---void free_found_contours(FoundContours *f)-{- cvReleaseMemStorage(&(f->storage));- free(f);- -}--int reset_contour(FoundContours *f)-{ - f->contour = f->start;-}--int cur_contour_size(FoundContours *f)-{ - return f->contour->total;-}--double contour_area(FoundContours *f)-{ - return cvContourArea(f->contour,CV_WHOLE_SEQ,0);-}--CvMoments* contour_moments(FoundContours *f)-{ - CvMoments* moments = (CvMoments*) malloc(sizeof(CvMoments));- cvMoments(f->contour,moments,0);- return moments;-}--double contour_perimeter(FoundContours *f)-{ - return cvContourPerimeter(f->contour);-}--int more_contours(FoundContours *f)-{ - if (f->contour != 0)-  {return 1;}-  {return 0;} // no more contours-}--int next_contour(FoundContours *f)-{ - if (f->contour != 0)-  {f->contour = f->contour->h_next; return 1;}-  {return 0;} // no more contours-}--void contour_points(FoundContours *f, int *xs, int *ys)-{- if (f->contour==0) {printf("unavailable contour\n"); exit(1);}- - CvPoint *pt=0;- int total,i=0;- total = f->contour->total;- for (i=0; i<total;i++) -  {-   pt = (CvPoint*)cvGetSeqElem(f->contour,i);-   if (pt==0) {printf("point out of contour\n"); exit(1);}-   xs[i] = pt->x;-   ys[i] = pt->y;-  } -    -}--void print_contour(FoundContours *fc)-{-  int i=0;-  CvPoint *pt=0;-   for (i=0; i<fc->contour->total;++i) -    {-     pt = (CvPoint*)cvGetSeqElem(fc->contour,i);-     printf("PT=%d,%d\n",pt->x,pt->y);-    }-}--/* void draw_contour(FoundContours *fc,double color-                 , IplImage *img, IplImage *dst)-{- cvDrawContours( dst, fc->start, color, color, -1, 0, 8-               , cvPoint(0,0));-} */---FoundContours* get_contours(IplImage *src1)-{- CvSize size;- IplImage *src = ensure8U(src1);- //int dstDepth = IPL_DEPTH_8U;- //size = cvGetSize(src1);- //src = cvCreateImage(size,dstDepth,1);- //cvCopy(src1,src,NULL);- - - CvPoint* pt=0;- int i=0;- - CvMemStorage *storage=0;- CvSeq *contour=0;- FoundContours* result = (FoundContours*)malloc(sizeof(FoundContours));- storage = cvCreateMemStorage(0);-       - cvFindContours( src,storage-               , &contour-               , sizeof(CvContour) -               ,CV_RETR_EXTERNAL -            //,CV_RETR_CCOMP -               ,CV_CHAIN_APPROX_NONE-               ,cvPoint(0,0) );--// result->contour = cvApproxPoly( result->contour, sizeof(CvContour)-//                                , result->storage, CV_POLY_APPROX_DP-//                                , 3, 1 );- result->start = contour;- result->contour = contour;- result->storage = storage;-- cvReleaseImage(&src);- return result;-    - }-//@-node:aleator.20071016114634:Contours-//@+node:aleator.20070814123008:moments-CvMoments* getMoments(IplImage *src, int isBinary)-{- CvMoments* moments = (CvMoments*) malloc(sizeof(CvMoments));- cvMoments( src, moments, isBinary);- return moments;-}--void freeCvMoments(CvMoments *x)-{- free(x);-}---void getHuMoments(CvMoments *src,double *hu)-{- CvHuMoments* hu_moments = (CvHuMoments*) malloc(sizeof(CvHuMoments));- cvGetHuMoments( src, hu_moments);- *hu = hu_moments->hu1; ++hu;- *hu = hu_moments->hu2; ++hu;- *hu = hu_moments->hu3; ++hu;- *hu = hu_moments->hu4; ++hu;- *hu = hu_moments->hu5; ++hu;- *hu = hu_moments->hu6; ++hu;- *hu = hu_moments->hu7; - return;-}--void freeCvHuMoments(CvHuMoments *x)-{- free(x);-}-//@-node:aleator.20070814123008:moments-//@+node:aleator.20060727102514:blobCount-int blobCount(IplImage *src)-{-    int contourCount=0;-    CvMemStorage* storage = cvCreateMemStorage(0);-    CvSeq* contour = 0;--    contourCount = cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );--    cvReleaseMemStorage(&storage);-    return contourCount;-}--//@-node:aleator.20060727102514:blobCount-//@+node:aleator.20060413093124.1:sizeFilter-IplImage* sizeFilter(IplImage *src, double minSize, double maxSize)-{-    IplImage* dst = cvCreateImage( cvGetSize(src), IPL_DEPTH_32F, 1 );-    CvMemStorage* storage = cvCreateMemStorage(0);-    CvSeq* contour = 0;--    cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );-    cvZero( dst );--    for( ; contour != 0; contour = contour->h_next )-    {-        double area=fabs(cvContourArea(contour,CV_WHOLE_SEQ,0));-        if (area <=minSize || area >= maxSize) continue;-        CvScalar color = cvScalar(1,1,1,1);-        cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8,-            cvPoint(0,0));-    }-    cvReleaseMemStorage(&storage);-    return dst;-}-//@-node:aleator.20060413093124.1:sizeFilter-//@-node:aleator.20060413093124:Connected components-//@+node:aleator.20050908101148.1:function for rotating image-IplImage* rotateImage(IplImage* src,double scale,double angle)-{--  IplImage* dst = cvCloneImage( src );-  angle = angle * (180 / CV_PI);-  int w = src->width;-  int h = src->height;-  CvMat *M;-  M = cvCreateMat(2,3,CV_32FC1);-  CvPoint2D32f center = cvPoint2D32f(w/2.0,h/2.0);-  CvMat *N = cv2DRotationMatrix(center,angle,scale,M);-  cvWarpAffine( src, dst, N, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS-              , cvScalarAll(0)); -  return dst;-  cvReleaseMat(&M);-}---inline double cubicInterpolate(-   double y0,double y1,-   double y2,double y3,-   double mu)-{-   double a0,a1,a2,a3,mu2;--   mu2 = mu*mu;-   a0 = y3 - y2 - y0 + y1;-   a1 = y0 - y1 - a0;-   a2 = y2 - y0;-   a3 = y1;-   return(a0*mu*mu2+a1*mu2+a2*mu+a3);-}--double bilinearInterp(IplImage *tex, double u, double v) {-   CvSize s = cvGetSize(tex);-   int x = floor(u);-   int y = floor(v);-   double u_ratio = u - x;-   double v_ratio = v - y;-   double u_opposite = 1 - u_ratio;-   double v_opposite = 1 - v_ratio;-   double result = ((x+1 >= s.width) || (y+1 >= s.height)) ? FGET(tex,x,y) :-                   (FGET(tex,x,y)   * u_opposite  + FGET(tex,x+1,y)   * u_ratio) * v_opposite + -                   (FGET(tex,x,y+1) * u_opposite  + FGET(tex,x+1,y+1) * u_ratio) * v_ratio;-   return result;- }--// TODO: Check boundaries! #SAFETY-double bicubicInterp(IplImage *tex, double u, double v) {-   CvSize s = cvGetSize(tex);-   int x = floor(u);-   int y = floor(v);-   double u_ratio = u - x;-   double v_ratio = v - y;-   double p[4][4] = {FGET(tex,x-1,y-1),  FGET(tex,x,y-1),  FGET(tex,x+1,y-1),  FGET(tex,x+2,y-1),-                     FGET(tex,x-1,y),    FGET(tex,x,y),    FGET(tex,x+1,y),    FGET(tex,x+2,y),-                     FGET(tex,x-1,y+1),  FGET(tex,x,y+1),  FGET(tex,x+1,y+1),  FGET(tex,x+2,y+1),-                     FGET(tex,x-1,y+2),  FGET(tex,x,y+2),  FGET(tex,x+1,y+2),  FGET(tex,x+2,y+2)-                     };-    double a00 = p[1][1];-	double a01 = -p[1][0] + p[1][2];-	double a02 = 2*p[1][0] - 2*p[1][1] + p[1][2] - p[1][3];-	double a03 = -p[1][0] + p[1][1] - p[1][2] + p[1][3];-	double a10 = -p[0][1] + p[2][1];-	double a11 = p[0][0] - p[0][2] - p[2][0] + p[2][2];-	double a12 = -2*p[0][0] + 2*p[0][1] - p[0][2] + p[0][3] + 2*p[2][0] - 2*p[2][1] -                 + p[2][2] - p[2][3];-	double a13 = p[0][0] - p[0][1] + p[0][2] - p[0][3] - p[2][0] + p[2][1] - p[2][2] + p[2][3];-	double a20 = 2*p[0][1] - 2*p[1][1] + p[2][1] - p[3][1];-	double a21 = -2*p[0][0] + 2*p[0][2] + 2*p[1][0] - 2*p[1][2] - p[2][0] + p[2][2] -                 + p[3][0] - p[3][2];-	double a22 = 4*p[0][0] - 4*p[0][1] + 2*p[0][2] - 2*p[0][3] - 4*p[1][0] + 4*p[1][1] -                 - 2*p[1][2] + 2*p[1][3] + 2*p[2][0] - 2*p[2][1] + p[2][2] - p[2][3] -                 - 2*p[3][0] + 2*p[3][1] - p[3][2] + p[3][3];-	double a23 = -2*p[0][0] + 2*p[0][1] - 2*p[0][2] + 2*p[0][3] + 2*p[1][0] - 2*p[1][1] -                 + 2*p[1][2] - 2*p[1][3] - p[2][0] + p[2][1] - p[2][2] + p[2][3] + p[3][0] -                 - p[3][1] + p[3][2] - p[3][3];-	double a30 = -p[0][1] + p[1][1] - p[2][1] + p[3][1];-	double a31 = p[0][0] - p[0][2] - p[1][0] + p[1][2] + p[2][0] - p[2][2] - p[3][0] + p[3][2];-	double a32 = -2*p[0][0] + 2*p[0][1] - p[0][2] + p[0][3] + 2*p[1][0] - 2*p[1][1] -                 + p[1][2] - p[1][3] - 2*p[2][0] + 2*p[2][1] - p[2][2] + p[2][3] + 2*p[3][0] -                 - 2*p[3][1] + p[3][2] - p[3][3];-	double a33 = p[0][0] - p[0][1] + p[0][2] - p[0][3] - p[1][0] + p[1][1] - p[1][2] -                 + p[1][3] + p[2][0] - p[2][1] + p[2][2] - p[2][3] - p[3][0] + p[3][1] -                 - p[3][2] + p[3][3];--	double x2 = u_ratio * u_ratio;-	double x3 = x2 * u_ratio;-	double y2 = v_ratio * v_ratio;-	double y3 = y2 * v_ratio;--	return a00 + a01 * v_ratio + a02 * y2 + a03 * y3 +-	       a10 * u_ratio + a11 * u_ratio * v_ratio + a12 * u_ratio * y2 + a13 * u_ratio * y3 +-	       a20 * x2 + a21 * x2 * v_ratio + a22 * x2 * y2 + a23 * x2 * y3 +-	       a30 * x3 + a31 * x3 * v_ratio + a32 * x3 * y2 + a33 * x3 * y3;- }--void radialRemap(IplImage *source, IplImage *dest, double k)-{-    int i,j;-    CvSize s = cvGetSize(dest);-    double x,y,cx,cy,nx,ny,r2;-    cx = s.width/2.0;-    cy = s.height/2.0;-    for (i=0; i<s.height; i++)-       for (j=0; j<s.width; j++) {-           nx = (j-cx)/s.width;-           ny = (i-cy)/s.height;-           r2 = nx*nx+ny*ny;-           nx = nx*(1+k*r2);-           ny = ny*(1+k*r2);-           x = (nx+0.5)*s.width;-           y = (ny+0.5)*s.height;-           if (x<0 || x>=s.width || y<0 || y>=s.height) -            { FGET(dest,j,i) = 0; -             continue;}-           FGET(dest,j,i) = bilinearInterp(source,x,y);-           }---}---//@-node:aleator.20050908101148.1:function for rotating image-//@+node:aleator.20051220091717:Matrix multiplication--void wrapMatMul(int w, int h, double *mat-               , double *vec, double *t)-{--CvMat matrix;-CvMat vector;-CvMat target;-cvInitMatHeader(&matrix,w,h,CV_64FC1,mat,CV_AUTOSTEP);-cvInitMatHeader(&vector,h,1,CV_64FC1,vec,CV_AUTOSTEP);-cvInitMatHeader(&target,w,1,CV_64FC1,t,CV_AUTOSTEP);-cvMatMul(&matrix,&vector,&target);-}--void maximal_covering_circle(int ox,int oy, double or, IplImage *distmap-                            ,int *max_x, int *max_y, double *max_r)-{- double distance,radius;-- *max_x = ox;- *max_y = oy;- *max_r  = or;-- CvSize s = cvGetSize(distmap);- for(int i=0; i<s.width; i++) // TODO: Limit with max_r-  for(int j=0; j<s.height; j++)-   {-    distance = sqrt((i-ox)*(i-ox) + (j-oy)*(j-oy));-    radius   = FGET(distmap,i,j);-    if (radius > *max_r && radius >= or+distance )-         { *max_x=i; *max_y=j; *max_r=radius;}-   }-}--double juliaF(double a, double b,double x, double y) {-     int limit = 1000;-     double complex z;-     int i=0;-     double complex c;-     double cr,ci;-     c = a + b*I;-     z = x+y*I;-     for (i=0;i<limit;i++)-        {-         cr=creal(z); ci=cimag(i);-         if (cr*cr+ci*ci>4) return (i*1.0)/limit;-         z=z*z+c;-        }-    return 0;-    }--CvVideoWriter* wrapCreateVideoWriter(char *fn, int fourcc,-                                     double fps,int w, int h,-                                     int color) - {-   CvVideoWriter *res = cvCreateVideoWriter(fn,CV_FOURCC('M','P','G','4'),fps,cvSize(w,h), color);-   return res;- }--//@-node:aleator.20051220091717:Matrix multiplication-//@-all-//@-node:aleator.20050908100314:@thin cvWrapLEO.c-//@-leo
− CV/cvWrapLEO.h
@@ -1,282 +0,0 @@-//@+leo-ver=4-thin-//@+node:aleator.20050908101148.2:@thin cvWrapLEO.h-//@@language c-#ifndef __CVWRAP__-#define __CVWRAP__--#ifndef M_PI-#define M_PI           3.14159265358979323846-#endif--#include <opencv/cv.h>-#include <opencv/cxcore.h>-#include <opencv/highgui.h>-#include <complex.h>--IplImage* wrapCreateImage32F(const int width, const int height, const int channels);-IplImage* wrapCreateImage64F(const int width, const int height, const int channels);--IplImage* wrapCreateImage8U(const int width, const int height, const int channels);--void wrapSubRS(const CvArr *src, double s,CvArr *dst);-void wrapSubS(const CvArr *src, double s,CvArr *dst);-void wrapAddS(const CvArr *src, double s, CvArr *dst);--double wrapAvg(const CvArr *src);-double wrapStdDev(const CvArr *src);-double wrapStdDevMask(const CvArr *src,const CvArr *mask);-double wrapSum(const CvArr *src);-void wrapMinMax(const CvArr *src,const CvArr *mask-               ,double *minVal, double *maxVal);-void wrapAbsDiffS(const CvArr *src, double s, CvArr *dst);--void wrapSetImageROI(IplImage *i,int x, int y, int w, int h);--IplImage* wrapSobel(IplImage *src,int dx-                   ,int dy,int size);--IplImage* wrapLaplace(IplImage *src,int size);--IplImage* ensure8U(const IplImage *src);-IplImage* ensure32F(const IplImage *src);--void wrapSet32F2D(CvArr *arr, int x, int y, double value);-double wrapGet32F2D(CvArr *arr, int x, int y);-uint8_t wrapGet8U2DC(IplImage *arr, int x, int y,int c);--void wrapDrawCircle(CvArr *img, int x, int y, int radius, float r,float g,float b, int thickness);--void wrapDrawLine(CvArr *img, int x, int y, int x1, int y1, double r, double g, double b, int thickness);--void wrapFillPolygon(IplImage *img, int pc, int *xs, int *ys, float r, float g, float b);--void wrapMatMul(int w, int h, double *mat-               , double *vec, double *t);--// Utils. Place them in another file-IplImage* rotateImage(IplImage* src,double scale,double angle);-CvHistogram* calculateHistogram(IplImage *img,int bins);-void wrapReleaseHist(CvHistogram *hist);-double getHistValue(CvHistogram *h,int bin);-void get_histogram(IplImage *img,IplImage *mask-                 ,float a, float b,int isCumulative-                 ,int binCount-                 ,double *values);--//void get_weighted_histogram(IplImage *img,IplImage *mask);-//                 ,float a, float b-//                 ,int binCount-//                 ,double *values);--IplImage* getSubImage(IplImage *img, int sx,int sy,int w,int h);-int getImageHeight(IplImage *img);-int getImageWidth(IplImage *img);---IplImage* susanSmooth(IplImage *src, int w, int h-                     ,double t, double sigma);--IplImage* susanEdge(IplImage *src,int w,int h,double t);-IplImage* getNthCentralMoment(IplImage *src, int n, int w, int h);-IplImage* getNthAbsCentralMoment(IplImage *src, int n, int w, int h);-IplImage* getNthMoment(IplImage *src, int n, int w, int h);--double calcGabor(double x, double y-                ,double stdX, double stdY-                ,double theta, double phase-                ,double cycles);--void gaborFilter(const CvArr *src, CvArr *dst-                ,int maskWidth, int maskHeight-                ,double stdX, double stdY-                ,double theta,double phase-                ,double cycles);--void radialGaborFilter(const CvArr *src, CvArr *dst-                ,int maskWidth, int maskHeight-                ,double sigma-                ,double phase,double center-                ,double cycles);--void renderRadialGabor(CvArr *dst,int width, int height-                ,double sigma-                ,double phase, double center-                ,double cycles);--void render_gaussian(IplImage *dst-                   ,double stdX, double stdY);--void renderGabor(CvArr *dst,int width, int height-                ,double dx, double dy-                ,double stdX, double stdY-                ,double theta, double phase-                ,double cycles);--void smb(IplImage *image,double t);-void smab(IplImage *image,int w, int h,double t);--IplImage* selectiveAvgFilter(IplImage *src,double t-                            ,int wwidth, int wheight);--IplImage* wrapFilter2D(IplImage *src, int ax,int ay, -                    int w, int h, double *kernel);-IplImage* wrapFilter2DImg(IplImage *src-                         ,IplImage *mask-                         ,int ax,int ay);--void wrapFloodFill(IplImage *i, int x, int y, double c-                  ,double low, double high,int fixed);--void sqrtImage(IplImage *src,IplImage *dst);--void weighted_localBinaryPattern(IplImage *src,int offsetX,int offsetXY-                                , IplImage* weights, double *LBP);--void localBinaryPattern(IplImage *src, int *LBP);-void localBinaryPattern3(IplImage *src, int *LBP);-void localBinaryPattern5(IplImage *src, int *LBP);-void localHorizontalBinaryPattern(IplImage *src, int *LBP);-void localVerticalBinaryPattern(IplImage *src, int *LBP);--void get_weighted_histogram(IplImage *src, IplImage *weights, -                       double start, double end, -                       int bins, double *histo);---void eigenValsViaSVD(double *A, int size, double *eVals-                    ,double *eVects);--IplImage* sizeFilter(IplImage *src, double minSize, double maxSize);-int blobCount(IplImage *src);---IplImage *acquireImage(int w, int h, double *d);--void wrapProbHoughLines(IplImage *img, double rho, double theta-                       , int threshold, double minLength-                       , double gapLength-                       , int *maxLines-                       , int *xs, int *ys-                       , int *xs1, int *ys1);---double average_of_line(int x0, int y0-                     ,int x1, int y1-                     ,IplImage *src);-                     -IplImage* adaUpdateDistrImage(IplImage *target-                          ,IplImage *weigths-                          ,IplImage *test-                          ,double at);--double adaFitness1(IplImage *target-                 ,IplImage *weigths-                 ,IplImage *test);-           -CvMoments* getMoments(IplImage *src, int isBinary);--void freeCvMoments(CvMoments *x);--void getHuMoments(CvMoments *src,double *hu);--void freeCvHuMoments(CvHuMoments *x);--void haarFilter(IplImage *intImg, -                int a, int b, int c, int d,-                IplImage *target);--double haar_at(IplImage *intImg, -                int x1, int y1, int w, int h);--void wrapDrawRectangle(CvArr *img, int x1, int y1, -                       int x2, int y2, float r, float g, float b,-                       int thickness);--void calculateAtan(IplImage *src, IplImage *dst);-void calculateAtan2(IplImage *src1,IplImage *src2, IplImage *dst);---// Contours-typedef struct {-  CvMemStorage *storage;-  CvSeq *contour;-  CvSeq *start;-  -} FoundContours;--CvMoments* contour_moments(FoundContours *f);-void contour_points(FoundContours *f, int *xs, int *ys);-CvMoments* contour_Moments(FoundContours *f);-int cur_contour_size(FoundContours *f);-double contour_area(FoundContours *f);-double contour_perimeter(FoundContours *f);-int more_contours(FoundContours *f);-int next_contour(FoundContours *f);-int reset_contour(FoundContours *f);-void free_found_contours(FoundContours *f);-void get_next_contour(FoundContours *fc);-void print_contour(FoundContours *fc);-FoundContours* get_contours(IplImage *src);--double juliaF(double a, double b,double x, double y);-void simpleMatchTemplate(const IplImage* target, const IplImage* template, int* x, int* y, double *val, int type);-IplImage* templateImage(const IplImage* target, const IplImage* template);-IplImage* simpleMergeImages(IplImage *a, IplImage *b,int offset_x, int offset_y);--void alphaBlit(IplImage *a, IplImage *aAlpha, IplImage *b, IplImage *bAlpha, int offset_x, int offset_y);-void blitImg(IplImage *a, IplImage *b,int offset_x, int offset_y);-IplImage* fadedEdges(int w, int h, int edgeW);-IplImage* rectangularDistance(int w, int h);-void radialRemap(IplImage *source, IplImage *dest, double k);-void plainBlit(IplImage *a, IplImage *b, int offset_y, int offset_x);-void wrapMinMaxLoc(const IplImage* target, int* minx, int* miny, int* maxx, int* maxy, double *minval, double *maxval);-void incrImageC(void);-IplImage* vignettingModelCos4(int w, int h) ;-IplImage* vignettingModelCos4XCyl(int w, int h) ;-IplImage* vignettingModelX2Cyl(int w, int h,double m, double s, double c);-void wrapDrawText(CvArr *img, char *text, float s, int x, int y,float r,float g,float b);--IplImage* vignettingModelB3(int w, int h,double b1, double b2, double b3);-inline CvPoint2D64f toNormalizedCoords(CvSize area, CvPoint from);-inline CvPoint fromNormalizedCoords(CvSize area, CvPoint2D64f from);-inline double eucNorm(CvPoint2D64f p);-IplImage* vignettingModelP(int w, int h,double scalex, double scaley, double max);-IplImage* wrapPerspective(IplImage* src, double a1, double a2, double a3-                                       , double a4, double a5, double a6-                                       , double a7, double a8, double a9);-IplImage* simplePerspective(double k,IplImage *src);-double bilinearInterp(IplImage *tex, double u, double v);-inline CvPoint2D64f fromNormalizedCoords64f(CvSize area, CvPoint2D64f from);-void findHomography(double* srcPts, double *dstPts, int noPts, double *homography);-void masked_merge(IplImage *src1, IplImage *mask, IplImage *src2, IplImage *dst);-IplImage* makeEvenUp(IplImage *src);-IplImage* padUp(IplImage *src,int right, int bottom);-IplImage* makeEvenDown(IplImage *src);-void vertical_average(IplImage *src1, IplImage *dst);--IplImage* composeMultiChannel(IplImage* img0-                             ,IplImage* img1-                             ,IplImage* img2-                             ,IplImage* img3-                             ,const int channels);--IplImage *acquireImageSlow(int w, int h, double *d);-IplImage *acquireImageSlowF(int w, int h, float *d);-void exportImageSlow(IplImage *img, double *d);-void exportImageSlowF(IplImage *img, float *d);--IplImage *acquireImageSlowComplex(int w, int h, complex double *d);-void exportImageSlowComplex(IplImage *img, complex double *d);-void subpixel_blit(IplImage *a, IplImage *b, double offset_y, double offset_x);-double bicubicInterp(IplImage *tex, double u, double v);--CvVideoWriter* wrapCreateVideoWriter(char *fn, int fourcc, double fps,int w, int h, int color); --double wrapGet32F2DC(CvArr *arr, int x, int y,int c);-void maximal_covering_circle(int ox,int oy, double or, IplImage *distmap-                            ,int *max_x, int *max_y, double *max_r);---#endif-//@-node:aleator.20050908101148.2:@thin cvWrapLEO.h-//@-leo
+ Utils/Function.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE PatternGuards #-}+module Utils.Function where++both f (x,y) = (f x, f y)++with f = \x -> (x, f x)++under a b = \x y -> a (b x y)++-- Numerical functions++affine1d (toA,toB) (fromA,fromB) x = x1+    where+     x0 = (x - toA)/(toB-toA)+     x1 = x0*(fromB-fromA) + fromA++mkFst f a = (f a, a)+mkSnd f a = (a, f a)+++-- For Ord. Find a proper location for these++minBy :: (a -> a -> Ordering) -> a -> a -> a+minBy op a b | LT <- op a b = a+             | EQ <- op a b = a+             | GT <- op a b = b++maxBy :: (a -> a -> Ordering) -> a -> a -> a+maxBy op a b | LT <- op a b = b+             | EQ <- op a b = a+             | GT <- op a b = a
+ Utils/List.hs view
@@ -0,0 +1,264 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Utils.List where++import Data.List+import Data.Function+import Data.Maybe+import Control.Arrow ((&&&))+import qualified Data.Map as M+import Test.QuickCheck+++-- | Group list into indevidual pairs: [1,2,3,4] => [(1,2),(3,4)]. +--   Works only with even number of elements+pairs [] = []+pairs [x] = error "Non-even list for pair function"+pairs (x:y:xs) = (x,y):pairs xs++-- | Undo pairs function+fromPairs [] = []+fromPairs ((x,y):xs) = x:y:fromPairs xs++prop_pairsFromTo xs = even (length xs) ==> xs == fromPairs (pairs xs)++-- | Group list into pairs: [1,2,3] => [(1,2),(2,3)]. +--   Works with non null lists++pairs1 x = zip x (tail x)++-- | Undo pairs1 function+fromPairs1 [] = []+fromPairs1 [(x,y)] = [x,y]+fromPairs1 ((x,y):xs) = x:fromPairs1 (xs)++prop_pairsFromTo1 xs = length xs > 1 ==> xs == fromPairs1 (pairs1 xs)++crease op = map (uncurry op) . pairs1+creaseM op = sequence . (crease op)++ranks f xs = map fst $ rankBy f xs++rankBy f xs = map (\(rank,(orig,val)) -> (rank,val))+              . sortBy (compare`on`(fst.snd))+              . zip [1..] +              . sortBy (f`on`snd) +              . zip [1..] +              $ xs++clusterBy :: Ord b => (a -> b) -> [a] -> [[a]]+clusterBy f = M.elems . M.map reverse . M.fromListWith (++)+            . map (f &&& return)+++groupItems b a items = map ( (b . head) &&& map a) +                       . groupBy ((==)`on` b)+                       . sortBy (comparing b) $ items ++-- Assoc-list lookup with default value+lookupDef d a lst = fromMaybe d $ lookup a lst++-- get all consecutive pairs of a list: +--pairings "kissa"+-- => [('k','i'),('i','s'),('s','s'),('s','a')]++pairings [] = []+pairings [x,y] = [(x,y)]+pairings (x:y:ys) = (x,y):pairings (y:ys)++-- Perform an operation for each in lst+forEach fun lst = unfoldr op ([],lst)+    where+     op (start,[]) = Nothing+     op (start,a:as) = Just (start++(fun a):as+                            ,(start++[a],as)) ++forPairs fun lst lst2 = map (map fst) +                         $ forEach (\(a,b)->(fun a b,b))+                         $ zip lst lst2++-- +replicateList n l = concat $ replicate n l+--++concatZipNub (a:as) (b:bs) +    | a == b = a:concatZipNub as bs+    | a /= b = a:b:concatZipNub as bs                    +concatZipNub [] _ = []+concatZipNub _ [] = []++histogram binWidth values = (map len grouped)+    where+     len x = (snap (head x), fromIntegral (length x)) +     min = minimum values+     max = maximum values+     grouped = group sorted+     sorted = sort $ map snap values+     snap x = binWidth*(fromIntegral $ floor (x/binWidth))++binList binWidth op ivs = zip bins (map op values) +    where+     values = map (map snd) grouped+     bins = map (fst.head) grouped +     grouped = groupBy (\(a,_) (b,_) -> a == b ) sorted+     sorted = sortBy (comparing fst) $ map snapIndex ivs+     snapIndex (i,v) = (binWidth*(i`div`binWidth),v)+     +++-- Map numeric list so it becomes zeromean+zeroMean lst = map (\x -> x - mean) lst +    where mean = average lst++-- Take n best elements according to fitnesses++takeNAccordingTo n (fitnesses,elements) = +                take n+              $ sortBy (comparing fst)+              $ zip fitnesses elements++-- Zip two lists by selection function+select c = zipWith (\a b -> if c a b then a else b)++-- Take half++takeHalf lst = take (length lst `div` 2) lst++splitToNParts n lst | n <= 0    = error "splitToNParts n <= 0"+                    | otherwise = takeLengths (lengths (length lst) n) lst+        where+        lengths len n = zipWith (+) (replicate n (len`div`n)) (replicate (len`mod`n) 1++repeat 0)++prop_splitEq n xs = n>0 ==> concat (splitToNParts n xs) == xs+prop_splitLen n xs = n>0 && n<= (length xs) ==> length (splitToNParts n xs) == n++-- Count elements that match predicate p+count p = foldl (\sum i -> if p i then sum+1 else sum) 0 ++-- Count frequencies of elements in list+frequencies lst = map (\x -> (head x,genericLength x)) $ group $ sort lst+normalizeFrequencies ls = map (\(a,b) -> (a,b/sum (map snd ls))) ls+-- Count average of list+average s = sum s / (genericLength $ s) ++-- Take n smallest given op+smallestBy  op n lst = smallestBy' op n lst [] +smallestBy' op n [] o = o+smallestBy' op n (i:input) [] = smallestBy' op n input [i]+smallestBy' op n (i:input) output@(o:os) +     = smallestBy' op n input (take n $ insertBy op i output)+-- (sloppily) Count median of list+median s | odd len = sorted !! middle+         | otherwise = ((sorted !! middle) + +                       (sorted !! (middle -1))) / 2+    where+     middle = len `div` 2+     sorted = sort s+     len = length s++takeTail n lst = reverse $ take n $ reverse lst++-- Count standard deviation of a list +stdDev l = sqrt (sum (map (\x -> (x - avg)^2) l)  +                 / genericLength l)+        where avg = average l++-- Transform a list so that nth element is sum of n first elements+cumulate [] = []+cumulate values = tail $ scanl (+) 0 values++schwartzianTransform :: (Ord a,Ord b) => (a -> b) -> [a] -> [a]+schwartzianTransform f = map snd . sort . map (\x -> (f x, x))++sortVia f = map snd . sortBy cmp . map (\x -> (f x , x))+    where cmp (a1,a2) (b1,b2) = compare a1 b1++comparing p a b = compare (p a) (p b)++-- Pick element that has majority in the list+majority lst = head $ maximumBy (comparing length) $ group $ sort lst++-- Get all possible k-sized neighbourhoods in the list+getKNeighbourhoods k p = get (length p) pknot+    where +        pknot = p++pknot+        get 0 p = []+        get i p = take k p:get (i-1) (tail p)++prop_headIdentical_KN n xs = 1 <= n && length xs >= 1 ==>+                    map head (getKNeighbourhoods n xs)+                    ==+                    xs++-- Split a list to `l` length pieces.+splitToLength l lst = unfoldr split lst+    where+     split [] = Nothing+     split lst = Just (take l lst, drop l lst) ++-- Take n pieces of given lengths+--takeLengths :: [Int] -> [a] -> [[a]]+takeLengths [] lst = []+takeLengths (l:ls) lst = take l lst:takeLengths ls (drop l lst) ++prop_takeLen ls xs = all (>=0) ls &&  sum ls < length xs ==> length (takeLengths ls xs) == length ls+prop_takeLens ls xs = all (>=0) ls &&  sum ls < length xs ==> map length (takeLengths ls xs) == ls++-- From LicencedPreludeExts (hawiki)+splitBy :: (a->Bool) -> [a] -> [[a]]+splitBy _ [] = []+splitBy f list =  first : splitBy f (dropWhile f rest)+   where+     (first, rest) = break f list++--splitBetween :: ((a,a) -> Bool) -> [a] -> [[a]]+splitBetween c acc [] = [reverse acc] +splitBetween c acc [a] = [reverse $ a:acc] +splitBetween c acc (a:b:cs) | c a b = (reverse $ a:acc):splitBetween c [] (b:cs)+                            | otherwise = splitBetween c (a:acc) (b:cs)++-- split list into subsets matching predicate+tear op l = (filter (not.op) l, filter op l)++swapEverywhere a b = concat $ zipWith merge (inits a) (tails a)+    where+     merge i [] = []+     merge i (t:ts) = map (\x -> i++[x]++ts) b+++takeWhile2 op lst = reverse $ tw op [head lst] (tail lst)+ where+    tw _  l [] = []+    tw op l (x:xs) = if op (head l) x +                              then tw op (x:l) xs+                              else l++applyMap val ops = map (\op -> op val) ops +applyMapM :: (Monad m) => a -> [a -> m b] -> m [b]+applyMapM val ops = mapM (\op -> op val) ops +changesM :: (Monad m) => [a -> m b] -> a -> m [b]+changesM = flip applyMapM++rollList (a:xs) = xs ++[a]+roll = rollList++mergeList a b = a ++ drop (length a) b++takeWhile1 test [] = []+takeWhile1 test (x:xs) | test x = x:takeWhile1 test xs+                       | otherwise =  [x]+++-- Modify each element in list with function that has knowledge of already+-- modified elements+editingMap f l = editingTrav f [] l++editingTrav fun [] l@(x:xs) = editingTrav fun [(fun l x)] xs+editingTrav fun a [] = reverse a+editingTrav fun ss l@(x:xs) = editingTrav fun+                                         (fun (reverse ss++l) x:ss)+                                         xs+++-- Rotations of list+rotate (x:xs) = xs++[x]+cycles x = take (length x) $ iterate rotate x
+ Utils/Point.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}+module Utils.Point where++type Pt a = (a,a)++instance Num a => Num (Pt a) where+    (x1,x2) + (y1,y2) = (x1+y1,x2+y2) +    (x1,x2) * (y1,y2) = (x1*y1,x2*y2) +    (x1,x2) - (y1,y2) = (x1-y1,x2-y2) +    negate (x1,x2) = (negate x1,negate x2) +    abs (x1,x2) = (abs x1, abs x2) -- Not really mathematical, but the type must be same+    signum (x1,x2) = (signum x1, signum x2) -- Ditto+    fromInteger x = (fromInteger x,fromInteger x) -- As well++norm2 :: (Num a) => Pt a -> a+norm2 (a,b) = a*a+b*b++norm = sqrt . norm2++(a,b) >/ (c,d) = (a `div` c, b `div` d)
+ Utils/Rectangle.hs view
@@ -0,0 +1,120 @@+module Utils.Rectangle where+import Test.LazySmallCheck++import Utils.Point+import Control.DeepSeq++newtype Rectangle a = Rectangle ((a,a),(a,a)) deriving (Eq,Show)++a `s` b = rnf a `seq` b ++instance (NFData a) => NFData (Rectangle a) where+    rnf (Rectangle ((a,b),(c,d))) = (a `s` b `s` c `s` d) `seq` ()++left   (Rectangle ((x,y),(w,h))) = x+right  (Rectangle ((x,y),(w,h))) = x+w+top    (Rectangle ((x,y),(w,h))) = y+bottom (Rectangle ((x,y),(w,h))) = y+h+topLeft  (Rectangle ((x,y),(w,h))) = (x,y)+topRight (Rectangle ((x,y),(w,h))) = (x+w,y)  +bottomLeft (Rectangle ((x,y),(w,h))) = (x,y+h)  +bottomRight (Rectangle ((x,y),(w,h))) = (x+w,y+h)  +vertices r = [topLeft r, topRight r, bottomLeft r, bottomRight r]+rSize (Rectangle ((x,y),(w,h))) = (w,h)+rArea r = let (w,h) = rSize r in (w*h)++-- TODO: Add documentation #Cleanup++instance (Num a, Ord a , Serial a) => Serial (Rectangle a) where+    series = cons4 $ \a b c d -> mkRectangle (a,b) (c,d)++-- | Create rectangle around point (x,y)+around (x,y) (w,h) = mkRectangle (x', y') (w,h)+    where (x',y') = (x-(w/2),y-(h/2))++mkRectangle (x,y) (w,h) = Rectangle ((x-negW,y-negH),(abs w,abs h))+    where+     negH | h<0  = abs h+          | h>=0 = 0+     negW | w<0  = abs w+          | w>=0 = 0++mkRectCorners (x1,y1) (x2,y2) = Rectangle ((x,y),(w,h))+ where+    x = min x1 x2+    y = min y1 y2+    w = abs (x1-x2)+    h = abs (y1-y2)++prop_Corners :: (Int,Int) -> (Int,Int) -> Bool+prop_Corners p w = mkRectCorners p (p+w) == mkRectangle p w++mkRec = uncurry mkRectangle++-- | Return rectangle r2 in coordinate system defined by r1+inCoords r1 r2@(Rectangle (pos,size)) = Rectangle (pos-topLeft r1,size )++-- | Return a point in coordinates of given rectangle+inCoords' r1 pt = pt - topLeft r1++-- | Adjust the size of the rectangle to be divisible by 2^n.+enlargeToNthPower n (Rectangle ((x,y),(w,h))) = Rectangle ((x,y),(w2,h2))+    where+     (w2,h2) = (pad w, pad h)+     pad x = x + (np - x `mod` np)+     np = 2^n++intersection r1 r2 +    = mkRectCorners (max (left r1)   (left r2)+                    ,max (top r1)    (top r2))+                    (min (right r1)  (right r2)+                    ,min (bottom r1) (bottom r2))++propIntersectionArea r1 r2 +    = (intersects r1 r2) +       ==> rArea (intersection r1 r2) <= rArea r1 &&+           rArea (intersection r1 r2) <= rArea r2++propIntersectionCommutes r1 r2 +    = (intersects r1 r2) +       ==> (intersection r1 r2) == (intersection r2 r1) ++intersects rect1 rect2 +    = intersect1D (left rect1, right rect1) (left rect2, right rect2) && +      intersect1D (top rect1, bottom rect1) (top rect2, bottom rect2)++contains a b = left a <= left b +                && top a <= top b +                && bottom a >= bottom b+                && right a >= right b++intersect1D (x,y) (u,w) = +    not $ (x < min u w && y < min u w) || (x > max u w && y > max u w) ++prop_intersect1DCommutes a b +    = intersect1D  a b == intersect1D b a++prop_intersectsCommutes sa@(_,(s1,s2)) sb@(b,(s3,s4)) +    = intersects (mkRec sa) (mkRec sb) == intersects (mkRec sb) (mkRec sa)++-- | Create a tiling of a rectangles. +tile tilesize overlap r = [mkRectangle ((x,y)-overlap) tilesize +                          | x <- [startx,startx+fst tilesize..endx]+                          , y <- [starty,starty+fst tilesize..endy] ]+    where+     startx = left r-fst overlap+     starty = top  r-snd overlap+     endx = right  r+fst overlap+     endy = bottom r+snd overlap++-- | Scale a rectangle+scale (a,b) (Rectangle ((x,y),(s1,s2))) +    = mkRectangle (round (a*fromIntegral x),round (b*fromIntegral y))+                  (round (a*fromIntegral s1),round (b*fromIntegral s2))+++toInt (Rectangle (p, s)) +    = Rectangle (both round p +                ,both round s)+ where both f (a,b) = (f a , f b)+
+ Utils/Stream.hs view
@@ -0,0 +1,185 @@+module Utils.Stream where+import Control.Applicative+import Control.Monad+import Control.Monad.Trans++-- This module provides Monadic streams.++-- | Stream of monadic values+data Stream m a = Terminated | Value (m (a,Stream m a))++-- | Attaching side effects+sideEffect :: (Monad m) => (a -> m ()) -> Stream m a -> Stream m a+sideEffect p Terminated = Terminated+sideEffect p (Value next) = Value renext+	where +	  renext = do+                (r,n) <- next+                p r+                return (r,sideEffect p n)++-- | Repeating stream+listToStream [] = Terminated+listToStream (l:lst) = Value (return (l,listToStream lst))+repeatS x = Value (return (x,repeatS x))+repeatSM x = sequenceS (repeatS x) +-- | Create a stream by iterating a monadic action+iterateS op n = Value cont+	where +         cont = do+		 r <- op n+		 return $ (n,iterateS op r) ++-- | Pure and monadic left fold over a stream+foldS op i Terminated = return i+foldS op i (Value xs) = xs >>= \(x,xn) -> foldS op (op i x) xn++foldSM op i Terminated = return i+foldSM op i (Value xs) = xs >>= \(x,xn) -> op i x >>= \opix -> foldSM op opix xn++-- | Merge two (time)streams+time (a,_) = a+value (_,a) = a+mergeTimeStreams starta startb  a b = mergeE (starta,startb) (mergeS a b)+mergeTimeStreamsWith sa sb op a b = fmap (\(t,(a,b)) -> (t,(op a b))) $ mergeTimeStreams sa sb a b+mergeManyW starts op streams = snd $ foldl1 (\(s,m) (s1,n) -> ((op s s1),mergeTimeStreamsWith s s1 op m n)) (zip starts streams)++mergeS Terminated _ = Terminated+mergeS _ Terminated = Terminated+mergeS _ Terminated = Terminated+mergeS (Value xs) (Value ys) = Value renext+    where+        renext = do+            (x,xn) <- xs+            (y,yn) <- ys+            case compare (time x) (time y) of+                LT -> return (L x,mergeS xn (push y yn))+                EQ -> return (B (time x,(value x,value y)),mergeS xn yn)+                GT -> return (R y,mergeS (push x xn) yn)++data LRB a b c = L a | B b |  R c  deriving (Show)++mergeE _ Terminated = Terminated+mergeE (l,r) (Value xs) = Value renext+    where+        renext = do+                   (x,xn) <- xs+                   case x of+                    L (t,a) -> return ((t,(a,r)),mergeE (a,r) xn)+                    B (t,(a,b)) -> return ((t,(a,b)),mergeE (a,b) xn)+                    R (t,b) -> return ((t,(l,b)),mergeE (l,b) xn)++push x Terminated = Value (return (x,Terminated))+push x xs = Value (return (x,xs))+ ++-- | Map over a stream+instance (Monad m) => Functor (Stream m) where+    fmap _ Terminated   = Terminated+    fmap f (Value next) = Value renext+	where +	  renext = do+		    (r,n) <- next+		    return (f r,fmap f n)++instance (Monad m) => Applicative (Stream m) where+    pure f  = repeatS f+    Terminated <*> _ = Terminated+    _ <*> Terminated = Terminated+    (Value a) <*> (Value b) = Value renext +      where +      renext = do+        (fun,anext) <- a+        (br,bnext)  <- b+        return (fun br,anext<*>bnext)+		+zipS a b = (,) <$> a <*> b+                +--+sequenceS :: (Monad m) => Stream m (m a) -> (Stream m a)+sequenceS Terminated = Terminated+sequenceS (Value next) = Value $ do+			    (op,n) <- next+			    r <- op	+		            return (r,sequenceS n)++mapMS :: (Monad m) => (a -> m b) -> Stream m a -> Stream m b+mapMS op s = sequenceS . fmap op $ s++-- |Drop elements from the stream. Due to stream structure, this operation cannot+--  fail gracefully when dropping more elements than what is found in the stream+dropS :: (Monad m) => Int -> Stream m a -> Stream m a+dropS _ Terminated = Terminated+dropS n next = Value renext+	where+         drop 0 s = return s+         drop _ Terminated = return Terminated+         drop n (Value next) =  do+            (r,ne) <- next +            drop (n-1) ne+         renext = do+            r <- drop n next+            case r of+                Terminated -> error "Not enough elements to drop"+                Value x -> x++takeS :: (Monad m) => Int -> Stream m a -> Stream m a+takeS _ Terminated = Terminated+takeS n (Value next) = Value renext+	where+         renext = do+		   (r,ne) <- next+		   if n<1 then return (r,Terminated)+		   	     else return (r,takeS (n-1) ne)++takeWhileS _ Terminated = Terminated+takeWhileS c (Value next) = Value renext+	where+         renext = do+		   (r,ne) <- next+		   if not . c $ r then return (r,Terminated)+		   	      else return (r,takeWhileS c ne)++consS a Terminated = Value (return (a, Terminated))+consS a s  = Value (return (a, s))++-- pairS is safe only for infinite streams+pairS :: (Monad m) => Stream m a -> Stream m (a,a)+pairS Terminated = Terminated+pairS (Value next) = Value renext+	where+         renext = do+            (val1,nexts2) <- next+            case nexts2 of+                Terminated    -> return (undefined,Terminated)+                (Value next2) -> do (val2,next3) <- next2+                                    return ((val1,val2),pairS (consS val2 next3))+++terminateOn :: (Monad m) => (a -> Bool) -> Stream m a -> Stream m a+terminateOn cond Terminated = Terminated+terminateOn cond (Value next) = Value renext+	where+         renext = do+		   (r,n) <- next+		   if cond r then return (r,Terminated)+		   	     else return (r,terminateOn cond n)++runStream Terminated  = return []+runStream (Value s) = do+			 (n,next) <- s+			 r<-runStream next+			 return (n:r)++runStream_ Terminated  = return ()+runStream_ (Value s) = do+			 (n,next) <- s+			 runStream_ next++runLast l Terminated  = return l+runLast l (Value s) = do+   	 (n,next) <- s+   	 runLast n next++runLast1 s = runLast (error "Empty Stream") s+			 
+ cbits/cvWrapLEO.c view
@@ -0,0 +1,2344 @@+//@+leo-ver=4-thin+//@+node:aleator.20050908100314:@thin cvWrapLEO.c+//@@language c++//@+all+//@+node:aleator.20050908100314.1:Includes+#include "cvWrapLEO.h"+#include <stdio.h>+#include <complex.h>+#include <stdint.h>++//@-node:aleator.20050908100314.1:Includes+//@+node:aleator.20050908100314.2:Wrappers++#define FGET(img,x,y) (((float *)((img)->imageData + (y)*(img)->widthStep))[(x)])+#define UGETC(img,color,x,y) (((uint8_t *)((img)->imageData + (y)*(img)->widthStep))[(x)*3+(color)])++size_t images;++void incrImageC(void)+{+ images++;+}++void wrapReleaseImage(IplImage *t)+{+ // printf("%d ",images);+ cvReleaseImage(&t);+ images--;+}++void wrapReleaseCapture(CvCapture *t)+{+ cvReleaseCapture(&t);+}++void wrapReleaseVideoWriter(CvCapture *t)+{+ cvReleaseCapture(&t);+}++void wrapReleaseStructuringElement(IplConvKernel *t)+{+ cvReleaseStructuringElement(&t);+}++IplImage* wrapLaplace(IplImage *src,int size)+{+IplImage *res;+IplImage *tmp;+tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,1);+res = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);+cvLaplace(src,tmp,size);+cvConvertScale(tmp,res,1,0);+return res;+}++IplImage* wrapSobel(IplImage *src,int dx+                   ,int dy,int size)+{+IplImage *res;+IplImage *tmp;+tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,1);+res = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);+cvSobel(src,tmp,dx,dy,size);+cvConvertScale(tmp,res,1,0);+cvReleaseImage(&tmp);+return res;+}++IplImage* wrapCreateImage32F(const int width+                         ,const int height+                         ,const int channels)+{+ CvSize s;+ IplImage *r;+ s.width = width; s.height = height;+ r = cvCreateImage(s,IPL_DEPTH_32F,channels);+ cvSetZero(r);+ return r;+}++IplImage* wrapCreateImage64F(const int width+                         ,const int height+                         ,const int channels)+{+ CvSize s;+ IplImage *r;+ s.width = width; s.height = height;+ r = cvCreateImage(s,IPL_DEPTH_64F,channels);+ cvSetZero(r);+ return r;+}+++IplImage* wrapCreateImage8U(const int width+                         ,const int height+                         ,const int channels)+{+ CvSize s;+ IplImage *r;+ s.width = width; s.height = height;+ r = cvCreateImage(s,IPL_DEPTH_8U,channels);+ cvSetZero(r);+ return r;+}++IplImage* composeMultiChannel(IplImage* img0+                             ,IplImage* img1+                             ,IplImage* img2+                             ,IplImage* img3+                             ,const int channels)+{+ CvSize s;+ IplImage *r;+ s = cvGetSize(img0);+ r = cvCreateImage(s,img0->depth,channels);+ cvSetZero(r);+ cvMerge(img0,img1,img2,img3,r);+ return r;+}+void wrapSubRS(const CvArr *src, double s, CvArr *dst)+{+ cvSubRS(src,cvRealScalar(s),dst,0);+}++void wrapSubS(const CvArr *src, double s, CvArr *dst)+{+ cvSubS(src,cvRealScalar(s),dst,0);+}++void wrapAddS(const CvArr *src, double s, CvArr *dst)+{+ cvAddS(src,cvRealScalar(s),dst,0);+}++void wrapAbsDiffS(const CvArr *src, double s, CvArr *dst)+{+ cvAbsDiffS(src,dst,cvScalarAll(s));+}++double wrapAvg(const CvArr *src)+{+ CvScalar avg = cvAvg(src,0);+ return avg.val[0];+}++double wrapStdDev(const CvArr *src)+{+ CvScalar dev;+ cvAvgSdv(src,0,&dev,0);+ return dev.val[0];+}++double wrapStdDevMask(const CvArr *src,const CvArr *mask)+{+ CvScalar dev;+ IplImage *mask8 = ensure8U(mask);+ cvAvgSdv(src,0,&dev,mask8);+ cvReleaseImage(&mask8); + return dev.val[0];+}+double wrapMeanMask(const CvArr *src,const CvArr *mask)+{+ CvScalar mean;+ IplImage *mask8 = ensure8U(mask);+ cvAvgSdv(src,&mean,0,mask8);+ cvReleaseImage(&mask8); + return mean.val[0];+}++double wrapSum(const CvArr *src)+{+ CvScalar sum = cvSum(src);+ return sum.val[0];+}++void wrapMinMax(const CvArr *src,const CvArr *mask+               ,double *minVal, double *maxVal)+{+ //cvMinMaxLoc(src,minVal,maxVal,NULL,NULL,NULL);+ int i,j;+ int minx,miny,maxx,maxy;+ double pixel;+ double maskP;+ int t;+ double min=100000,max=-100000; // Some problem with DBL_MIN.++ CvSize s = cvGetSize(src);+ for(i=0; i<s.width; i++)+  for(j=0; j<s.height; j++)+   {+   pixel = cvGetReal2D(src,j,i);+   maskP = mask != 0 ? cvGetReal2D(mask,j,i) : 1;+   // TODO: Fix below.. +   min   = (maskP >0.5 ) && (pixel < min) ? pixel : min; +   max   = (maskP >0.5 ) && (pixel > max) ? pixel : max; +   }+ (*minVal) = min; (*maxVal) = max; +}++void wrapSetImageROI(IplImage *i,int x, int y, int w, int h)+{+ CvRect r = cvRect(x,y,w,h);+ cvSetImageROI(i,r);+}+++// Return image that is IPL_DEPTH_8U version of +// given src+IplImage* ensure8U(const IplImage *src)+{+ CvSize size;+ IplImage *result;+ int channels = src->nChannels;+ int dstDepth = IPL_DEPTH_8U;+ size = cvGetSize(src);+ result = cvCreateImage(size,dstDepth,channels);++ switch(src->depth) {+  case IPL_DEPTH_32F:+  case IPL_DEPTH_64F:+   cvConvertScale(src,result,255.0,0); // Scale the values to [0,255]+   return result;+  case IPL_DEPTH_8U:+   cvConvertScale(src,result,1,0);+   return result;+  default:+   printf("Cannot convert to floating image");+   abort();+   + }+}++// Return image that is IPL_DEPTH_32F version of +// given src+IplImage* ensure32F(const IplImage *src)+{+ CvSize size;+ IplImage *result;+ int channels = src->nChannels;+ int dstDepth = IPL_DEPTH_32F;+ size = cvGetSize(src);+ result = cvCreateImage(size,dstDepth,channels);++ switch(src->depth) {+  case IPL_DEPTH_32F:+  case IPL_DEPTH_64F:+   cvConvertScale(src,result,1,0); // Scale the values to [0,255]+   return result;+  case IPL_DEPTH_8U:+  case IPL_DEPTH_8S:+   cvConvertScale(src,result,1.0/255.0,0);+   return result;+  case IPL_DEPTH_16S:+   cvConvertScale(src,result,1.0/65535.0,0);+   return result;+  case IPL_DEPTH_32S:+   cvConvertScale(src,result,1.0/4294967295.0,0);+   return result;+  default:+   printf("Cannot convert to floating image");+   abort();+   + }+}++void wrapSet32F2D(CvArr *arr, int x, int y, double value)+{ + cvSet2D(arr,x,y,cvRealScalar(value)); +}+++double wrapGet32F2D(CvArr *arr, int x, int y)+{ + CvScalar r;+ r = cvGet2D(arr,x,y); + return r.val[0];+}++double wrapGet32F2DC(CvArr *arr, int x, int y,int c)+{ + CvScalar r;+ r = cvGet2D(arr,x,y); + return r.val[c];+}++uint8_t wrapGet8U2DC(IplImage *arr, int x, int y,int c)+{ + return UGETC(arr,c,y,x);+}+++void wrapDrawCircle(CvArr *img, int x, int y, int radius, float r,float g,float b, int thickness)+{+ cvCircle(img,cvPoint(x,y),radius,CV_RGB(r,g,b),thickness,8,0);+}++void wrapDrawText(CvArr *img, char *text, float s, int x, int y,float r,float g,float b)+{+CvFont font; //?+cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, s, s, 0, 2, 8);+cvPutText(img, text, cvPoint(x,y), &font, CV_RGB(r,g,b));+}++void wrapDrawRectangle(CvArr *img, int x1, int y1, +                       int x2, int y2, float r, float g, float b,+                       int thickness)+{+ cvRectangle(img,cvPoint(x1,y1),cvPoint(x2,y2),CV_RGB(r,g,b),thickness,8,0);+}+++void wrapDrawLine(CvArr *img, int x, int y, int x1, int y1, double r, double g, double b, int thickness)+{+ cvLine(img,cvPoint(x,y),cvPoint(x1,y1),CV_RGB(r,g,b),thickness,4,0);+}++void wrapFillPolygon(IplImage *img, int pc, int *xs, int *ys, float r, float g, float b)+{ + int i=0;+ int pSizes[] = {pc};+ CvPoint *pts = (CvPoint*)malloc(pc*sizeof(CvPoint));+ for (i=0; i<pc; ++i)+    {pts[i].x = xs[i]; +     pts[i].y = ys[i]; +     }+ cvFillPoly(img, &pts, pSizes, 1, CV_RGB(r,g,b), 8, 0 );+ free(pts);+}++++int getImageWidth(IplImage *img)+{+ return cvGetSize(img).width;+}+int getImageHeight(IplImage *img)+{+ return cvGetSize(img).height;+}++IplImage* getSubImage(IplImage *img, int sx,int sy,int w,int h)+{+ CvRect r;+ CvSize s;+ IplImage *newImage;+ + r.x = sx; r.y = sy;+ r.width = w; r.height = h;+ s.width = w; s.height = h;+ + cvSetImageROI(img,r);+ newImage = cvCreateImage(s,img->depth,img->nChannels);+ cvCopy(img, newImage,0);+ cvResetImageROI(img);+ return newImage;+}++IplImage* simpleMergeImages(IplImage *a, IplImage *b,int offset_x, int offset_y)+{+ CvSize aSize = cvGetSize(a);+ CvSize bSize = cvGetSize(b);+ int startx = 0 < offset_x ? 0 : offset_x;+ int endx = aSize.width > bSize.width+offset_x ? aSize.width : bSize.width+offset_x ;++ int starty = 0 < offset_y ? 0 : offset_y;+ int endy = aSize.height > bSize.height+offset_y ? aSize.height : bSize.height+offset_y ;++ CvSize size;+ size.width  = endx-startx;+ size.height = endy-starty;++ CvRect aPos = cvRect(offset_x<0?-offset_x:0+                     ,offset_y<0?-offset_y:0+                     ,aSize.width+                     ,aSize.height);++ CvRect bPos = cvRect(offset_x<0?0:offset_x+                     ,offset_y<0?0:offset_y+                     ,bSize.width+                     ,bSize.height);++ IplImage *resultImage = cvCreateImage(size,a->depth,a->nChannels);++ // Blit the images into bigger result image using cvCopy+ cvSetImageROI(resultImage,aPos);+ cvCopy(a,resultImage,NULL);+ cvSetImageROI(resultImage,bPos);+ cvCopy(b,resultImage,NULL);+ cvResetImageROI(resultImage);+ return resultImage;+}++void blitImg(IplImage *a, IplImage *b,int offset_x, int offset_y)+{+ CvSize bSize = cvGetSize(b);+ CvRect pos = cvRect(offset_x+                    ,offset_y+                    ,bSize.width+                    ,bSize.height);++ // Blit the images b into a using cvCopy+ printf("Doing a blit\n"); fflush(stdout);+ cvSetImageROI(a,pos);+ cvCopy(b,a,NULL);+ cvResetImageROI(a);+ printf("Done!\n"); fflush(stdout);+}++IplImage* makeEvenDown(IplImage *src)+{+ CvSize size = cvGetSize(src);+ int w = size.width-(size.width % 2);+ int h = size.height-(size.height % 2);+ IplImage *result = wrapCreateImage32F(w,h,1);    + CvRect pos = cvRect(0+                    ,0+                    ,size.width+                    ,size.height);+ // Blit the images b into a using cvCopy+ cvSetImageROI(src,pos);+ cvCopy(src,result,NULL);+ cvResetImageROI(result);+ return result;+}++IplImage* makeEvenUp(IplImage *src)+{+ CvSize size = cvGetSize(src);+ int w = size.width+(size.width % 2);+ int h = size.height+(size.height % 2);+ int j;+ IplImage *result = wrapCreateImage32F(w,h,1);    + CvRect pos = cvRect(0+                    ,0+                    ,size.width+                    ,size.height);+ // Blit the images b into a using cvCopy+ cvSetImageROI(result,pos);+ cvCopy(src,result,NULL);+ cvResetImageROI(result);+ if (size.width % 2 == 1)+      {for (j=0; j<=size.height; j++) {+          FGET(result,size.width,j) = FGET(result,size.width-1,j); } }+ if (size.width % 2 == 1)+      {for (j=0; j<=size.width; j++) {+          FGET(result,j,(size.height)) = FGET(result,j,(size.height-1)); } }+ return result;+}++IplImage* padUp(IplImage *src,int right, int bottom)+{+ CvSize size = cvGetSize(src);+ int w = size.width + (right  ? 1 : 0);+ int h = size.height+ (bottom ? 1 : 0);+ int j;+ IplImage *result = wrapCreateImage32F(w,h,1);    + CvRect pos = cvRect(0+                    ,0+                    ,size.width+                    ,size.height);+ // Blit the images b into a using cvCopy+ cvSetImageROI(result,pos);+ cvCopy(src,result,NULL);+ cvResetImageROI(result);+ if (right)+      {for (j=0; j<=size.height; j++) {+          FGET(result,size.width,j) = 2*FGET(result,size.width-1,j)+                                       -FGET(result,size.width-2,j); } }+ if (bottom)+      {for (j=0; j<=size.width; j++) {++          FGET(result,j,(size.height)) = 2*FGET(result,j,(size.height-1))+                                          -FGET(result,j,(size.height-2)); +                                          } }+ return result;+}++void masked_merge(IplImage *src1, IplImage *mask, IplImage *src2, IplImage *dst)+{+ int i,j;+ CvSize size = cvGetSize(dst);+ for (i=0; i<size.width; i++)+    for (j=0; j<size.height; j++) {+       FGET(dst,i,j) =  FGET(src1,i,j)*FGET(mask,i,j) +                        +FGET(src2,i,j)*(1-FGET(mask,i,j));+     }+}++void vertical_average(IplImage *src, IplImage *dst)+{+ int i,j;+ double avg;+ CvSize size = cvGetSize(dst);+ for (i=0; i<size.width; i++) {+    avg = 0;+    for (j=0; j<size.height; j++) { avg += FGET(src,i,j); }+    avg = avg / size.height;+    for (j=0; j<size.height; j++) { FGET(dst,i,j) = avg; }+    }+}+++IplImage* fadedEdges(int w, int h, int edgeW) {+    IplImage *result;+    int i,j;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+           float dx = i < (h/2.0) ? i : h-i ;+           float dy = j < (w/2.0) ? j : w-j ;+           float x = dx > edgeW ? 1 : dx/edgeW;+           float y = dy > edgeW ? 1 : dy/edgeW;+           FGET(result,j,i) = x*y;+           }+    return result;+}++IplImage* rectangularDistance(int w, int h) {+    IplImage *result;+    int i,j;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+           float dx = i < (h/2.0) ? i/(h*1.0) : (h-i)/(h*1.0) ;+           float dy = j < (w/2.0) ? j/(w*1.0) : (w-j)/(w*1.0) ;+           FGET(result,j,i) = dx<dy?dx:dy;+           }+    return result;+}+IplImage* vignettingModelCos4(int w, int h) {+    IplImage *result;+    int i,j;+    double nx,ny;+    double r;+    const double x0 = w/2.0;+    const double y0 = h/2.0;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+            nx = (y0-i)/h;+            ny = (x0-j)/w;+            r = sqrt(nx*nx+ny*ny);+            FGET(result,j,i) = pow(cos (r),4);+           }+    return result;+}++IplImage* vignettingModelCos4XCyl(int w, int h) {+    IplImage *result;+    int i,j;+    double r;+    const double x0 = w/2.0;+    const double y0 = h/2.0;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+            r = fabs((i-y0)/y0) ;+            FGET(result,j,i) = pow(cos (r),4);+           }+    return result;+}++IplImage* vignettingModelX2Cyl(int w, int h,double m, double s, double c) {+    IplImage *result;+    int i,j;+    double r;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+            FGET(result,j,i) = -((i-c)*s)*((i-c)*s)-m;+           }+    return result;+}+inline double eucNorm(CvPoint2D64f p) {return (p.x*p.x+p.y*p.y);}++IplImage* vignettingModelB3(int w, int h,double b1, double b2, double b3) {+    IplImage *result;+    int i,j;+    double r;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+            CvPoint2D64f nor = toNormalizedCoords(cvSize(w,h),cvPoint(j,i));+            r = eucNorm(nor);+            FGET(result,j,i) = b3*pow(r,6)+b2*pow(r,4)+b3*pow(r,2)+1;+           }+    return result;+}+IplImage* vignettingModelP(int w, int h,double scalex, double scaley, double max) {+    IplImage *result;+    int i,j;+    double r;+    double mx = w/2.0;+    double my = w/2.0;+    result = wrapCreateImage32F(w,h,1);    +    for (i=0; i<h; i++)+       for (j=0; j<w; j++) {+            FGET(result,j,i) =-((i-my)*scaley)*((i-my)*scaley)*((j-mx)*scalex)*((j-mx)*scalex)-max ;+           }+    return result;+}++IplImage* simplePerspective(double k,IplImage *src) {+    IplImage *result;+    int i,j;+    double r;+    result = cvCloneImage(src);    +    int h = cvGetSize(src).height;+    int w = cvGetSize(src).width;+    CvPoint2D32f srcPts[4] = {{0,0},{w-1,0},{w-1,h-1},{0,h-1}};+    CvPoint2D32f dstPts[4] = {{-k,0},{w-1+k,0},{w-1,h-1},{0,h-1}};+    CvMat* M = cvCreateMat(3,3,CV_32FC1);+    cvGetPerspectiveTransform(srcPts, dstPts, M);+    cvWarpPerspective(src, result, M, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));+    cvReleaseMat(&M);+    return result;+}++IplImage* wrapPerspective(IplImage* src, double a1, double a2, double a3+                                       , double a4, double a5, double a6+                                       , double a7, double a8, double a9)+{+    IplImage *res = cvCloneImage(src);+    double a[] = { a1,a2,a3,+                   a4,a5,a6,+                   a7,a8,a9};++    CvMat M = cvMat(3,3,CV_64FC1,a);+    cvWarpPerspective(src, res, &M, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));+    return res;+}++void findHomography(double* srcPts, double *dstPts, int noPts, double *homography)+{+CvMat src = cvMat(noPts, 2, CV_64FC1, srcPts);+CvMat dst = cvMat(noPts, 2, CV_64FC1, dstPts);+CvMat *hmg = cvCreateMat(3,3,CV_32FC1);+int i;+cvFindHomography(&src, &dst, hmg, 0, 0, 0);+for (i=0;i<3*3;++i)+        homography[i] = cvmGet(hmg,i/3,i%3);+cvReleaseMat(&hmg);+}++inline CvPoint2D64f toNormalizedCoords(CvSize area, CvPoint from)+{+    CvPoint2D64f res;+    res.x = (from.x-area.width/2.0)/area.width;+    res.y = (from.y-area.height/2.0)/area.height;   +    return res;+}++inline CvPoint fromNormalizedCoords(CvSize area, CvPoint2D64f from)+{+    CvPoint res;+    res.x = (from.x+0.5)*area.width;+    res.y = (from.y+0.5)*area.height;   +    return res;+}++inline CvPoint2D64f fromNormalizedCoords64f(CvSize area, CvPoint2D64f from)+{+    CvPoint2D64f res;+    res.x = (from.x+0.5)*area.width;+    res.y = (from.y+0.5)*area.height;   +    return res;+}++void alphaBlit(IplImage *a, IplImage *aAlpha, IplImage *b, IplImage *bAlpha, int offset_y, int offset_x)+{+    // TODO: Add checks for image type and size+ int i,j;+ CvSize bSize = cvGetSize(b);+ CvSize aSize = cvGetSize(a);+ CvRect pos = cvRect(offset_x+                    ,offset_y+                    ,bSize.width+                    ,bSize.height);+ for (i=0; i<bSize.height; i++)+    for (j=0; j<bSize.width; j++) {+       float aA, bA,fV;+       if (j+offset_x>=aSize.width || i+offset_y>=aSize.height || i+offset_y < 0 || j+offset_x<0) continue;++       aA = FGET(aAlpha,j+offset_x,i+offset_y);+       bA = FGET(bAlpha,j,i);+       fV = aA+bA > 0 ? (FGET(b,j,i)*bA+FGET(a,j+offset_x,i+offset_y)*aA)/(aA+bA) : FGET(b,j,i) ;+       FGET(a,j+offset_x,i+offset_y) =fV;+       FGET(aAlpha,j+offset_x,i+offset_y) =aA+bA;+    }+}+++void plainBlit(IplImage *a, IplImage *b, int offset_y, int offset_x)+{+    // TODO: Add checks for image type and size+ int i,j;+ CvSize aSize = cvGetSize(a);+ CvSize bSize = cvGetSize(b);+ for (i=0; i<bSize.height; i++) {+    for (j=0; j<bSize.width; j++) {+       if (j+offset_x<0 || j+offset_x>=aSize.width || i+offset_y<0 || i+offset_y>=aSize.height ) continue;+       if (a->nChannels == 1) +            {FGET(a,j+offset_x,i+offset_y) =FGET(b,j,i);}+        else if (a->nChannels ==3) +            {+             int dx = j+offset_x; int dy = i+offset_y;+             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 0] =+              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 0] ; // B+             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 1] =+              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 1] ; // G+             ((float *)(a->imageData + dy*a->widthStep))[dx*a->nChannels + 2] =+              ((float *)(b->imageData + i*b->widthStep))[j*b->nChannels + 2] ; // R+            }+             else {printf("Can't blit this - pic weird number of channels\n"); abort();}++    }}+}++void subpixel_blit(IplImage *a, IplImage *b, double offset_y, double offset_x)+{+    // TODO: Add checks for image type and size+ int i,j;+ CvSize aSize = cvGetSize(a);+ CvSize bSize = cvGetSize(b);+ for (i=0; i<aSize.height; i++)+    for (j=0; j<aSize.width; j++) {+       double x_at_b=j-offset_x;+       double y_at_b=i-offset_y;+       if (x_at_b <0 || x_at_b >= bSize.width+           || y_at_b <0 || y_at_b >= bSize.height) continue;+       FGET(a,j,i) =bilinearInterp(b,x_at_b,y_at_b);+        // TODO: Check boundaries! #SAFETY++    }+}+++// Histograms.+void wrapReleaseHist(CvHistogram *hist)+{+ cvReleaseHist(&hist);+}++CvHistogram* calculateHistogram(IplImage *img,int bins)+{+ float st_range[] = {-1,1};+ float *ranges[]  = {st_range};+ int hist_size[] = {bins};+ CvHistogram *result = cvCreateHist(1,hist_size,CV_HIST_ARRAY,ranges,1);+ cvCalcHist(&img,result,0,0);+ return result;+}++void get_histogram(IplImage *img,IplImage *mask+                 ,float a, float b,int isCumulative+                 ,int binCount+                 ,double *values)+{+ int i=0;+ float st_range[] = {a,b};+ float *ranges[]  = {st_range};+ int hist_size[] = {binCount};+ CvHistogram *result = cvCreateHist(1,hist_size,CV_HIST_ARRAY+                                   ,ranges,1);+ cvCalcHist(&img,result,isCumulative,mask);+ for (i=0;i<binCount;++i)+    {+     *values = cvQueryHistValue_1D(result,i); values++;+    }+ cvReleaseHist(&result);+ return;+}+++double getHistValue(CvHistogram *h,int bin)+{+ return *cvGetHistValue_1D(h,bin);+}++// Convolutions+IplImage* wrapFilter2D(IplImage *src, int ax,int ay, +                    int w, int h, double *kernel){+int i,j;+IplImage *target = cvCloneImage(src);+CvMat *kernelMat = cvCreateMat(w,h,CV_32FC1);+for(i=0;i<w*h;i++)+  cvSetReal2D(kernelMat,i%w,i/w,kernel[i]); +cvFilter2D(src,target,kernelMat,cvPoint(ay,ax));+cvReleaseMat(&kernelMat);+return target;+}++IplImage* wrapFilter2DImg(IplImage *src+                         ,IplImage *mask+                         ,int ax,int ay)+{+int i,j;+IplImage *target = cvCloneImage(src);+CvSize size = cvGetSize(mask);+CvMat *kernelMat = cvCreateMat(size.width,size.height,CV_32FC1);+for(i=0;i<size.width;i++)+ for(j=0;j<size.height;j++)+  cvSetReal2D(kernelMat,i,j,cvGetReal2D(mask,j,i)); +cvFilter2D(src,target,kernelMat,cvPoint(ay,ax));+cvReleaseMat(&kernelMat);+return target;+}++// Connected components++void wrapFloodFill(IplImage *i, int x, int y, double c+                  ,double low, double high,int fixed)+{+ int flag = 8 | (fixed ? CV_FLOODFILL_FIXED_RANGE : 0);+ cvFloodFill(i,cvPoint(x,y),cvRealScalar(c),cvRealScalar(low)+            ,cvRealScalar(high),NULL,flag,NULL);+}+                  +// hough-lines++void wrapProbHoughLines(IplImage *img, double rho, double theta+                       , int threshold, double minLength+                       , double gapLength+                       , int *maxLines+                       , int *xs, int *ys+                       , int *xs1, int *ys1)+{+ IplImage *tmp;+ CvSeq *lines = 0;+ int i;+ CvMemStorage *storage = cvCreateMemStorage(0); + + tmp = ensure8U(img);++ lines = cvHoughLines2(tmp,storage,CV_HOUGH_PROBABILISTIC+                     ,rho,theta,threshold,minLength,gapLength);+ for( i = 0; i < MIN(lines->total,*maxLines); i++ )+        {+            CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);+            xs[i] = line[0].x; xs1[i] = line[1].x;+            ys[i] = line[0].y; ys1[i] = line[1].y; +        }+ *maxLines = MIN(lines->total,*maxLines);++ cvReleaseImage(&tmp);+ cvReleaseMemStorage(&storage);+ +}+                       +++//@-node:aleator.20050908100314.2:Wrappers+//@+node:aleator.20050908100314.3:Utilities+/* These are utilities that operate on opencv primitives but+  are not really wrappers.. Due to the fact that I seem to+  be incapable to link multiple objects including openCV+  headers this seems to be the next best solution.++  Watch out for name collisions!++*/+//@+node:aleator.20070906153003:Trigonometric operations++void calculateAtan(IplImage *src, IplImage *dst)+{+  CvSize imageSize = cvGetSize(dst);+  double r=0; int i; int j;+  for(i=0; i<imageSize.width; ++i)+    for(j=0; j<imageSize.height; ++j) {+          r = FGET(src,j,i); //// cvGetReal2D(src,j,i);+          FGET(dst,j,i) = atan(r);+          //cvSet2D(dst,j,i,cvScalarAll(atan(r)));+    }+}++void calculateAtan2(IplImage *src1,IplImage *src2, IplImage *dst)+{+  CvSize imageSize = cvGetSize(dst);+  for(int i=0; i<imageSize.width; ++i)+    for(int j=0; j<imageSize.height; ++j) {+          double a = FGET(src1,j,i);+          double b = FGET(src2,j,i);+          FGET(dst,j,i) = atan2(a,b);+    }+}++//@nonl+//@-node:aleator.20070906153003:Trigonometric operations+//@+node:aleator.20051109111547:Pixel accessors+// All these will work only on grayscale.+inline int imax(int x, int y) {return (x>y) ? x:y;}+inline int imin(int x, int y) {return (x<y) ? x:y;}+inline double blurGet2D(IplImage *img,int x, int y)+{+ CvSize size = cvGetSize(img);+ x = imax(0,imin(x,size.width-1));+ y = imax(0,imin(y,size.height-1));++ return cvGetReal2D(img,y,x);+}++//@-node:aleator.20051109111547:Pixel accessors+//@+node:aleator.20070827150608:Haar Filters++// Simple routines for calculating pixelwise+// haar responses++void haarFilter(IplImage *intImg, +                int x1, int y1, int x2, int y2,+                IplImage *target)+{+  int i,j;+  double s = 0;+  double ratio = 1;+  double desArea = (x2-x1)*(y1-y2);+  double area = 0;+  int rx1,rx2,ry1,ry2;+  CvSize imageSize = cvGetSize(target);  +  for(i=0; i<imageSize.width; ++i)+    for(j=0; j<imageSize.height; ++j) {+         rx1 = imax(0,imin(i+x1,imageSize.width-1));  +         ry1 = imax(0,imin(j+y1,imageSize.height-1));+         rx2 = imax(0,imin(i+x2,imageSize.width-1)); +         ry2 = imax(0,imin(j+y2,imageSize.height-1));+         area = (float)((rx2-rx1)*(ry2-ry1));+        // if (area > 0) ratio = fabs(desArea/area);+        // else ratio=1;+         //printf("Ratio(%d,%d) is %lf\n",rx1,ry1,ratio);+         s = blurGet2D(intImg,rx1,ry1)+             -blurGet2D(intImg,rx1,ry2)+             -blurGet2D(intImg,rx2,ry1)+             +blurGet2D(intImg,rx2,ry2);+          cvSet2D(target,j,i,cvScalarAll(s/area));+    }+}++double haar_at(IplImage *intImg, +                int x1, int y1, int w, int h)+{+  int i,j;+  double s = 0;+  s = blurGet2D(intImg,x1,y1)+     -blurGet2D(intImg,x1,y1+h)+     -blurGet2D(intImg,x1+w,y1)+     +blurGet2D(intImg,x1+w,y1+h);+  return s;+}+                +//@nonl+//@-node:aleator.20070827150608:Haar Filters+//@+node:aleator.20070130144337:Statistics along a line+#define SWAP(a,b) { \+        int c = (a);    \+        (a) = (b);      \+        (b) = c;        \+    }+++double average_of_line(int x0, int y0+                     ,int x1, int y1+                     ,IplImage *src) {+     int steep = abs(y1 - y0) > abs(x1 - x0);+     int deltax=0; int deltay=0;+     int error=0;+     int ystep=0;+     int x=0; int y=0;+     float sum=0; int len=0;++     if (steep)   { SWAP(x0, y0); SWAP(x1, y1); }+     if (x0 > x1) { SWAP(x0, x1); SWAP(y0, y1); }+     deltax = x1 - x0;+     deltay = abs(y1 - y0);+     error  = 0;+     y = y0;+     if (y0 < y1) {ystep = 1;} else {ystep = -1;}+     for (x=x0; x<x1; ++x) {+         if (steep) {sum+=blurGet2D(src,y,x);+                     ++len;} +                    // _plot(y,x);} +         else       {sum+=blurGet2D(src,x,y);+                     ++len; } +                    //_plot(x,y);}+         error = error + deltay;+         if (2*error >= deltax) {+             y = y + ystep;+             error = error - deltax; }+         }+         return (sum/len);+}++//@-node:aleator.20070130144337:Statistics along a line+//@+node:aleator.20051130130836:Taking square roots of images++void sqrtImage(IplImage *src,IplImage *dst)+{+int i;int j;+double result;+CvSize size = cvGetSize(src);++for(i=0;i<size.width;++i)+ for(j=0;j<size.height;++j)+    {+     result = cvSqrt(cvGetReal2D(src,j,i));+     cvSetReal2D(dst,j,i,result);+    }+}+//@-node:aleator.20051130130836:Taking square roots of images+//@+node:aleator.20050930104348:Histogram Features+#define HISTOGRAMSIZE 10++double calculateMoment(int i,double arr[], int l)+{+int j=0;+double result = 0;+for(j=0; j<l; j++)+  {  result += pow((j*1.0)/HISTOGRAMSIZE,i)*arr[j]; }+return result;+}++double calculateAbsCentralMoment(int i,double arr[], int l)+{+int j=0;+double m1 = calculateMoment(1,arr,l);+double result = 0;+for(j=0; j<l; j++)+ {+  result += pow(fabs(((j*1.0)/HISTOGRAMSIZE)-m1),i)*arr[j];}+return result;+}++double calculateCentralMoment(int i,double arr[], int l)+{+int j=0;+double m1 = calculateMoment(1,arr, l);+double result = 0;+for(j=0; j<l; j++)+ {  +    result += pow(((j*1.0)/HISTOGRAMSIZE)-m1,i)*arr[j];++ }+return result;+}+//@+node:aleator.20050930104348.1:Central Moments++IplImage* getNthCentralMoment(IplImage *src,int n, int w, int h)+{++CvSize size = cvGetSize(src);+int iw = size.width-w;+int ih = size.height-h;+IplImage *target = wrapCreateImage32F(iw,ih,1);+int x = 0;+int y = 0;+int i = 0;+int j = 0;+double histogram[HISTOGRAMSIZE]; +for (x=0; x<ih; x++)+ for (y=0; y<iw; y++)+ {+memset(histogram,0,HISTOGRAMSIZE*sizeof(double));+double result = 0;++// Calculate the local histogram+for (i=0; i<w; i++)+ for (j=0; j<h; j++)+    {+     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];+     histogram[slot] += 1.0/(w*h*1.0);+    }+++result = calculateCentralMoment(n,histogram,HISTOGRAMSIZE); +cvSet2D(target,x,y,cvScalarAll(result));+ }++return target;+}++IplImage* getNthAbsCentralMoment(IplImage *src,int n, int w, int h)+{++CvSize size = cvGetSize(src);+int iw = size.width-w;+int ih = size.height-h;+IplImage *target = wrapCreateImage32F(iw,ih,1);+int x = 0;+int y = 0;+int i = 0;+int j = 0;+double histogram[HISTOGRAMSIZE]; +for (x=0; x<ih; x++)+ for (y=0; y<iw; y++)+ {+memset(histogram,0,HISTOGRAMSIZE*sizeof(double));+double result = 0;++// Calculate the local histogram+for (i=0; i<w; i++)+ for (j=0; j<h; j++)+    {+     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];+     histogram[slot] += 1.0/(w*h*1.0);+    }+++result = calculateAbsCentralMoment(n,histogram,HISTOGRAMSIZE); +cvSet2D(target,x,y,cvScalarAll(result));+ }++return target;+}++IplImage* getNthMoment(IplImage *src,int n, int w, int h)+{++CvSize size = cvGetSize(src);+int iw = size.width-w;+int ih = size.height-h;+IplImage *target = wrapCreateImage32F(iw,ih,1);+int x = 0;+int y = 0;+int i = 0;+int j = 0;+double histogram[HISTOGRAMSIZE]; +for (x=0; x<ih; x++)+ for (y=0; y<iw; y++)+ {+memset(histogram,0,HISTOGRAMSIZE*sizeof(double));+double result = 0;++// Calculate the local histogram+for (i=0; i<w; i++)+ for (j=0; j<h; j++)+    {+     int slot = HISTOGRAMSIZE*cvGet2D(src,x+i,y+j).val[0];+     histogram[slot] += 1.0/(w*h*1.0);+    }++result = calculateMoment(n,histogram,HISTOGRAMSIZE); +cvSet2D(target,x,y,cvScalarAll(result));+ }++return target;+}++//@-node:aleator.20050930104348.1:Central Moments+//@+node:aleator.20051103110155:SMAB+   +// Perform second moment adaptive binarization for a single pixel `x`+// using given histogram.+double max(double x,double y) {if (x<y) return y; else return x;}+double min(double x,double y) {if (x>y) return y; else return x;}+int SMABx(double x, CvHistogram *h,int binCount,double t)+{+ int binnedX;  double leftSM=0;+ double rightSM=0;+ int i=0;+ binnedX = round(min(1,max(x,0))*(binCount-1));++ // Calculate left second moment:+ for(i=0; i<binnedX; i++)+  { leftSM += pow(x - ((1.0*i)/(1.0*binCount)),2) * getHistValue(h,i); }+ for(i=binnedX; i<binCount; i++)+  { rightSM += pow(x - ((1.0*i)/(1.0*binCount)),2) * getHistValue(h,i); }+ return (leftSM - (rightSM * t));+}++// Perform SMAB for image+void smb(IplImage *image,double t)+{+int i;int j;+double result;+CvSize size = cvGetSize(image);+CvHistogram *h = calculateHistogram(image,255);+for(i=0;i<size.width;++i)+ for(j=0;j<size.height;++j)+ {+     result = SMABx(cvGet2D(image,j,i).val[0],h,255,t);+     cvSet2D(image,j,i,cvScalarAll(result));+ }+}++void smab(IplImage *image,int w, int h,double t)+{+int i;int j;+int wi;int wj;+double result;+CvHistogram *histogram;+CvRect roi;+CvSize size = cvGetSize(image);+roi.width = w;+roi.height = h;++for(i=0;i<size.width;++i)+ for(j=0;j<size.height;++j)+ {+     roi.x = i-(w/2);+     roi.y = j-(h/2);+     cvSetImageROI(image,roi);+     histogram = calculateHistogram(image,50);+     cvResetImageROI(image);+     result = SMABx(cvGetReal2D(image,j,i),histogram,50,t);+     cvReleaseHist(&histogram);+     cvSet2D(image,j,i,cvScalarAll(result));+ }+}+//@-node:aleator.20051103110155:SMAB+//@+node:aleator.20051108093248:Skewness++//@-node:aleator.20051108093248:Skewness+//@-node:aleator.20050930104348:Histogram Features+//@+node:aleator.20050926095227:Susan+/* + Susan (Smallest Univalue Segmenting Nucleus) is + family of image processing methods, including+ edge preserving noise reduction.+*/+//@+node:aleator.20050926095227.1:Susan Smoothing Function++/* + Calculate susan smoothing for `src` around `x`,`y` coordinates.+ `t` determines brightness treshold and sigma controls scale of+ spatial smoothing. `w` and `h` determine window size.+*/++inline double calcSusanSmooth(IplImage* src, int x, int y+                      ,double t,double sigma,int w, int h)+{++int i = 0;+int j = 0;++long double numerator = 0;+long double denominator = 0;+for (i = 0; i<w; i++)+ for (j = 0; j<h; j++)+    {+    if (i==w/2 && j==h/2) continue;+    double r2 = i*i+j*j;+    double expFrac = (cvGet2D(src,x+i,y+j).val[0] +                     - cvGet2D(src,x,y).val[0]);+    expFrac *= expFrac;++    double exponential = exp(  (-r2/(2*sigma*sigma)) - (expFrac/(t*t))  );++    numerator   += cvGet2D(src,x+i,y+j).val[0] * exponential;+    denominator += exponential;+    }+return numerator/denominator;+}+//@-node:aleator.20050926095227.1:Susan Smoothing Function+//@+node:aleator.20050926100856:Susan Smoothing++IplImage* susanSmooth(IplImage *src, int w, int h+                     ,double t, double sigma)++{++CvSize size = cvGetSize(src);+int iw = size.width-w;+int ih = size.height-h;+IplImage *target = wrapCreateImage32F(iw,ih,1);+int x = 0;+int y = 0;+double result = 0;+++for (x=0; x<iw; x++)+ for (y=0; y<ih; y++)+ {+  result = calcSusanSmooth(src,y,x,t,sigma,h,w);+  cvSet2D(target,y,x,cvScalarAll(result));+ }+return target;+}+//@-node:aleator.20050926100856:Susan Smoothing+//@+node:aleator.20050927083244:Susan Edge+/* + Susan Edge Detector.+*/++// susan threshold function+inline double susanC(double r, double r0,double t)+{+ return exp(-((r-r0)/t));+}++inline double susanValue(IplImage *src,int x, int y+                        ,int w, int h, double t)+{+int i; int j;+double geometricTreshold = (3*(w*h)) / 4;+double sum = 0;++for (i = 0; i<w; i++)+ for (j = 0; j<h; j++)+    {+     sum += susanC(cvGet2D(src,x+i,y+j).val[0]+                  ,cvGet2D(src,x,y).val[0]+                  ,t);+    }+if (sum < geometricTreshold)+    return geometricTreshold - sum;+else return 0;+}++IplImage* susanEdge(IplImage *src,int w,int h,double t)+{+CvSize size = cvGetSize(src);+int iw = size.width-w;+int ih = size.height-h;+IplImage *target = wrapCreateImage32F(iw,ih,1);+int x = 0;+int y = 0;+double result = 0;+++for (x=0; x<iw; x++)+ for (y=0; y<ih; y++)+ {+  result = susanValue(src,y,x,h,w,t);+  cvSet2D(target,y,x,cvScalarAll(result));+ }+return target;++}+//@-node:aleator.20050927083244:Susan Edge+//@-node:aleator.20050926095227:Susan+//@+node:aleator.20050908112008:Gabors+/* + Gabor functions are modulated gaussians which bear some resemblance+ to human visual cortex neurons. */+//@+node:aleator.20050908104238:gabor function in C+/* This function calculates value of simple gabor function+  at given x,y coordinates. Parameters for the gabor are:+  +  stdX  - standard deviation in oscillation direction+  stdY  - standard deviation tangential to stdX+  theta - angle (in radians) of the gabor+  phase - phase of the gabor+++*/+double calcGabor(double x, double y+                ,double stdX, double stdY+                ,double theta, double phase+                ,double cycles)+{+ double xth = x*cos(theta)  - y*sin(theta);+ double yth = x*sin(theta)  + y*cos(theta);+ double oscillationPart = cos(2*M_PI*xth/cycles+phase);+ double gaussianPart    = exp((-0.5*xth*xth)/(stdX*stdX))+                         *exp((-0.5*yth*yth)/(stdY*stdY));+ + return gaussianPart * oscillationPart;+}++double calc1DGabor(double x+                ,double sigma+                ,double phase, double center+                ,double cycles)+{+ double oscillationPart = cos(2*M_PI*(x-center)/cycles+phase);+ double gaussianPart    = exp((-0.5*(x-center)*(x-center))+                              /(sigma*sigma));+ + return gaussianPart * oscillationPart;+}+++//@-node:aleator.20050908104238:gabor function in C+//@+node:aleator.20050908112116:rendering gabors to arrays+void renderGabor(CvArr *dst,int width, int height+                ,double dx, double dy+                ,double stdX, double stdY+                ,double theta, double phase+                ,double cycles)++{+ int i,j;+ int mx = width/2;+ int my = height/2;+ for (i=0; i<width; i++)+  for (j=0; j<height; j++) // TODO: This might be a bug+   cvSet2D(dst,i,j,cvScalarAll(calcGabor(i-dx,j-dy,stdX,stdY+                                        ,theta,phase,cycles)));+}++void render_gaussian(IplImage *dst+                   ,double stdX, double stdY)++{+ int i,j;+ double distX;+ double distY;+ CvSize size = cvGetSize(dst);+ double centerX = size.width/2.0;+ double centerY = size.height/2.0;+ for (i=0; i<size.width-1; i++)+  for (j=0; j<size.height-1; j++)+   { distX = ((centerX-i*1.0)*(centerX-i*1.0)) / (2*stdX*stdX);+     distY = ((centerY-j*1.0)*(centerY-j*1.0)) / (2*stdY*stdY);+  //   printf("w: %d, h: %d, i: %d, j:%d,dx: %e,dy: %e,exp:%e\n",size.width,size.height,i,j,distX,distY,exp(-distX-distY));+     fflush(stdout);+     cvSet2D(dst,j,i,cvScalarAll( exp(-distX-distY) ));+  }+}+++void renderRadialGabor(CvArr *dst,int width, int height+                ,double sigma+                ,double phase, double center+                ,double cycles)++{+ int i,j;+ int mx = width/2;+ int my = height/2;+ double rad = 0;+ for (i=0; i<width; i++)+  for (j=0; j<width; j++)+   {+   rad = sqrt((i-mx)*(i-mx)+(j-my)*(j-my));+   cvSet2D(dst,i,j,cvScalarAll(calc1DGabor(rad,sigma+                                          ,phase,center,cycles)));+   }+}++void wrapMinMaxLoc(const IplImage* target, int* minx, int* miny, int* maxx, int* maxy, double *minval, double *maxval)+{+	CvPoint maxPoint;+	CvPoint minPoint;+	cvMinMaxLoc(target,minval,maxval,&minPoint, &maxPoint, NULL);+    *maxx = maxPoint.x ;+    *maxy = maxPoint.y ;+    *minx = minPoint.x ;+    *miny = minPoint.y ;+} ++void simpleMatchTemplate(const IplImage* target, const IplImage* template, int* x, int* y, double *val,int type)+{+	int rw = cvGetSize(target).width-cvGetSize(template).width+1;+	int rh = cvGetSize(target).height-cvGetSize(template).height+1;+	IplImage* result = wrapCreateImage32F(rw,rh,1);+	cvMatchTemplate(target,template,result,type);+	double min,max;+	CvPoint maxPoint;+	maxPoint.x=-1;+	maxPoint.y=-1;+	min =0;+	max =0;+	cvMinMaxLoc(result,&min,&max,NULL, &maxPoint, NULL);+	*x = maxPoint.x;+rw/2;+	*y = maxPoint.y;+rh/2;+	*val = max;+	cvReleaseImage(&result);+	} ++IplImage* templateImage(const IplImage* target, const IplImage* template)+{+	int rw = cvGetSize(target).width-cvGetSize(template).width+1;+	int rh = cvGetSize(target).height-cvGetSize(template).height+1;+	IplImage* result = wrapCreateImage32F(rw,rh,1);+	cvMatchTemplate(target,template,result,CV_TM_CCORR);+	return result;+	} +++//@-node:aleator.20050908112116:rendering gabors to arrays+//@+node:aleator.20050908101148:gabor filter using cvFilter2D+void gaborFilter(const CvArr *src, CvArr *dst+                ,int maskWidth, int maskHeight+                ,double stdX, double stdY+                ,double theta,double phase+                ,double cycles)++{+ int mx = maskWidth/2;+ int my = maskHeight/2;+ CvMat *kernel = cvCreateMat(maskWidth,maskHeight,CV_32F);+ renderGabor(kernel,maskWidth,maskHeight,mx,my,stdX,stdY+             ,theta,phase,cycles);+ cvFilter2D(src,dst,kernel,cvPoint(-1,-1));+}++void radialGaborFilter(const CvArr *src, CvArr *dst+                ,int maskWidth, int maskHeight+                ,double sigma+                ,double phase,double center+                ,double cycles)++{+ CvMat *kernel = cvCreateMat(maskWidth,maskHeight,CV_32F);+ renderRadialGabor(kernel,maskWidth,maskHeight,sigma+               ,phase,center,cycles);+ cvFilter2D(src,dst,kernel,cvPoint(-1,-1));+}+++//@-node:aleator.20050908101148:gabor filter using cvFilter2D+//@-node:aleator.20050908112008:Gabors+//@+node:aleator.20070511142414:Adaboost Learning+// This doesn't really work properly yet.. No+// time to do anything about it really.+//@nonl+//@+node:aleator.20070511142414.1:Fitness+// In the following the class is encoded bit+// differently. 0 is one class and +1 is another.+// if target is gray it is considered null area.++double adaFitness1(IplImage *target+                 ,IplImage *weigths+                 ,IplImage *test)+{+CvSize size = cvGetSize(target);+int i,j;+int width  = size.width;+int height = size.height;+double result=0;+double tij=0,wij=0,testij=0,rij=0; +for (i=0; i<width; i++)+ for (j=0; j<height; j++)+ { +   tij = cvGetReal2D(target,j,i);+   wij = cvGetReal2D(weigths,j,i);+   testij = cvGetReal2D(test,j,i);+   rij=wij;+   if (((tij < 0.2) && (testij < 0.2)) || ((tij > 0.8) && (testij > 0.8))) +    {rij=0;} +   result += rij;+ }+ +return result;+}+//@-node:aleator.20070511142414.1:Fitness+//@+node:aleator.20070511145251:Updating distributions++// This function is used to update distribution.+// Notice that alpha_t must be calculated separately+// and normalization is not applied.+IplImage* adaUpdateDistrImage(IplImage *target+                          ,IplImage *weigths+                          ,IplImage *test+                          ,double at)+{+CvSize size = cvGetSize(target);+int i,j;+int width  = size.width;+int height = size.height;+double tij=0,wij=0,testij=0,rij=0; +IplImage *result = wrapCreateImage32F(width,height,1);+for (i=0; i<width; i++)+ for (j=0; j<height; j++)+ { +   tij = cvGetReal2D(target,j,i);+   wij = cvGetReal2D(weigths,j,i);+   testij = cvGetReal2D(test,j,i);+   if ( (tij>0.2) && (tij<0.8) ) continue;+   if (((tij < 0.2) && (testij < 0.2)) +      || ((tij > 0.8) && (testij > 0.8))) +    {rij = wij*exp(-at);+     cvSetReal2D(result,j,i,rij); }+   else +    {rij = wij*exp(at);+     cvSetReal2D(result,j,i,rij); }+ }+ +return result;+}++//@-node:aleator.20070511145251:Updating distributions+//@-node:aleator.20070511142414:Adaboost Learning+//@+node:aleator.20051207074905:LBP++void get_weighted_histogram(IplImage *src, IplImage *weights, +                       double start, double end, +                       int bins, double *histo)+{+  int i,j,index;+  double value,weight;+  CvSize imageSize = cvGetSize(src);  +  for(i=0;i<bins;++i) histo[i]=0;+  for(i=0; i<imageSize.width-1; ++i)+    for(j=0; j<imageSize.height-1; ++j)+        {+         value = cvGetReal2D(src,j,i);+         weight = cvGetReal2D(weights,j,i);+         index = floor(bins*((value - start)/(end - start)));+         //printf("Adding weight %e to index %d\n",weight,index);+         if (index<0 || index>=bins) continue;+         histo[index] += weight;+        }+  +}++// Calculate local binary pattern for image. +// LBP is outgoing array+// of (preallocated) 256 bytes that are assumed to be 0.+void localBinaryPattern(IplImage *src, int *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=1; i<imageSize.width-1; ++i)+    for(j=1; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);++         pattern += (blurGet2D(src,i-1,j-1) > center) *1;+         pattern += (blurGet2D(src,i,j-1)   > center) *2;+         pattern += (blurGet2D(src,i+1,j-1) > center) *4;+         +         pattern += (blurGet2D(src,i-1,j)   > center) *8;+         pattern += (blurGet2D(src,i+1,j)   > center) *16;+         +         pattern += (blurGet2D(src,i-1,j+1) > center) *32;+         pattern += (blurGet2D(src,i,j+1)   > center) *64;+         pattern += (blurGet2D(src,i+1,j+1) > center) *128;+         LBP[pattern]++;+         pattern = 0;+        }+}+++void localBinaryPattern3(IplImage *src, int *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=1; i<imageSize.width-1; ++i)+    for(j=1; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);++         pattern += (blurGet2D(src,i-2,j-2) > center) *1;+         pattern += (blurGet2D(src,i,j-3)   > center) *2;+         pattern += (blurGet2D(src,i+2,j-2) > center) *4;+         +         pattern += (blurGet2D(src,i-3,j)   > center) *8;+         pattern += (blurGet2D(src,i+3,j)   > center) *16;+         +         pattern += (blurGet2D(src,i-2,j+2) > center) *32;+         pattern += (blurGet2D(src,i,j+3)   > center) *64;+         pattern += (blurGet2D(src,i+2,j+2) > center) *128;+         LBP[pattern]++;+         pattern = 0;+        }+}+void localBinaryPattern5(IplImage *src, int *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=1; i<imageSize.width-1; ++i)+    for(j=1; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);++         pattern += (blurGet2D(src,i-4,j-4) > center) *1;+         pattern += (blurGet2D(src,i,j-5)   > center) *2;+         pattern += (blurGet2D(src,i+4,j-4) > center) *4;+         +         pattern += (blurGet2D(src,i-5,j)   > center) *8;+         pattern += (blurGet2D(src,i+5,j)   > center) *16;+         +         pattern += (blurGet2D(src,i-4,j+4) > center) *32;+         pattern += (blurGet2D(src,i,j+5)   > center) *64;+         pattern += (blurGet2D(src,i+4,j+4) > center) *128;+         LBP[pattern]++;+         pattern = 0;+        }+}++void weighted_localBinaryPattern(IplImage *src,int offsetX,int offsetXY+                                , IplImage* weights, double *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  double weight = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=1; i<imageSize.width-1; ++i)+    for(j=1; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);+         weight = cvGetReal2D(weights,j,i);++         pattern += (blurGet2D(src,i-offsetXY,j-offsetXY) > center) *1;+         pattern += (blurGet2D(src,i,j-offsetX)   > center) *2;+         pattern += (blurGet2D(src,i+offsetXY,j-offsetXY) > center) *4;+         +         pattern += (blurGet2D(src,i-offsetX,j)   > center) *8;+         pattern += (blurGet2D(src,i+offsetX,j)   > center) *16;+         +         pattern += (blurGet2D(src,i-offsetXY,j+offsetXY) > center) *32;+         pattern += (blurGet2D(src,i,j+offsetX)   > center) *64;+         pattern += (blurGet2D(src,i+offsetXY,j+offsetXY) > center) *128;+         LBP[pattern] += weight;+         pattern = 0;+        }+}+++void localHorizontalBinaryPattern(IplImage *src, int *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=0; i<imageSize.width-1; ++i)+    for(j=0; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);++         pattern += (blurGet2D(src,i-4,j) > center) *1;+         pattern += (blurGet2D(src,i-3,j) > center) *2;+         pattern += (blurGet2D(src,i-2,j) > center) *4;+         pattern += (blurGet2D(src,i-1,j) > center) *8;+         pattern += (blurGet2D(src,i+1,j) > center) *16;+         pattern += (blurGet2D(src,i+2,j) > center) *32;+         pattern += (blurGet2D(src,i+3,j) > center) *64;+         pattern += (blurGet2D(src,i+4,j) > center) *128;+         LBP[pattern]++;+         pattern = 0;+        }+}++void localVerticalBinaryPattern(IplImage *src, int *LBP)+{+  int i,j;+  int pattern = 0;+  double center = 0;+  CvSize imageSize = cvGetSize(src);  +  for(i=0; i<imageSize.width-1; ++i)+    for(j=0; j<imageSize.height-1; ++j)+        {+         center = cvGetReal2D(src,j,i);++         pattern += (blurGet2D(src,i,j-4) > center) *1;+         pattern += (blurGet2D(src,i,j-3) > center) *2;+         pattern += (blurGet2D(src,i,j-2) > center) *4;+         pattern += (blurGet2D(src,i,j-1) > center) *8;+         pattern += (blurGet2D(src,i,j+1) > center) *16;+         pattern += (blurGet2D(src,i,j+2) > center) *32;+         pattern += (blurGet2D(src,i,j+3) > center) *64;+         pattern += (blurGet2D(src,i,j+4) > center) *128;+         LBP[pattern]++;+         pattern = 0;+        }+}+++//@-node:aleator.20051207074905:LBP+//@+node:aleator.20051109102750:Selective Average+// Assuming grayscale image calculate local selective average of point x y +inline double calcSelectiveAvg(IplImage *img,double t+                                   ,int x, int y+                                   ,int wwidth, int wheight)+{+int i,j;+double accum=0; +double count=0;+double centerValue; double processed=0;+CvSize size = cvGetSize(img);+centerValue = blurGet2D(img,x,y);++for (i=-wwidth; i<wwidth;++i)+ for (j=-wheight; j<wheight;++j)+  { +   if (  x+i<0 || x+i>=size.width+      || y+j<0 || y+j>=size.height)+      continue;+      +   processed = blurGet2D(img,x+i,y+j);+   if (fabs(processed-centerValue)<t)+        {accum+=processed;++count;}+  }+return accum/count;+}+++IplImage* selectiveAvgFilter(IplImage *src,double t+                            ,int wwidth, int wheight)+{+CvSize size = cvGetSize(src);+int i,j;+int width  = size.width;+int height = size.height;+double result;++IplImage *target = wrapCreateImage32F(width,height,1);+for (i=0; i<width; i++)+ for (j=0; j<height; j++)+ {+  result = calcSelectiveAvg(src,t,i,j,wwidth,wheight);+  cvSetReal2D(target,j,i,result);+ }+ +return target;+}++//@-node:aleator.20051109102750:Selective Average+//@+node:aleator.20060104154125:AcquireImage++// Copy array into single channel iplImage+IplImage *acquireImageSlow(int w, int h, double *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         //printf("(%d,%d) => %d is %f\n",j,i,(i+j*h),d[i+j*h]);+         FGET(img,j,i) = d[j*h+i]; +         }+    }+ return img;+}++IplImage *acquireImageSlowF(int w, int h, float *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         //printf("(%d,%d) => %d is %f\n",j,i,(i+j*h),d[i+j*h]);+         FGET(img,j,i) = d[j*h+i]; +         }+    }+ return img;+}++#define BLUE = 0+#define GREEN = 1+#define RED = 2+++IplImage *acquireImageSlow8U(int w, int h, uint8_t *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U,1);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         UGETC(img,0,j,i) = *d; d++; +         }+    }+ return img;+}++IplImage *acquireImageSlow8URGB(int w, int h, uint8_t *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U,3);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         UGETC(img,0,j,i) = *d; d++; +         UGETC(img,1,j,i) = *d; d++; +         UGETC(img,2,j,i) = *d; d++; +         }+    }+ return img;+}++IplImage *acquireImageSlow8UBGR(int w, int h, uint8_t *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U,3);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         UGETC(img,2,j,i) = *d; d++; +         UGETC(img,1,j,i) = *d; d++; +         UGETC(img,0,j,i) = *d; d++; +         }+    }+ return img;+}++IplImage *acquireImageSlowComplex(int w, int h, complex double *d)+{+ IplImage *img;+ int i,j;+ img = cvCreateImage(cvSize(w,h), IPL_DEPTH_32F,1);+ for (i=0; i<h; i++) {+   for (j=0; j<w; j++) { +         FGET(img,j,i) = (float)(creal(d[j*h+i])); +         }+    }+ return img;+}++void exportImageSlowComplex(IplImage *img, complex double *d)+{+ int i,j;+ CvSize s= cvGetSize(img);+ for (i=0; i<s.height; i++) {+   for (j=0; j<s.width; j++) { +         d[j*s.height+i] = (complex float)(FGET(img,j,i) + 0*I); +         }+    }+}++void exportImageSlow(IplImage *img, double *d)+{+ int i,j;+ CvSize s= cvGetSize(img);+ for (i=0; i<s.height; i++) {+   for (j=0; j<s.width; j++) { +         d[j*s.height+i] = FGET(img,j,i); +         }+    }+}+void exportImageSlowF(IplImage *img, float *d)+{+ int i,j;+ CvSize s= cvGetSize(img);+ for (i=0; i<s.height; i++) {+   for (j=0; j<s.width; j++) { +         d[j*s.height+i] = FGET(img,j,i); +         }+    }+}+//@-node:aleator.20060104154125:AcquireImage+//@-node:aleator.20050908100314.3:Utilities+//@+node:aleator.20060413093124:Connected components+//@+node:aleator.20071016114634:Contours+++void free_found_contours(FoundContours *f)+{+ cvReleaseMemStorage(&(f->storage));+ free(f);+ +}++int reset_contour(FoundContours *f)+{ + f->contour = f->start;+}++int cur_contour_size(FoundContours *f)+{ + return f->contour->total;+}++double contour_area(FoundContours *f)+{ + return cvContourArea(f->contour,CV_WHOLE_SEQ,0);+}++CvMoments* contour_moments(FoundContours *f)+{ + CvMoments* moments = (CvMoments*) malloc(sizeof(CvMoments));+ cvMoments(f->contour,moments,0);+ return moments;+}++double contour_perimeter(FoundContours *f)+{ + return cvContourPerimeter(f->contour);+}++int more_contours(FoundContours *f)+{ + if (f->contour != 0)+  {return 1;}+  {return 0;} // no more contours+}++int next_contour(FoundContours *f)+{ + if (f->contour != 0)+  {f->contour = f->contour->h_next; return 1;}+  {return 0;} // no more contours+}++void contour_points(FoundContours *f, int *xs, int *ys)+{+ if (f->contour==0) {printf("unavailable contour\n"); exit(1);}+ + CvPoint *pt=0;+ int total,i=0;+ total = f->contour->total;+ for (i=0; i<total;i++) +  {+   pt = (CvPoint*)cvGetSeqElem(f->contour,i);+   if (pt==0) {printf("point out of contour\n"); exit(1);}+   xs[i] = pt->x;+   ys[i] = pt->y;+  } +    +}++void print_contour(FoundContours *fc)+{+  int i=0;+  CvPoint *pt=0;+   for (i=0; i<fc->contour->total;++i) +    {+     pt = (CvPoint*)cvGetSeqElem(fc->contour,i);+     printf("PT=%d,%d\n",pt->x,pt->y);+    }+}++/* void draw_contour(FoundContours *fc,double color+                 , IplImage *img, IplImage *dst)+{+ cvDrawContours( dst, fc->start, color, color, -1, 0, 8+               , cvPoint(0,0));+} */+++FoundContours* get_contours(IplImage *src1)+{+ CvSize size;+ IplImage *src = ensure8U(src1);+ //int dstDepth = IPL_DEPTH_8U;+ //size = cvGetSize(src1);+ //src = cvCreateImage(size,dstDepth,1);+ //cvCopy(src1,src,NULL);+ + + CvPoint* pt=0;+ int i=0;+ + CvMemStorage *storage=0;+ CvSeq *contour=0;+ FoundContours* result = (FoundContours*)malloc(sizeof(FoundContours));+ storage = cvCreateMemStorage(0);+       + cvFindContours( src,storage+               , &contour+               , sizeof(CvContour) +               ,CV_RETR_EXTERNAL +            //,CV_RETR_CCOMP +               ,CV_CHAIN_APPROX_NONE+               ,cvPoint(0,0) );++// result->contour = cvApproxPoly( result->contour, sizeof(CvContour)+//                                , result->storage, CV_POLY_APPROX_DP+//                                , 3, 1 );+ result->start = contour;+ result->contour = contour;+ result->storage = storage;++ cvReleaseImage(&src);+ return result;+    + }+//@-node:aleator.20071016114634:Contours+//@+node:aleator.20070814123008:moments+CvMoments* getMoments(IplImage *src, int isBinary)+{+ CvMoments* moments = (CvMoments*) malloc(sizeof(CvMoments));+ cvMoments( src, moments, isBinary);+ return moments;+}++void freeCvMoments(CvMoments *x)+{+ free(x);+}+++void getHuMoments(CvMoments *src,double *hu)+{+ CvHuMoments* hu_moments = (CvHuMoments*) malloc(sizeof(CvHuMoments));+ cvGetHuMoments( src, hu_moments);+ *hu = hu_moments->hu1; ++hu;+ *hu = hu_moments->hu2; ++hu;+ *hu = hu_moments->hu3; ++hu;+ *hu = hu_moments->hu4; ++hu;+ *hu = hu_moments->hu5; ++hu;+ *hu = hu_moments->hu6; ++hu;+ *hu = hu_moments->hu7; + return;+}++void freeCvHuMoments(CvHuMoments *x)+{+ free(x);+}+//@-node:aleator.20070814123008:moments+//@+node:aleator.20060727102514:blobCount+int blobCount(IplImage *src)+{+    int contourCount=0;+    CvMemStorage* storage = cvCreateMemStorage(0);+    CvSeq* contour = 0;++    contourCount = cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );++    cvReleaseMemStorage(&storage);+    return contourCount;+}++//@-node:aleator.20060727102514:blobCount+//@+node:aleator.20060413093124.1:sizeFilter+IplImage* sizeFilter(IplImage *src, double minSize, double maxSize)+{+    IplImage* dst = cvCreateImage( cvGetSize(src), IPL_DEPTH_32F, 1 );+    CvMemStorage* storage = cvCreateMemStorage(0);+    CvSeq* contour = 0;++    cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );+    cvZero( dst );++    for( ; contour != 0; contour = contour->h_next )+    {+        double area=fabs(cvContourArea(contour,CV_WHOLE_SEQ,0));+        if (area <=minSize || area >= maxSize) continue;+        CvScalar color = cvScalar(1,1,1,1);+        cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8,+            cvPoint(0,0));+    }+    cvReleaseMemStorage(&storage);+    return dst;+}+//@-node:aleator.20060413093124.1:sizeFilter+//@-node:aleator.20060413093124:Connected components+//@+node:aleator.20050908101148.1:function for rotating image+IplImage* rotateImage(IplImage* src,double scale,double angle)+{++  IplImage* dst = cvCloneImage( src );+  angle = angle * (180 / CV_PI);+  int w = src->width;+  int h = src->height;+  CvMat *M;+  M = cvCreateMat(2,3,CV_32FC1);+  CvPoint2D32f center = cvPoint2D32f(w/2.0,h/2.0);+  CvMat *N = cv2DRotationMatrix(center,angle,scale,M);+  cvWarpAffine( src, dst, N, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+              , cvScalarAll(0)); +  return dst;+  cvReleaseMat(&M);+}+++inline double cubicInterpolate(+   double y0,double y1,+   double y2,double y3,+   double mu)+{+   double a0,a1,a2,a3,mu2;++   mu2 = mu*mu;+   a0 = y3 - y2 - y0 + y1;+   a1 = y0 - y1 - a0;+   a2 = y2 - y0;+   a3 = y1;+   return(a0*mu*mu2+a1*mu2+a2*mu+a3);+}++double bilinearInterp(IplImage *tex, double u, double v) {+   CvSize s = cvGetSize(tex);+   int x = floor(u);+   int y = floor(v);+   double u_ratio = u - x;+   double v_ratio = v - y;+   double u_opposite = 1 - u_ratio;+   double v_opposite = 1 - v_ratio;+   double result = ((x+1 >= s.width) || (y+1 >= s.height)) ? FGET(tex,x,y) :+                   (FGET(tex,x,y)   * u_opposite  + FGET(tex,x+1,y)   * u_ratio) * v_opposite + +                   (FGET(tex,x,y+1) * u_opposite  + FGET(tex,x+1,y+1) * u_ratio) * v_ratio;+   return result;+ }++// TODO: Check boundaries! #SAFETY+double bicubicInterp(IplImage *tex, double u, double v) {+   CvSize s = cvGetSize(tex);+   int x = floor(u);+   int y = floor(v);+   double u_ratio = u - x;+   double v_ratio = v - y;+   double p[4][4] = {FGET(tex,x-1,y-1),  FGET(tex,x,y-1),  FGET(tex,x+1,y-1),  FGET(tex,x+2,y-1),+                     FGET(tex,x-1,y),    FGET(tex,x,y),    FGET(tex,x+1,y),    FGET(tex,x+2,y),+                     FGET(tex,x-1,y+1),  FGET(tex,x,y+1),  FGET(tex,x+1,y+1),  FGET(tex,x+2,y+1),+                     FGET(tex,x-1,y+2),  FGET(tex,x,y+2),  FGET(tex,x+1,y+2),  FGET(tex,x+2,y+2)+                     };+    double a00 = p[1][1];+	double a01 = -p[1][0] + p[1][2];+	double a02 = 2*p[1][0] - 2*p[1][1] + p[1][2] - p[1][3];+	double a03 = -p[1][0] + p[1][1] - p[1][2] + p[1][3];+	double a10 = -p[0][1] + p[2][1];+	double a11 = p[0][0] - p[0][2] - p[2][0] + p[2][2];+	double a12 = -2*p[0][0] + 2*p[0][1] - p[0][2] + p[0][3] + 2*p[2][0] - 2*p[2][1] +                 + p[2][2] - p[2][3];+	double a13 = p[0][0] - p[0][1] + p[0][2] - p[0][3] - p[2][0] + p[2][1] - p[2][2] + p[2][3];+	double a20 = 2*p[0][1] - 2*p[1][1] + p[2][1] - p[3][1];+	double a21 = -2*p[0][0] + 2*p[0][2] + 2*p[1][0] - 2*p[1][2] - p[2][0] + p[2][2] +                 + p[3][0] - p[3][2];+	double a22 = 4*p[0][0] - 4*p[0][1] + 2*p[0][2] - 2*p[0][3] - 4*p[1][0] + 4*p[1][1] +                 - 2*p[1][2] + 2*p[1][3] + 2*p[2][0] - 2*p[2][1] + p[2][2] - p[2][3] +                 - 2*p[3][0] + 2*p[3][1] - p[3][2] + p[3][3];+	double a23 = -2*p[0][0] + 2*p[0][1] - 2*p[0][2] + 2*p[0][3] + 2*p[1][0] - 2*p[1][1] +                 + 2*p[1][2] - 2*p[1][3] - p[2][0] + p[2][1] - p[2][2] + p[2][3] + p[3][0] +                 - p[3][1] + p[3][2] - p[3][3];+	double a30 = -p[0][1] + p[1][1] - p[2][1] + p[3][1];+	double a31 = p[0][0] - p[0][2] - p[1][0] + p[1][2] + p[2][0] - p[2][2] - p[3][0] + p[3][2];+	double a32 = -2*p[0][0] + 2*p[0][1] - p[0][2] + p[0][3] + 2*p[1][0] - 2*p[1][1] +                 + p[1][2] - p[1][3] - 2*p[2][0] + 2*p[2][1] - p[2][2] + p[2][3] + 2*p[3][0] +                 - 2*p[3][1] + p[3][2] - p[3][3];+	double a33 = p[0][0] - p[0][1] + p[0][2] - p[0][3] - p[1][0] + p[1][1] - p[1][2] +                 + p[1][3] + p[2][0] - p[2][1] + p[2][2] - p[2][3] - p[3][0] + p[3][1] +                 - p[3][2] + p[3][3];++	double x2 = u_ratio * u_ratio;+	double x3 = x2 * u_ratio;+	double y2 = v_ratio * v_ratio;+	double y3 = y2 * v_ratio;++	return a00 + a01 * v_ratio + a02 * y2 + a03 * y3 ++	       a10 * u_ratio + a11 * u_ratio * v_ratio + a12 * u_ratio * y2 + a13 * u_ratio * y3 ++	       a20 * x2 + a21 * x2 * v_ratio + a22 * x2 * y2 + a23 * x2 * y3 ++	       a30 * x3 + a31 * x3 * v_ratio + a32 * x3 * y2 + a33 * x3 * y3;+ }++void radialRemap(IplImage *source, IplImage *dest, double k)+{+    int i,j;+    CvSize s = cvGetSize(dest);+    double x,y,cx,cy,nx,ny,r2;+    cx = s.width/2.0;+    cy = s.height/2.0;+    for (i=0; i<s.height; i++)+       for (j=0; j<s.width; j++) {+           nx = (j-cx)/s.width;+           ny = (i-cy)/s.height;+           r2 = nx*nx+ny*ny;+           nx = nx*(1+k*r2);+           ny = ny*(1+k*r2);+           x = (nx+0.5)*s.width;+           y = (ny+0.5)*s.height;+           if (x<0 || x>=s.width || y<0 || y>=s.height) +            { FGET(dest,j,i) = 0; +             continue;}+           FGET(dest,j,i) = bilinearInterp(source,x,y);+           }+++}+++//@-node:aleator.20050908101148.1:function for rotating image+//@+node:aleator.20051220091717:Matrix multiplication++void wrapMatMul(int w, int h, double *mat+               , double *vec, double *t)+{++CvMat matrix;+CvMat vector;+CvMat target;+cvInitMatHeader(&matrix,w,h,CV_64FC1,mat,CV_AUTOSTEP);+cvInitMatHeader(&vector,h,1,CV_64FC1,vec,CV_AUTOSTEP);+cvInitMatHeader(&target,w,1,CV_64FC1,t,CV_AUTOSTEP);+cvMatMul(&matrix,&vector,&target);+}++void maximal_covering_circle(int ox,int oy, double or, IplImage *distmap+                            ,int *max_x, int *max_y, double *max_r)+{+ double distance,radius;++ *max_x = ox;+ *max_y = oy;+ *max_r  = or;++ CvSize s = cvGetSize(distmap);+ for(int i=0; i<s.width; i++) // TODO: Limit with max_r+  for(int j=0; j<s.height; j++)+   {+    distance = sqrt((i-ox)*(i-ox) + (j-oy)*(j-oy));+    radius   = FGET(distmap,i,j);+    if (radius > *max_r && radius >= or+distance )+         { *max_x=i; *max_y=j; *max_r=radius;}+   }+}++double juliaF(double a, double b,double x, double y) {+     int limit = 1000;+     double complex z;+     int i=0;+     double complex c;+     double cr,ci;+     c = a + b*I;+     z = x+y*I;+     for (i=0;i<limit;i++)+        {+         cr=creal(z); ci=cimag(i);+         if (cr*cr+ci*ci>4) return (i*1.0)/limit;+         z=z*z+c;+        }+    return 0;+    }++CvVideoWriter* wrapCreateVideoWriter(char *fn, int fourcc,+                                     double fps,int w, int h,+                                     int color) + {+   CvVideoWriter *res = cvCreateVideoWriter(fn,CV_FOURCC('M','P','G','4'),fps,cvSize(w,h), color);+   return res;+ }++int wrapFindChessBoardCorners(const void* image, int pw, int ph, CvPoint2D32f* corners, int* cornerCount, int flags)+{+ CvSize s = {pw,ph};+ //for (int i=0; i<pw*ph; i++) {corners[i].x=i; corners[i].y=i+10;}+ cvFindChessboardCorners(image,s,corners,cornerCount,flags);+}++int wrapDrawChessBoardCorners(void* image, int pw, int ph, CvPoint2D32f* corners, int cornerCount, int wasFound)+{+ CvSize s = {pw,ph};+ cvDrawChessboardCorners(image,s,corners,cornerCount,wasFound);+}++double wrapCalibrateCamera2(const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* pointCounts, CvSize *imageSize, CvMat* cameraMatrix, CvMat* distCoeffs, CvMat* rvecs, CvMat* tvecs, int flags)+{+return cvCalibrateCamera2(objectPoints, imagePoints, pointCounts, *imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, flags);+};++void wrapFindCornerSubPix(const CvArr* image, CvPoint2D32f* corners, int count, int winW, int winH, int zeroW, int zeroH, int tType, int maxIter, double epsilon) {+ CvTermCriteria t = {tType,maxIter,epsilon};+ CvSize searchWindow = {winW,winH};+ CvSize zero = {winW,winH};+ cvFindCornerSubPix(image, corners, count, searchWindow, zero, t);+};+++//+//@-node:aleator.20051220091717:Matrix multiplication+//@-all+//@-node:aleator.20050908100314:@thin cvWrapLEO.c+//@-leo
+ cbits/cvWrapLEO.h view
@@ -0,0 +1,287 @@+//@+leo-ver=4-thin+//@+node:aleator.20050908101148.2:@thin cvWrapLEO.h+//@@language c+#ifndef __CVWRAP__+#define __CVWRAP__++#ifndef M_PI+#define M_PI           3.14159265358979323846+#endif++#include <opencv/cv.h>+#include <opencv/cxcore.h>+#include <opencv/highgui.h>+#include <complex.h>++IplImage* wrapCreateImage32F(const int width, const int height, const int channels);+IplImage* wrapCreateImage64F(const int width, const int height, const int channels);++IplImage* wrapCreateImage8U(const int width, const int height, const int channels);++void wrapSubRS(const CvArr *src, double s,CvArr *dst);+void wrapSubS(const CvArr *src, double s,CvArr *dst);+void wrapAddS(const CvArr *src, double s, CvArr *dst);++double wrapAvg(const CvArr *src);+double wrapStdDev(const CvArr *src);+double wrapStdDevMask(const CvArr *src,const CvArr *mask);+double wrapSum(const CvArr *src);+void wrapMinMax(const CvArr *src,const CvArr *mask+               ,double *minVal, double *maxVal);+void wrapAbsDiffS(const CvArr *src, double s, CvArr *dst);++void wrapSetImageROI(IplImage *i,int x, int y, int w, int h);++IplImage* wrapSobel(IplImage *src,int dx+                   ,int dy,int size);++IplImage* wrapLaplace(IplImage *src,int size);++IplImage* ensure8U(const IplImage *src);+IplImage* ensure32F(const IplImage *src);++void wrapSet32F2D(CvArr *arr, int x, int y, double value);+double wrapGet32F2D(CvArr *arr, int x, int y);+uint8_t wrapGet8U2DC(IplImage *arr, int x, int y,int c);++void wrapDrawCircle(CvArr *img, int x, int y, int radius, float r,float g,float b, int thickness);++void wrapDrawLine(CvArr *img, int x, int y, int x1, int y1, double r, double g, double b, int thickness);++void wrapFillPolygon(IplImage *img, int pc, int *xs, int *ys, float r, float g, float b);++void wrapMatMul(int w, int h, double *mat+               , double *vec, double *t);++// Utils. Place them in another file+IplImage* rotateImage(IplImage* src,double scale,double angle);+CvHistogram* calculateHistogram(IplImage *img,int bins);+void wrapReleaseHist(CvHistogram *hist);+double getHistValue(CvHistogram *h,int bin);+void get_histogram(IplImage *img,IplImage *mask+                 ,float a, float b,int isCumulative+                 ,int binCount+                 ,double *values);++//void get_weighted_histogram(IplImage *img,IplImage *mask);+//                 ,float a, float b+//                 ,int binCount+//                 ,double *values);++IplImage* getSubImage(IplImage *img, int sx,int sy,int w,int h);+int getImageHeight(IplImage *img);+int getImageWidth(IplImage *img);+++IplImage* susanSmooth(IplImage *src, int w, int h+                     ,double t, double sigma);++IplImage* susanEdge(IplImage *src,int w,int h,double t);+IplImage* getNthCentralMoment(IplImage *src, int n, int w, int h);+IplImage* getNthAbsCentralMoment(IplImage *src, int n, int w, int h);+IplImage* getNthMoment(IplImage *src, int n, int w, int h);++double calcGabor(double x, double y+                ,double stdX, double stdY+                ,double theta, double phase+                ,double cycles);++void gaborFilter(const CvArr *src, CvArr *dst+                ,int maskWidth, int maskHeight+                ,double stdX, double stdY+                ,double theta,double phase+                ,double cycles);++void radialGaborFilter(const CvArr *src, CvArr *dst+                ,int maskWidth, int maskHeight+                ,double sigma+                ,double phase,double center+                ,double cycles);++void renderRadialGabor(CvArr *dst,int width, int height+                ,double sigma+                ,double phase, double center+                ,double cycles);++void render_gaussian(IplImage *dst+                   ,double stdX, double stdY);++void renderGabor(CvArr *dst,int width, int height+                ,double dx, double dy+                ,double stdX, double stdY+                ,double theta, double phase+                ,double cycles);++void smb(IplImage *image,double t);+void smab(IplImage *image,int w, int h,double t);++IplImage* selectiveAvgFilter(IplImage *src,double t+                            ,int wwidth, int wheight);++IplImage* wrapFilter2D(IplImage *src, int ax,int ay, +                    int w, int h, double *kernel);+IplImage* wrapFilter2DImg(IplImage *src+                         ,IplImage *mask+                         ,int ax,int ay);++void wrapFloodFill(IplImage *i, int x, int y, double c+                  ,double low, double high,int fixed);++void sqrtImage(IplImage *src,IplImage *dst);++void weighted_localBinaryPattern(IplImage *src,int offsetX,int offsetXY+                                , IplImage* weights, double *LBP);++void localBinaryPattern(IplImage *src, int *LBP);+void localBinaryPattern3(IplImage *src, int *LBP);+void localBinaryPattern5(IplImage *src, int *LBP);+void localHorizontalBinaryPattern(IplImage *src, int *LBP);+void localVerticalBinaryPattern(IplImage *src, int *LBP);++void get_weighted_histogram(IplImage *src, IplImage *weights, +                       double start, double end, +                       int bins, double *histo);+++void eigenValsViaSVD(double *A, int size, double *eVals+                    ,double *eVects);++IplImage* sizeFilter(IplImage *src, double minSize, double maxSize);+int blobCount(IplImage *src);+++IplImage *acquireImage(int w, int h, double *d);++void wrapProbHoughLines(IplImage *img, double rho, double theta+                       , int threshold, double minLength+                       , double gapLength+                       , int *maxLines+                       , int *xs, int *ys+                       , int *xs1, int *ys1);+++double average_of_line(int x0, int y0+                     ,int x1, int y1+                     ,IplImage *src);+                     +IplImage* adaUpdateDistrImage(IplImage *target+                          ,IplImage *weigths+                          ,IplImage *test+                          ,double at);++double adaFitness1(IplImage *target+                 ,IplImage *weigths+                 ,IplImage *test);+           +CvMoments* getMoments(IplImage *src, int isBinary);++void freeCvMoments(CvMoments *x);++void getHuMoments(CvMoments *src,double *hu);++void freeCvHuMoments(CvHuMoments *x);++void haarFilter(IplImage *intImg, +                int a, int b, int c, int d,+                IplImage *target);++double haar_at(IplImage *intImg, +                int x1, int y1, int w, int h);++void wrapDrawRectangle(CvArr *img, int x1, int y1, +                       int x2, int y2, float r, float g, float b,+                       int thickness);++void calculateAtan(IplImage *src, IplImage *dst);+void calculateAtan2(IplImage *src1,IplImage *src2, IplImage *dst);+++// Contours+typedef struct {+  CvMemStorage *storage;+  CvSeq *contour;+  CvSeq *start;+  +} FoundContours;++CvMoments* contour_moments(FoundContours *f);+void contour_points(FoundContours *f, int *xs, int *ys);+CvMoments* contour_Moments(FoundContours *f);+int cur_contour_size(FoundContours *f);+double contour_area(FoundContours *f);+double contour_perimeter(FoundContours *f);+int more_contours(FoundContours *f);+int next_contour(FoundContours *f);+int reset_contour(FoundContours *f);+void free_found_contours(FoundContours *f);+void get_next_contour(FoundContours *fc);+void print_contour(FoundContours *fc);+FoundContours* get_contours(IplImage *src);++double juliaF(double a, double b,double x, double y);+void simpleMatchTemplate(const IplImage* target, const IplImage* template, int* x, int* y, double *val, int type);+IplImage* templateImage(const IplImage* target, const IplImage* template);+IplImage* simpleMergeImages(IplImage *a, IplImage *b,int offset_x, int offset_y);++void alphaBlit(IplImage *a, IplImage *aAlpha, IplImage *b, IplImage *bAlpha, int offset_x, int offset_y);+void blitImg(IplImage *a, IplImage *b,int offset_x, int offset_y);+IplImage* fadedEdges(int w, int h, int edgeW);+IplImage* rectangularDistance(int w, int h);+void radialRemap(IplImage *source, IplImage *dest, double k);+void plainBlit(IplImage *a, IplImage *b, int offset_y, int offset_x);+void wrapMinMaxLoc(const IplImage* target, int* minx, int* miny, int* maxx, int* maxy, double *minval, double *maxval);+void incrImageC(void);+IplImage* vignettingModelCos4(int w, int h) ;+IplImage* vignettingModelCos4XCyl(int w, int h) ;+IplImage* vignettingModelX2Cyl(int w, int h,double m, double s, double c);+void wrapDrawText(CvArr *img, char *text, float s, int x, int y,float r,float g,float b);++IplImage* vignettingModelB3(int w, int h,double b1, double b2, double b3);+inline CvPoint2D64f toNormalizedCoords(CvSize area, CvPoint from);+inline CvPoint fromNormalizedCoords(CvSize area, CvPoint2D64f from);+inline double eucNorm(CvPoint2D64f p);+IplImage* vignettingModelP(int w, int h,double scalex, double scaley, double max);+IplImage* wrapPerspective(IplImage* src, double a1, double a2, double a3+                                       , double a4, double a5, double a6+                                       , double a7, double a8, double a9);+IplImage* simplePerspective(double k,IplImage *src);+double bilinearInterp(IplImage *tex, double u, double v);+inline CvPoint2D64f fromNormalizedCoords64f(CvSize area, CvPoint2D64f from);+void findHomography(double* srcPts, double *dstPts, int noPts, double *homography);+void masked_merge(IplImage *src1, IplImage *mask, IplImage *src2, IplImage *dst);+IplImage* makeEvenUp(IplImage *src);+IplImage* padUp(IplImage *src,int right, int bottom);+IplImage* makeEvenDown(IplImage *src);+void vertical_average(IplImage *src1, IplImage *dst);++IplImage* composeMultiChannel(IplImage* img0+                             ,IplImage* img1+                             ,IplImage* img2+                             ,IplImage* img3+                             ,const int channels);++IplImage *acquireImageSlow(int w, int h, double *d);+IplImage *acquireImageSlowF(int w, int h, float *d);+void exportImageSlow(IplImage *img, double *d);+void exportImageSlowF(IplImage *img, float *d);++IplImage *acquireImageSlowComplex(int w, int h, complex double *d);+void exportImageSlowComplex(IplImage *img, complex double *d);+void subpixel_blit(IplImage *a, IplImage *b, double offset_y, double offset_x);+double bicubicInterp(IplImage *tex, double u, double v);++CvVideoWriter* wrapCreateVideoWriter(char *fn, int fourcc, double fps,int w, int h, int color); ++double wrapGet32F2DC(CvArr *arr, int x, int y,int c);+void maximal_covering_circle(int ox,int oy, double or, IplImage *distmap+                            ,int *max_x, int *max_y, double *max_r);++int wrapFindChessBoardCorners(const void* image, int pw, int ph, CvPoint2D32f* corners, int* cornerCount, int flags);++int wrapDrawChessBoardCorners(void* image, int pw, int ph, CvPoint2D32f* corners, int cornerCount, int wasFound);++double wrapCalibrateCamera2(const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* pointCounts, CvSize *imageSize, CvMat* cameraMatrix, CvMat* distCoeffs, CvMat* rvecs, CvMat* tvecs, int flags);++#endif+//@-node:aleator.20050908101148.2:@thin cvWrapLEO.h+//@-leo
+ examples/Chessboard.hs view
@@ -0,0 +1,10 @@+module Main where+import CV.Image+import CV.Calibration++main = do+    Just i <- loadColorImage "chess.png"+    let corners = findChessboardCorners (unsafeImageTo8Bit i) (4,5) (FastCheck:defaultFlags)+    let y = drawChessboardCorners (unsafeImageTo8Bit i) (4,5) corners+    mapM_ print (corners)+    saveImage "found_chessboard.png" y
+ examples/Monster.hs view
@@ -0,0 +1,73 @@+{-#LANGUAGE ViewPatterns#-}+module Main where++import CV.Image++import CV.ColourUtils+import CV.Morphology+import CV.Filters+import CV.Thresholding+import CV.Edges+import CV.ImageMathOp+import qualified CV.ImageMath as IM+import CV.FunnyStatistics+import CV.ConnectedComponents+import CV.Transforms+import System.Environment+import CV.Pixelwise+import Graphics.Gnuplot.Simple+import Data.List+import Data.Ord++hdef d (x:xs) = x+hdef d _      = d++horMax :: Image GrayScale D32 -> [Double]+horMax (fromImage -> pixels) = [fromIntegral $ snd $ maximumBy (comparing value) [(i,j) | j<-[0..height-1]] | i <- [0..width-1] ]+    where+        value (x,y) = getPixel (x,y) pixels +        (width,height) = getSize pixels++ntimes n op = (!! n) . iterate op++smooth [x] = [x]+smooth [x,y] = [(x+y) / 2]+smooth (x:y:xs) = (x+y) / 2:smooth (y:xs)++conv mask = map (prod mask) . tails+    where +     prod xs ys = sum (zipWith (*) xs ys)++-- TODO: Something is not type safe in this chain:+main = do+    Just x <- getArgs >>= loadImage . hdef (error "No file given!") >>= return . fmap (enlarge n )+    let +        operR = unsafeImageTo32F . nibbly 1 0.01 . IM.abs . sobel (1,0) s3  -- nibbly 0.3 0.01+        operL = unsafeImageTo32F . nibbly 1 0.01 . IM.abs . sobel (0,1) s3  -- nibbly 0.3 0.01+        down oper = take n $ map oper $ iterate pyrDown x+        up  oper = foldl1 (\a b -> (pyrUp a) `IM.min` b) $ reverse (down oper)+        se = structuringElement (9,9) (4,4) EllipseShape+        thd =  dilate se 2 . unsafeImageTo32F . nibbly 0.9 0.001 $ IM.invert x +        pyrd = stretchHistogram $  (up operL) #+ (up operR)-- $ sobel (1,0) s3 x -- $ (up operR)+        clean :: Image GrayScale D8+        clean = selectSizedComponents (10000) (10000000) $ IM.moreThan 0.2 $ thd #* (close se pyrd)+        final = unsafeImageTo32F clean -- #* (IM.abs (sobel (1,0) s1 x) #+ IM.abs (sobel (0,1) s1 x))+        rotated :: Image GrayScale D8+        rotated = rotate (pi/4.5) final+--        hm = (horMax rotated)+--        shm = ntimes 100 smooth hm+    saveImage "Combine.png" rotated+--    print (length hm,getSize rotated, getSize (fromImage rotated)) +--    plotLists [YRange (-15,15)] [map (*100) $ nonMaxSupress 30 $ conv [-1,2,-1] $ shm, map (\x -> (x-400)/20) shm]+ where n = 5++nonMaxSupress w = reverse . nonMaxSupress' w . reverse . nonMaxSupress' w+nonMaxSupress' w = map supress . map (take w) . tails +    where +        supress [] = 0 +        supress [x] = x+        supress (x:xs) | all (<x) xs = x+                       | otherwise   = 0 ++threshold t x | x <t = 0+              | otherwise = 10
+ examples/StupidConv.hs view
@@ -0,0 +1,35 @@+{-#LANGUAGE BangPatterns#-}+import CV.Image+import CV.ColourUtils+import Control.Monad+import qualified CV.ImageMath as IM++{-#INLINE (×)#-}+a × b = [(a',b') | a' <- a , b' <- b]++stupidConv im m = do+    res <- create (w-mw,h-mh)+    forM_ ([0..w-1-mw] × [0..h-1-mh]) $ \(x,y) -> +     setPixel (x,y) (sum [getPixel (x+i,y+j) im * getPixel (i,j) m +                         | (i,j) <- [0..mw-1] × [0..mh-1]]) res+    return res+ where +    maskSize = IM.sum m+    (!mw,!mh)  = getSize m+    (!w,!h)    = getSize im++main = do+    Just x <- loadImage "smallLena.jpg"+    m <- fromList (3,3) [-1,0,1+                        ,-1,0,1+                        ,-1,0,1] +    print (IM.sum x)+    r <- stupidConv x m+    print (IM.sum r)+    saveImage "stupid.png" $ stretchHistogram r+++fromList (w,h) xs = do+     i <- create (w,h)+     forM_ (zip ([0..w-1] × [0..h-1]) xs) $ \(p,v) -> setPixel p v i +     return i
+ examples/chess.png view

binary file changed (absent → 28293 bytes)

+ examples/pixelwise.hs view
@@ -0,0 +1,33 @@+module Main where+import CV.Image+import CV.Edges+import qualified CV.ImageMath as IM+import CV.ColourUtils+import CV.Pixelwise+import CV.Filters+import qualified CV.Transforms as T+import Control.Applicative hiding ((<**>))++main = do+    Just x <- loadImage "smallLena.jpg"+    let  y = T.flip T.Horizontal x+         u = T.flip T.Vertical   y+         z = T.flip T.Vertical   x+    saveImage "PixelWise.png" $ montage (3,3) 5 +        [x+        ,y+        ,{-#SCC "+" #-} stretchHistogram . toImage $ ((+) <$$> x <+> y)+        +        ,{-#SCC "++++" #-} stretchHistogram . toImage $ ((\a b c d -> a+b+c+d) <$$> x +                                                           <+> y+                                                           <+> u+                                                           <+> z)+        ,{-#SCC "sin" #-}stretchHistogram . toImage $ fmap (sin . (*9)) . fromImage $ x +        ,stretchHistogram . toImage $ fmap log . fromImage $ x +        +        ,stretchHistogram . gaussian (3,3) +                          . toImage $ atan2 <$$> (sobel (1,0) s5 x) +                                            <+>  (sobel (0,1) s5 x) +        ,toImage $ fmap (\x -> if x > 0.5 then 0 else 1) . fromImage $ x+        ,toImage $ fmap (\x -> if x > 0.5 && x < 0.6 then 0 else 1) . fromImage $ x+        ]
+ examples/readFrom.hs view
@@ -0,0 +1,12 @@+module Main where+import CV.Image++main = do+    x1 <- readFromFile "smallLena.jpg" :: IO (Image GrayScale D32)+    x2 <- readFromFile "smallLena.jpg" :: IO (Image GrayScale D8)+    x3 <- readFromFile "smallLena.jpg" :: IO (Image RGB D32)+    x4 <- readFromFile "smallLena.jpg" :: IO (Image RGB D8)+    saveImage "x1.png" x1+    saveImage "x2.png" x2+    saveImage "x3.png" x3+    saveImage "x4.png" x4
+ examples/testCalibrate.hs view
@@ -0,0 +1,6 @@+module Main where+import CV.Image++import CV.Calibration++main =