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 +36/−12
- CV/Arbitrary.hs +42/−0
- CV/Bindings/Calibrate.hsc +53/−0
- CV/Bindings/Matrix.hsc +90/−0
- CV/Calibration.chs +173/−0
- CV/ConnectedComponents.chs +1/−1
- CV/Conversions.hs +21/−3
- CV/Edges.chs +1/−1
- CV/Filters.chs +17/−5
- CV/Histogram.chs +0/−11
- CV/Image.chs +312/−101
- CV/ImageMath.chs +10/−3
- CV/ImageOp.hs +2/−2
- CV/Matrix.hs +207/−0
- CV/Morphology.chs +4/−4
- CV/MultiresolutionSpline.hs +8/−7
- CV/Pixelwise.hs +63/−0
- CV/Textures.chs +64/−16
- CV/Transforms.chs +12/−8
- CV/Video.chs +8/−2
- CV/cvWrapLEO.c +0/−2286
- CV/cvWrapLEO.h +0/−282
- Utils/Function.hs +31/−0
- Utils/List.hs +264/−0
- Utils/Point.hs +20/−0
- Utils/Rectangle.hs +120/−0
- Utils/Stream.hs +185/−0
- cbits/cvWrapLEO.c +2344/−0
- cbits/cvWrapLEO.h +287/−0
- examples/Chessboard.hs +10/−0
- examples/Monster.hs +73/−0
- examples/StupidConv.hs +35/−0
- examples/chess.png binary
- examples/pixelwise.hs +33/−0
- examples/readFrom.hs +12/−0
- examples/testCalibrate.hs +6/−0
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 =