{-# LANGUAGE BangPatterns
, FlexibleContexts
, FlexibleInstances
, ParallelListComp
, TypeFamilies
, TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Vision.Histogram (
Histogram (..), HistogramShape (..), ToHistogram (..)
, index, (!), linearIndex, map, assocs, pixToBin
, histogram, histogram2D, reduce, resize, cumulative, normalize
, equalizeImage
, compareCorrel, compareChi, compareIntersect, compareEMD
) where
import Data.Int
import Data.Vector.Storable (Vector)
import Foreign.Storable (Storable)
import Prelude hiding (map)
import qualified Data.Vector.Storable as V
import Vision.Image.Class (Pixel, MaskedImage, Image, ImagePixel, FunctorImage)
import Vision.Image.Grey.Type (GreyPixel (..))
import Vision.Image.HSV.Type (HSVPixel (..))
import Vision.Image.RGBA.Type (RGBAPixel (..))
import Vision.Image.RGB.Type (RGBPixel (..))
import Vision.Primitive (
Z (..), (:.) (..), Shape (..), DIM1, DIM3, DIM4, DIM5, ix1, ix3, ix4
)
import qualified Vision.Image.Class as I
{-# RULES
"realToFrac/Int32->Double" realToFrac = fromIntegral :: Int32 -> Double
"realToFrac/Int32->Float" realToFrac = fromIntegral :: Int32 -> Float
#-}
data Histogram sh a = Histogram {
forall sh a. Histogram sh a -> sh
shape :: !sh
, forall sh a. Histogram sh a -> Vector a
vector :: !(Vector a)
} deriving (Histogram sh a -> Histogram sh a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall sh a.
(Storable a, Eq sh, Eq a) =>
Histogram sh a -> Histogram sh a -> Bool
/= :: Histogram sh a -> Histogram sh a -> Bool
$c/= :: forall sh a.
(Storable a, Eq sh, Eq a) =>
Histogram sh a -> Histogram sh a -> Bool
== :: Histogram sh a -> Histogram sh a -> Bool
$c== :: forall sh a.
(Storable a, Eq sh, Eq a) =>
Histogram sh a -> Histogram sh a -> Bool
Eq, Histogram sh a -> Histogram sh a -> Bool
Histogram sh a -> Histogram sh a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {sh} {a}. (Storable a, Ord sh, Ord a) => Eq (Histogram sh a)
forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Bool
forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Ordering
forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Histogram sh a
min :: Histogram sh a -> Histogram sh a -> Histogram sh a
$cmin :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Histogram sh a
max :: Histogram sh a -> Histogram sh a -> Histogram sh a
$cmax :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Histogram sh a
>= :: Histogram sh a -> Histogram sh a -> Bool
$c>= :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Bool
> :: Histogram sh a -> Histogram sh a -> Bool
$c> :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Bool
<= :: Histogram sh a -> Histogram sh a -> Bool
$c<= :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Bool
< :: Histogram sh a -> Histogram sh a -> Bool
$c< :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Bool
compare :: Histogram sh a -> Histogram sh a -> Ordering
$ccompare :: forall sh a.
(Storable a, Ord sh, Ord a) =>
Histogram sh a -> Histogram sh a -> Ordering
Ord, Int -> Histogram sh a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall sh a.
(Show sh, Show a, Storable a) =>
Int -> Histogram sh a -> ShowS
forall sh a.
(Show sh, Show a, Storable a) =>
[Histogram sh a] -> ShowS
forall sh a.
(Show sh, Show a, Storable a) =>
Histogram sh a -> String
showList :: [Histogram sh a] -> ShowS
$cshowList :: forall sh a.
(Show sh, Show a, Storable a) =>
[Histogram sh a] -> ShowS
show :: Histogram sh a -> String
$cshow :: forall sh a.
(Show sh, Show a, Storable a) =>
Histogram sh a -> String
showsPrec :: Int -> Histogram sh a -> ShowS
$cshowsPrec :: forall sh a.
(Show sh, Show a, Storable a) =>
Int -> Histogram sh a -> ShowS
Show)
class Shape sh => HistogramShape sh where
toBin :: sh
-> sh
-> sh
-> sh
instance HistogramShape Z where
toBin :: Z -> Z -> Z -> Z
toBin Z
_ Z
_ Z
_ = Z
Z
{-# INLINE toBin #-}
instance HistogramShape sh => HistogramShape (sh :. Int) where
toBin :: (sh :. Int) -> (sh :. Int) -> (sh :. Int) -> sh :. Int
toBin !(sh
shBins :. Int
bins) !(sh
shMaxBins :. Int
maxBins) !(sh
shIx :. Int
ix)
| Int
bins forall a. Eq a => a -> a -> Bool
== Int
maxBins = sh
inner forall tail head. tail -> head -> tail :. head
:. Int
ix
| Bool
otherwise = sh
inner forall tail head. tail -> head -> tail :. head
:. (Int
ix forall a. Num a => a -> a -> a
* Int
bins forall a. Integral a => a -> a -> a
`quot` Int
maxBins)
where
inner :: sh
inner = forall sh. HistogramShape sh => sh -> sh -> sh -> sh
toBin sh
shBins sh
shMaxBins sh
shIx
{-# INLINE toBin #-}
class (Pixel p, Shape (PixelValueSpace p)) => ToHistogram p where
type PixelValueSpace p
pixToIndex :: p -> PixelValueSpace p
domainSize :: p -> PixelValueSpace p
instance ToHistogram GreyPixel where
type PixelValueSpace GreyPixel = DIM1
pixToIndex :: GreyPixel -> PixelValueSpace GreyPixel
pixToIndex !(GreyPixel Word8
val) = Int -> DIM1
ix1 forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> Int
int Word8
val
{-# INLINE pixToIndex #-}
domainSize :: GreyPixel -> PixelValueSpace GreyPixel
domainSize GreyPixel
_ = Int -> DIM1
ix1 Int
256
instance ToHistogram RGBAPixel where
type PixelValueSpace RGBAPixel = DIM4
pixToIndex :: RGBAPixel -> PixelValueSpace RGBAPixel
pixToIndex !(RGBAPixel Word8
r Word8
g Word8
b Word8
a) = Int -> Int -> Int -> Int -> DIM4
ix4 (forall a. Integral a => a -> Int
int Word8
r) (forall a. Integral a => a -> Int
int Word8
g) (forall a. Integral a => a -> Int
int Word8
b) (forall a. Integral a => a -> Int
int Word8
a)
{-# INLINE pixToIndex #-}
domainSize :: RGBAPixel -> PixelValueSpace RGBAPixel
domainSize RGBAPixel
_ = Int -> Int -> Int -> Int -> DIM4
ix4 Int
256 Int
256 Int
256 Int
256
instance ToHistogram RGBPixel where
type PixelValueSpace RGBPixel = DIM3
pixToIndex :: RGBPixel -> PixelValueSpace RGBPixel
pixToIndex !(RGBPixel Word8
r Word8
g Word8
b) = Int -> Int -> Int -> DIM3
ix3 (forall a. Integral a => a -> Int
int Word8
r) (forall a. Integral a => a -> Int
int Word8
g) (forall a. Integral a => a -> Int
int Word8
b)
{-# INLINE pixToIndex #-}
domainSize :: RGBPixel -> PixelValueSpace RGBPixel
domainSize RGBPixel
_ = Int -> Int -> Int -> DIM3
ix3 Int
256 Int
256 Int
256
instance ToHistogram HSVPixel where
type PixelValueSpace HSVPixel = DIM3
pixToIndex :: HSVPixel -> PixelValueSpace HSVPixel
pixToIndex !(HSVPixel Word8
h Word8
s Word8
v) = Int -> Int -> Int -> DIM3
ix3 (forall a. Integral a => a -> Int
int Word8
h) (forall a. Integral a => a -> Int
int Word8
s) (forall a. Integral a => a -> Int
int Word8
v)
{-# INLINE pixToIndex #-}
domainSize :: HSVPixel -> PixelValueSpace HSVPixel
domainSize HSVPixel
_ = Int -> Int -> Int -> DIM3
ix3 Int
180 Int
256 Int
256
index :: (Shape sh, Storable a) => Histogram sh a -> sh -> a
index :: forall sh a. (Shape sh, Storable a) => Histogram sh a -> sh -> a
index !Histogram sh a
hist = forall sh a. (Shape sh, Storable a) => Histogram sh a -> Int -> a
linearIndex Histogram sh a
hist forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sh. Shape sh => sh -> sh -> Int
toLinearIndex (forall sh a. Histogram sh a -> sh
shape Histogram sh a
hist)
{-# INLINE index #-}
(!) :: (Shape sh, Storable a) => Histogram sh a -> sh -> a
! :: forall sh a. (Shape sh, Storable a) => Histogram sh a -> sh -> a
(!) = forall sh a. (Shape sh, Storable a) => Histogram sh a -> sh -> a
index
{-# INLINE (!) #-}
linearIndex :: (Shape sh, Storable a) => Histogram sh a -> Int -> a
linearIndex :: forall sh a. (Shape sh, Storable a) => Histogram sh a -> Int -> a
linearIndex !Histogram sh a
hist = forall a. Storable a => Vector a -> Int -> a
(V.!) (forall sh a. Histogram sh a -> Vector a
vector Histogram sh a
hist)
{-# INLINE linearIndex #-}
map :: (Storable a, Storable b) => (a -> b) -> Histogram sh a -> Histogram sh b
map :: forall a b sh.
(Storable a, Storable b) =>
(a -> b) -> Histogram sh a -> Histogram sh b
map a -> b
f !(Histogram sh
sh Vector a
vec) = forall sh a. sh -> Vector a -> Histogram sh a
Histogram sh
sh (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map a -> b
f Vector a
vec)
{-# INLINE map #-}
assocs :: (Shape sh, Storable a) => Histogram sh a -> [(sh, a)]
assocs :: forall sh a. (Shape sh, Storable a) => Histogram sh a -> [(sh, a)]
assocs !(Histogram sh
sh Vector a
vec) = [ (sh
ix, a
v) | sh
ix <- forall sh. Shape sh => sh -> [sh]
shapeList sh
sh
| a
v <- forall a. Storable a => Vector a -> [a]
V.toList Vector a
vec ]
{-# INLINE assocs #-}
pixToBin :: (HistogramShape (PixelValueSpace p), ToHistogram p)
=> PixelValueSpace p -> p -> PixelValueSpace p
pixToBin :: forall p.
(HistogramShape (PixelValueSpace p), ToHistogram p) =>
PixelValueSpace p -> p -> PixelValueSpace p
pixToBin PixelValueSpace p
size p
p =
let !domain :: PixelValueSpace p
domain = forall p. ToHistogram p => p -> PixelValueSpace p
domainSize p
p
in forall sh. HistogramShape sh => sh -> sh -> sh -> sh
toBin PixelValueSpace p
size PixelValueSpace p
domain forall a b. (a -> b) -> a -> b
$! forall p. ToHistogram p => p -> PixelValueSpace p
pixToIndex p
p
{-# INLINE pixToBin #-}
histogram :: ( MaskedImage i, ToHistogram (ImagePixel i), Storable a, Num a
, HistogramShape (PixelValueSpace (ImagePixel i)))
=> Maybe (PixelValueSpace (ImagePixel i)) -> i
-> Histogram (PixelValueSpace (ImagePixel i)) a
histogram :: forall i a.
(MaskedImage i, ToHistogram (ImagePixel i), Storable a, Num a,
HistogramShape (PixelValueSpace (ImagePixel i))) =>
Maybe (PixelValueSpace (ImagePixel i))
-> i -> Histogram (PixelValueSpace (ImagePixel i)) a
histogram Maybe (PixelValueSpace (ImagePixel i))
mSize i
img =
let initial :: Vector a
initial = forall a. Storable a => Int -> a -> Vector a
V.replicate Int
nBins a
0
ones :: Vector a
ones = forall a. Storable a => Int -> a -> Vector a
V.replicate Int
nPixs a
1
ixs :: Vector Int
ixs = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map ImagePixel i -> Int
toIndex (forall i. MaskedImage i => i -> Vector (ImagePixel i)
I.values i
img)
in forall sh a. sh -> Vector a -> Histogram sh a
Histogram PixelValueSpace (ImagePixel i)
size (forall a b.
(Storable a, Storable b) =>
(a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
V.accumulate_ forall a. Num a => a -> a -> a
(+) Vector a
initial Vector Int
ixs Vector a
ones)
where
!size :: PixelValueSpace (ImagePixel i)
size = case Maybe (PixelValueSpace (ImagePixel i))
mSize of Just PixelValueSpace (ImagePixel i)
s -> PixelValueSpace (ImagePixel i)
s
Maybe (PixelValueSpace (ImagePixel i))
Nothing -> forall p. ToHistogram p => p -> PixelValueSpace p
domainSize (forall i. MaskedImage i => i -> ImagePixel i
I.pixel i
img)
!nChans :: Int
nChans = forall i. (Pixel (ImagePixel i), MaskedImage i) => i -> Int
I.nChannels i
img
!nPixs :: Int
nPixs = forall sh. Shape sh => sh -> Int
shapeLength (forall i. MaskedImage i => i -> DIM1 :. Int
I.shape i
img) forall a. Num a => a -> a -> a
* Int
nChans
!nBins :: Int
nBins = forall sh. Shape sh => sh -> Int
shapeLength PixelValueSpace (ImagePixel i)
size
toIndex :: ImagePixel i -> Int
toIndex !ImagePixel i
p = forall sh. Shape sh => sh -> sh -> Int
toLinearIndex PixelValueSpace (ImagePixel i)
size forall a b. (a -> b) -> a -> b
$!
case Maybe (PixelValueSpace (ImagePixel i))
mSize of Just PixelValueSpace (ImagePixel i)
_ -> forall p.
(HistogramShape (PixelValueSpace p), ToHistogram p) =>
PixelValueSpace p -> p -> PixelValueSpace p
pixToBin PixelValueSpace (ImagePixel i)
size ImagePixel i
p
Maybe (PixelValueSpace (ImagePixel i))
Nothing -> forall p. ToHistogram p => p -> PixelValueSpace p
pixToIndex ImagePixel i
p
{-# INLINE toIndex #-}
{-# INLINABLE histogram #-}
histogram2D :: ( Image i, ToHistogram (ImagePixel i), Storable a, Num a
, HistogramShape (PixelValueSpace (ImagePixel i)))
=> (PixelValueSpace (ImagePixel i)) :. Int :. Int -> i
-> Histogram ((PixelValueSpace (ImagePixel i)) :. Int :. Int) a
histogram2D :: forall i a.
(Image i, ToHistogram (ImagePixel i), Storable a, Num a,
HistogramShape (PixelValueSpace (ImagePixel i))) =>
((PixelValueSpace (ImagePixel i) :. Int) :. Int)
-> i
-> Histogram ((PixelValueSpace (ImagePixel i) :. Int) :. Int) a
histogram2D (PixelValueSpace (ImagePixel i) :. Int) :. Int
size i
img =
let initial :: Vector a
initial = forall a. Storable a => Int -> a -> Vector a
V.replicate Int
nBins a
0
ones :: Vector a
ones = forall a. Storable a => Int -> a -> Vector a
V.replicate Int
nPixs a
1
imgIxs :: Vector (DIM1 :. Int)
imgIxs = forall a. Storable a => Int -> (a -> a) -> a -> Vector a
V.iterateN Int
nPixs (forall sh. Shape sh => sh -> sh -> sh
shapeSucc DIM1 :. Int
imgSize) forall sh. Shape sh => sh
shapeZero
ixs :: Vector Int
ixs = forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith (DIM1 :. Int) -> ImagePixel i -> Int
toIndex Vector (DIM1 :. Int)
imgIxs (forall i. Image i => i -> Vector (ImagePixel i)
I.vector i
img)
in forall sh a. sh -> Vector a -> Histogram sh a
Histogram (PixelValueSpace (ImagePixel i) :. Int) :. Int
size (forall a b.
(Storable a, Storable b) =>
(a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
V.accumulate_ forall a. Num a => a -> a -> a
(+) Vector a
initial Vector Int
ixs Vector a
ones)
where
!imgSize :: DIM1 :. Int
imgSize@(Z
Z :. Int
h :. Int
w) = forall i. MaskedImage i => i -> DIM1 :. Int
I.shape i
img
!maxSize :: (PixelValueSpace (ImagePixel i) :. Int) :. Int
maxSize = forall p. ToHistogram p => p -> PixelValueSpace p
domainSize (forall i. MaskedImage i => i -> ImagePixel i
I.pixel i
img) forall tail head. tail -> head -> tail :. head
:. Int
h forall tail head. tail -> head -> tail :. head
:. Int
w
!nChans :: Int
nChans = forall i. (Pixel (ImagePixel i), MaskedImage i) => i -> Int
I.nChannels i
img
!nPixs :: Int
nPixs = forall sh. Shape sh => sh -> Int
shapeLength (forall i. MaskedImage i => i -> DIM1 :. Int
I.shape i
img) forall a. Num a => a -> a -> a
* Int
nChans
!nBins :: Int
nBins = forall sh. Shape sh => sh -> Int
shapeLength (PixelValueSpace (ImagePixel i) :. Int) :. Int
size
toIndex :: (DIM1 :. Int) -> ImagePixel i -> Int
toIndex !(Z
Z :. Int
y :. Int
x) !ImagePixel i
p =
let !ix :: (PixelValueSpace (ImagePixel i) :. Int) :. Int
ix = (forall p. ToHistogram p => p -> PixelValueSpace p
pixToIndex ImagePixel i
p) forall tail head. tail -> head -> tail :. head
:. Int
y forall tail head. tail -> head -> tail :. head
:. Int
x
in forall sh. Shape sh => sh -> sh -> Int
toLinearIndex (PixelValueSpace (ImagePixel i) :. Int) :. Int
size forall a b. (a -> b) -> a -> b
$! forall sh. HistogramShape sh => sh -> sh -> sh -> sh
toBin (PixelValueSpace (ImagePixel i) :. Int) :. Int
size (PixelValueSpace (ImagePixel i) :. Int) :. Int
maxSize (PixelValueSpace (ImagePixel i) :. Int) :. Int
ix
{-# INLINE toIndex #-}
{-# INLINABLE histogram2D #-}
reduce :: (HistogramShape sh, Storable a, Num a)
=> Histogram (sh :. Int :. Int) a -> Histogram sh a
reduce :: forall sh a.
(HistogramShape sh, Storable a, Num a) =>
Histogram ((sh :. Int) :. Int) a -> Histogram sh a
reduce !(Histogram (sh :. Int) :. Int
sh Vector a
vec) =
let !(sh
sh' :. Int
h :. Int
w) = (sh :. Int) :. Int
sh
!len2D :: Int
len2D = Int
h forall a. Num a => a -> a -> a
* Int
w
!vec' :: Vector a
vec' = forall a b.
Storable a =>
Int -> (b -> Maybe (a, b)) -> b -> Vector a
V.unfoldrN (forall sh. Shape sh => sh -> Int
shapeLength sh
sh') Vector a -> Maybe (a, Vector a)
step Vector a
vec
step :: Vector a -> Maybe (a, Vector a)
step !Vector a
rest = let (!Vector a
channels, !Vector a
rest') = forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
len2D Vector a
rest
in forall a. a -> Maybe a
Just (forall a. (Storable a, Num a) => Vector a -> a
V.sum Vector a
channels, Vector a
rest')
in forall sh a. sh -> Vector a -> Histogram sh a
Histogram sh
sh' Vector a
vec'
{-# SPECIALIZE reduce :: Histogram DIM5 Int32 -> Histogram DIM3 Int32
, Histogram DIM5 Double -> Histogram DIM3 Double
, Histogram DIM5 Float -> Histogram DIM3 Float
, Histogram DIM3 Int32 -> Histogram DIM1 Int32
, Histogram DIM3 Double -> Histogram DIM1 Double
, Histogram DIM3 Float -> Histogram DIM1 Float #-}
{-# INLINABLE reduce #-}
resize :: (HistogramShape sh, Storable a, Num a)
=> sh -> Histogram sh a -> Histogram sh a
resize :: forall sh a.
(HistogramShape sh, Storable a, Num a) =>
sh -> Histogram sh a -> Histogram sh a
resize !sh
sh' (Histogram sh
sh Vector a
vec) =
let initial :: Vector a
initial = forall a. Storable a => Int -> a -> Vector a
V.replicate (forall sh. Shape sh => sh -> Int
shapeLength sh
sh') a
0
reIndex :: Int -> Int
reIndex = forall sh. Shape sh => sh -> sh -> Int
toLinearIndex sh
sh' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sh. HistogramShape sh => sh -> sh -> sh -> sh
toBin sh
sh' sh
sh forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sh. Shape sh => sh -> Int -> sh
fromLinearIndex sh
sh
ixs :: Vector Int
ixs = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map Int -> Int
reIndex forall a b. (a -> b) -> a -> b
$ forall a. (Storable a, Num a) => a -> Int -> Vector a
V.enumFromN Int
0 (forall sh. Shape sh => sh -> Int
shapeLength sh
sh)
in forall sh a. sh -> Vector a -> Histogram sh a
Histogram sh
sh' (forall a b.
(Storable a, Storable b) =>
(a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
V.accumulate_ forall a. Num a => a -> a -> a
(+) Vector a
initial Vector Int
ixs Vector a
vec)
cumulative :: (Storable a, Num a) => Histogram DIM1 a -> Histogram DIM1 a
cumulative :: forall a.
(Storable a, Num a) =>
Histogram DIM1 a -> Histogram DIM1 a
cumulative (Histogram DIM1
sh Vector a
vec) = forall sh a. sh -> Vector a -> Histogram sh a
Histogram DIM1
sh (forall a. Storable a => (a -> a -> a) -> Vector a -> Vector a
V.scanl1' forall a. Num a => a -> a -> a
(+) Vector a
vec)
{-# SPECIALIZE cumulative :: Histogram DIM1 Int32 -> Histogram DIM1 Int32
, Histogram DIM1 Double -> Histogram DIM1 Double
, Histogram DIM1 Float -> Histogram DIM1 Float #-}
{-# INLINABLE cumulative #-}
normalize :: (Storable a, Real a, Storable b, Fractional b)
=> b -> Histogram sh a -> Histogram sh b
normalize :: forall a b sh.
(Storable a, Real a, Storable b, Fractional b) =>
b -> Histogram sh a -> Histogram sh b
normalize b
norm !hist :: Histogram sh a
hist@(Histogram sh
_ Vector a
vec) =
let !ratio :: b
ratio = b
norm forall a. Fractional a => a -> a -> a
/ forall a b. (Real a, Fractional b) => a -> b
realToFrac (forall a. (Storable a, Num a) => Vector a -> a
V.sum Vector a
vec)
equalizeVal :: a -> b
equalizeVal !a
val = forall a b. (Real a, Fractional b) => a -> b
realToFrac a
val forall a. Num a => a -> a -> a
* b
ratio
{-# INLINE equalizeVal #-}
in forall a b sh.
(Storable a, Storable b) =>
(a -> b) -> Histogram sh a -> Histogram sh b
map a -> b
equalizeVal Histogram sh a
hist
{-# SPECIALIZE normalize :: Double -> Histogram sh Int32 -> Histogram sh Double
, Float -> Histogram sh Int32 -> Histogram sh Float
, Double -> Histogram sh Double -> Histogram sh Double
, Float -> Histogram sh Double -> Histogram sh Float
, Double -> Histogram sh Float -> Histogram sh Double
, Float -> Histogram sh Float -> Histogram sh Float
#-}
{-# INLINABLE normalize #-}
equalizeImage :: ( FunctorImage i i, Integral (ImagePixel i)
, ToHistogram (ImagePixel i)
, PixelValueSpace (ImagePixel i) ~ DIM1)
=> i -> i
equalizeImage :: forall i.
(FunctorImage i i, Integral (ImagePixel i),
ToHistogram (ImagePixel i),
PixelValueSpace (ImagePixel i) ~ DIM1) =>
i -> i
equalizeImage i
img =
forall src res.
FunctorImage src res =>
(ImagePixel src -> ImagePixel res) -> src -> res
I.map ImagePixel i -> ImagePixel i
equalizePixel i
img
where
hist :: Histogram DIM1 Int32
hist = forall i a.
(MaskedImage i, ToHistogram (ImagePixel i), Storable a, Num a,
HistogramShape (PixelValueSpace (ImagePixel i))) =>
Maybe (PixelValueSpace (ImagePixel i))
-> i -> Histogram (PixelValueSpace (ImagePixel i)) a
histogram forall a. Maybe a
Nothing i
img :: Histogram DIM1 Int32
Z
Z :. Int
nBins = forall sh a. Histogram sh a -> sh
shape Histogram DIM1 Int32
hist
cumNormalized :: Histogram DIM1 Double
cumNormalized = forall a.
(Storable a, Num a) =>
Histogram DIM1 a -> Histogram DIM1 a
cumulative forall a b. (a -> b) -> a -> b
$ forall a b sh.
(Storable a, Real a, Storable b, Fractional b) =>
b -> Histogram sh a -> Histogram sh b
normalize (forall a. Integral a => a -> Double
double Int
nBins) Histogram DIM1 Int32
hist
!cumNormalized' :: Histogram DIM1 Int32
cumNormalized' = forall a b sh.
(Storable a, Storable b) =>
(a -> b) -> Histogram sh a -> Histogram sh b
map forall a b. (RealFrac a, Integral b) => a -> b
round Histogram DIM1 Double
cumNormalized :: Histogram DIM1 Int32
equalizePixel :: ImagePixel i -> ImagePixel i
equalizePixel !ImagePixel i
val = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Histogram DIM1 Int32
cumNormalized' forall sh a. (Shape sh, Storable a) => Histogram sh a -> sh -> a
! Int -> DIM1
ix1 (forall a. Integral a => a -> Int
int ImagePixel i
val)
{-# INLINE equalizePixel #-}
{-# INLINABLE equalizeImage #-}
compareCorrel :: (Shape sh, Storable a, Real a, Storable b, Eq b, Floating b)
=> Histogram sh a -> Histogram sh a -> b
compareCorrel :: forall sh a b.
(Shape sh, Storable a, Real a, Storable b, Eq b, Floating b) =>
Histogram sh a -> Histogram sh a -> b
compareCorrel (Histogram sh
sh1 Vector a
vec1) (Histogram sh
sh2 Vector a
vec2)
| sh
sh1 forall a. Eq a => a -> a -> Bool
/= sh
sh2 = forall a. HasCallStack => String -> a
error String
"Histograms are not of equal size."
| b
denominat forall a. Eq a => a -> a -> Bool
== b
0 = b
1
| Bool
otherwise = b
numerat forall a. Fractional a => a -> a -> a
/ b
denominat
where
numerat :: b
numerat = forall a. (Storable a, Num a) => Vector a -> a
V.sum forall a b. (a -> b) -> a -> b
$ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall a. Num a => a -> a -> a
(*) Vector b
diff1 Vector b
diff2
denominat :: b
denominat = forall a. Floating a => a -> a
sqrt (forall a. (Storable a, Num a) => Vector a -> a
V.sum (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map forall a. Num a => a -> a
square Vector b
diff1))
forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt (forall a. (Storable a, Num a) => Vector a -> a
V.sum (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map forall a. Num a => a -> a
square Vector b
diff2))
diff1 :: Vector b
diff1 = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (\a
v1 -> forall a b. (Real a, Fractional b) => a -> b
realToFrac a
v1 forall a. Num a => a -> a -> a
- b
avg1) Vector a
vec1
diff2 :: Vector b
diff2 = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (\a
v2 -> forall a b. (Real a, Fractional b) => a -> b
realToFrac a
v2 forall a. Num a => a -> a -> a
- b
avg2) Vector a
vec2
(b
avg1, b
avg2) = (forall {a} {a}. (Fractional a, Real a, Storable a) => Vector a -> a
avg Vector a
vec1, forall {a} {a}. (Fractional a, Real a, Storable a) => Vector a -> a
avg Vector a
vec2)
avg :: Vector a -> a
avg !Vector a
vec = forall a b. (Real a, Fractional b) => a -> b
realToFrac (forall a. (Storable a, Num a) => Vector a -> a
V.sum Vector a
vec) forall a. Fractional a => a -> a -> a
/ forall a b. (Real a, Fractional b) => a -> b
realToFrac (forall a. Storable a => Vector a -> Int
V.length Vector a
vec)
{-# SPECIALIZE compareCorrel
:: Shape sh => Histogram sh Int32 -> Histogram sh Int32 -> Double
, Shape sh => Histogram sh Int32 -> Histogram sh Int32 -> Float
, Shape sh => Histogram sh Double -> Histogram sh Double -> Double
, Shape sh => Histogram sh Double -> Histogram sh Double -> Float
, Shape sh => Histogram sh Float -> Histogram sh Float -> Double
, Shape sh => Histogram sh Float -> Histogram sh Float -> Float #-}
{-# INLINABLE compareCorrel #-}
compareChi :: (Shape sh, Storable a, Real a, Storable b, Fractional b)
=> Histogram sh a -> Histogram sh a -> b
compareChi :: forall sh a b.
(Shape sh, Storable a, Real a, Storable b, Fractional b) =>
Histogram sh a -> Histogram sh a -> b
compareChi (Histogram sh
sh1 Vector a
vec1) (Histogram sh
sh2 Vector a
vec2)
| sh
sh1 forall a. Eq a => a -> a -> Bool
/= sh
sh2 = forall a. HasCallStack => String -> a
error String
"Histograms are not of equal size."
| Bool
otherwise = (forall a. (Storable a, Num a) => Vector a -> a
V.sum forall a b. (a -> b) -> a -> b
$ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall {a} {a}. (Fractional a, Real a) => a -> a -> a
step Vector a
vec1 Vector a
vec2) forall a. Num a => a -> a -> a
* b
2
where
step :: a -> a -> a
step !a
v1 !a
v2 = let !denom :: a
denom = a
v1 forall a. Num a => a -> a -> a
+ a
v2
in if a
denom forall a. Eq a => a -> a -> Bool
== a
0
then a
0
else forall a b. (Real a, Fractional b) => a -> b
realToFrac (forall a. Num a => a -> a
square (a
v1 forall a. Num a => a -> a -> a
- a
v2)) forall a. Fractional a => a -> a -> a
/ forall a b. (Real a, Fractional b) => a -> b
realToFrac a
denom
{-# INLINE step #-}
{-# SPECIALIZE compareChi
:: Shape sh => Histogram sh Int32 -> Histogram sh Int32 -> Double
, Shape sh => Histogram sh Int32 -> Histogram sh Int32 -> Float
, Shape sh => Histogram sh Double -> Histogram sh Double -> Double
, Shape sh => Histogram sh Double -> Histogram sh Double -> Float
, Shape sh => Histogram sh Float -> Histogram sh Float -> Double
, Shape sh => Histogram sh Float -> Histogram sh Float -> Float #-}
{-# INLINABLE compareChi #-}
compareIntersect :: (Shape sh, Storable a, Num a, Ord a)
=> Histogram sh a -> Histogram sh a -> a
compareIntersect :: forall sh a.
(Shape sh, Storable a, Num a, Ord a) =>
Histogram sh a -> Histogram sh a -> a
compareIntersect (Histogram sh
sh1 Vector a
vec1) (Histogram sh
sh2 Vector a
vec2)
| sh
sh1 forall a. Eq a => a -> a -> Bool
/= sh
sh2 = forall a. HasCallStack => String -> a
error String
"Histograms are not of equal size."
| Bool
otherwise = forall a. (Storable a, Num a) => Vector a -> a
V.sum forall a b. (a -> b) -> a -> b
$ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall a. Ord a => a -> a -> a
min Vector a
vec1 Vector a
vec2
{-# SPECIALIZE compareIntersect
:: Shape sh => Histogram sh Int32 -> Histogram sh Int32 -> Int32
, Shape sh => Histogram sh Double -> Histogram sh Double -> Double
, Shape sh => Histogram sh Float -> Histogram sh Float -> Float #-}
{-# INLINABLE compareIntersect #-}
compareEMD :: (Num a, Storable a)
=> Histogram DIM1 a -> Histogram DIM1 a -> a
compareEMD :: forall a.
(Num a, Storable a) =>
Histogram DIM1 a -> Histogram DIM1 a -> a
compareEMD hist1 :: Histogram DIM1 a
hist1@(Histogram DIM1
sh1 Vector a
_) hist2 :: Histogram DIM1 a
hist2@(Histogram DIM1
sh2 Vector a
_)
| DIM1
sh1 forall a. Eq a => a -> a -> Bool
/= DIM1
sh2 = forall a. HasCallStack => String -> a
error String
"Histograms are not of equal size."
| Bool
otherwise = let Histogram DIM1
_ Vector a
vec1 = forall a.
(Storable a, Num a) =>
Histogram DIM1 a -> Histogram DIM1 a
cumulative Histogram DIM1 a
hist1
Histogram DIM1
_ Vector a
vec2 = forall a.
(Storable a, Num a) =>
Histogram DIM1 a -> Histogram DIM1 a
cumulative Histogram DIM1 a
hist2
in forall a. (Storable a, Num a) => Vector a -> a
V.sum forall a b. (a -> b) -> a -> b
$ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith (\a
v1 a
v2 -> forall a. Num a => a -> a
abs (a
v1 forall a. Num a => a -> a -> a
- a
v2)) Vector a
vec1 Vector a
vec2
{-# SPECIALIZE compareEMD
:: Histogram DIM1 Int32 -> Histogram DIM1 Int32 -> Int32
, Histogram DIM1 Double -> Histogram DIM1 Double -> Double
, Histogram DIM1 Float -> Histogram DIM1 Float -> Float #-}
{-# INLINABLE compareEMD #-}
square :: Num a => a -> a
square :: forall a. Num a => a -> a
square a
a = a
a forall a. Num a => a -> a -> a
* a
a
double :: Integral a => a -> Double
double :: forall a. Integral a => a -> Double
double= forall a b. (Integral a, Num b) => a -> b
fromIntegral
int :: Integral a => a -> Int
int :: forall a. Integral a => a -> Int
int = forall a b. (Integral a, Num b) => a -> b
fromIntegral