-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Compose a collage from overlapping image parts. In contrast to Hugin, -- this is not intended for creating panoramas from multiple -- photographies, but instead is specialised to creating highly accurate -- reconstructions of flat but big image sources, like record covers, -- posters or newspapers. It solves the problem that your scanner may be -- too small to capture a certain image as a whole. -- -- Restrictions: -- -- @package patch-image-cuda module Option.Utility parseNumber :: Read a => String -> (a -> Bool) -> String -> String -> IO a exitFailureMsg :: String -> IO a fmapArgDescr :: (a -> b) -> (ArgDescr a -> ArgDescr b) fmapOptDescr :: (a -> b) -> (OptDescr a -> OptDescr b) module LinearAlgebra absolutePositionsFromPairDisplacements :: Int -> [((Int, Int), (Float, Float))] -> ([(Double, Double)], [(Double, Double)]) leastSquaresSelected :: Matrix Double -> [Maybe Double] -> ([Double], [Double]) layoutFromPairDisplacements :: Int -> [((Int, (Float, Float)), (Int, (Float, Float)))] -> ([((Double, Double), Complex Double)], [(Double, Double)]) module Arithmetic inBox :: (Ord a, Num a) => (a, a) -> (a, a) -> Bool rotatePoint :: Num a => (a, a) -> (a, a) -> (a, a) rotateStretchMovePoint :: Fractional a => (a, a) -> (a, a) -> (a, a) -> (a, a) rotateStretchMoveBackPoint :: Fractional a => (a, a) -> (a, a) -> (a, a) -> (a, a) boundingBoxOfRotated :: (Num a, Ord a) => (a, a) -> (a, a) -> ((a, a), (a, a)) boundingBoxOfRotatedGen :: Num a => (a -> a -> a, a -> a -> a) -> (a, a) -> (a, a) -> ((a, a), (a, a)) canvasShape :: (RealFrac a, Integral i, PrintfArg a, PrintfArg i) => (image -> (i, i)) -> [Point2 a] -> [((a, a), image)] -> ((i, i), [((a, a), (a, a), image)], [String]) linearIp :: Num a => (a, a) -> a -> a cubicIp :: Fractional a => (a, a, a, a) -> a -> a data Vec a v Vec :: v -> (v -> v -> v) -> (a -> v -> v) -> Vec a v vecZero :: Vec a v -> v vecAdd :: Vec a v -> v -> v -> v vecScale :: Vec a v -> a -> v -> v vecScalar :: Num a => Vec a a linearIpVec :: Num a => Vec a v -> (v, v) -> a -> v cubicIpVec :: Fractional a => Vec a v -> (v, v, v, v) -> a -> v smooth3 :: Fractional a => (a, a, a) -> a type Point2 a = (a, a) type Line2 a = (Point2 a, Point2 a) intersect :: (Ord a, Fractional a) => Line2 a -> Line2 a -> Maybe (Point2 a) intersections :: (Fractional a, Ord a) => [Line2 a] -> [Line2 a] -> [Point2 a] type Geometry i a = ((a, a), (a, a), (i, i)) geometryFeatures :: (Fractional a, Integral i) => Geometry i a -> (Geometry i a, [Point2 a], [Line2 a]) geometryRelations :: (RealFrac a, Integral i) => [(Geometry i a, [Point2 a], [Line2 a])] -> [(Geometry i a, [Geometry i a], [Point2 a])] projectPerp :: Fractional a => Point2 a -> (Point2 a, Point2 a) -> (a, Point2 a) distanceSqr :: Num a => Point2 a -> Point2 a -> a distance :: Floating a => Point2 a -> Point2 a -> a linearScale :: Fractional a => Int -> (a, a) -> [a] minimumOverlapAbsFromPortion :: Integral i => Float -> (i, i) -> i ceilingPow2 :: (Bits i, Integral i) => i -> i ceilingSmooth7 :: (Bits i, Integral i) => i -> i ceilingSmooth7_100 :: (Bits i, Integral i) => i -> i -- | Rounds to the smallest number of the form 2^k*j, with k>=0 and -- 1<=j<=10 that is at least as large as n. ceilingSmooth7_10 :: (Bits i, Integral i) => i -> i divideByMaximumPower :: Integral i => i -> i -> i (^!) :: Num a => a -> Int -> a isSmooth7NumberReduce :: Integral i => i -> Bool isSmooth7NumberDiv :: Integral i => i -> Bool propIsSmooth7Number :: Bool correlationSize :: (Bits i, Integral i) => Float -> [(i, i)] -> (i, i) divUp :: Integral a => a -> a -> a pairFromComplex :: RealFloat a => Complex a -> (a, a) mapComplex :: (a -> b) -> Complex a -> Complex b mulConj :: RealFloat a => Complex a -> Complex a -> Complex a module Option data Args Args :: Option -> [(Image, FilePath)] -> Args option :: Args -> Option inputs :: Args -> [(Image, FilePath)] defltArgs :: Args data Option Option :: Verbosity -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Int -> Float -> Int -> Bool -> Int -> Int -> Float -> Float -> Bool -> Int -> Int -> Float -> Int -> Option verbosity :: Option -> Verbosity output :: Option -> Maybe FilePath outputHard :: Option -> Maybe FilePath outputShaped :: Option -> Maybe FilePath outputShapedHard :: Option -> Maybe FilePath outputOverlap :: Option -> Maybe String outputDistanceMap :: Option -> Maybe String outputShape :: Option -> Maybe String outputShapeHard :: Option -> Maybe String quality :: Option -> Int maximumAbsoluteAngle :: Option -> Float numberAngleSteps :: Option -> Int radonTransform :: Option -> Bool smooth :: Option -> Int padSize :: Option -> Int minimumOverlap :: Option -> Float maximumDifference :: Option -> Float finetuneRotate :: Option -> Bool numberStamps :: Option -> Int stampSize :: Option -> Int distanceGamma :: Option -> Float shapeSmooth :: Option -> Int defltOption :: Option data Image Image :: Maybe Float -> Image angle :: Image -> Maybe Float defltImage :: Image data Engine Knead :: Engine Accelerate :: Engine type EngineSet = T Word8 Engine knead :: EngineSet generic :: EngineSet accelerate :: EngineSet type Description a = [OptDescr (a -> IO a)] type EngineDescription a = [(EngineSet, OptDescr (a -> IO a))] opt :: EngineSet -> [Char] -> [String] -> ArgDescr a -> String -> (EngineSet, OptDescr a) optionDescription :: Description a -> EngineDescription Option description :: Description (Image, Args) -> EngineDescription (Image, Args) addFile :: FilePath -> ((Image, Args) -> IO (Image, Args)) get :: Engine -> IO Args instance Eq Image instance Eq Engine instance Ord Engine instance Enum Engine module Main readImage :: Verbosity -> FilePath -> IO (Array DIM3 Word8) writeImage :: Int -> FilePath -> Array DIM3 Word8 -> IO () writeGrey :: Int -> FilePath -> Array DIM2 Word8 -> IO () colorImageExtent :: Array DIM3 Word8 -> (Int, Int) imageFloatFromByte :: (Shape sh, Elt a, IsFloating a) => Acc (Array sh Word8) -> Acc (Array sh a) imageByteFromFloat :: (Shape sh, Elt a, IsFloating a) => Acc (Array sh a) -> Acc (Array sh Word8) cycleLeftDim3 :: Exp DIM3 -> Exp DIM3 cycleRightDim3 :: Exp DIM3 -> Exp DIM3 separateChannels :: Elt a => Acc (Array DIM3 a) -> Acc (Array DIM3 a) interleaveChannels :: Elt a => Acc (Array DIM3 a) -> Acc (Array DIM3 a) fastRound :: (Elt i, IsIntegral i, Elt a, IsFloating a) => Exp a -> Exp i floatArray :: Acc (Array sh Float) -> Acc (Array sh Float) splitFraction :: (Elt a, IsFloating a) => Exp a -> (Exp Int, Exp a) type Channel ix a = Array ((ix :. Int) :. Int) a type ExpDIM2 ix = (Exp ix :. Exp Int) :. Exp Int type ExpDIM3 ix = ((Exp ix :. Exp Int) :. Exp Int) :. Exp Int unliftDim2 :: Slice ix => Exp ((ix :. Int) :. Int) -> ExpDIM2 ix indexLimit :: (Slice ix, Shape ix, Elt a) => Acc (Channel ix a) -> ExpDIM2 ix -> Exp a indexFrac :: (Slice ix, Shape ix, Elt a, IsFloating a) => Acc (Channel ix a) -> (Exp ix :. Exp a) :. Exp a -> Exp a rotateStretchMoveCoords :: (Elt a, IsFloating a) => (Exp a, Exp a) -> (Exp a, Exp a) -> (Exp Int, Exp Int) -> Acc (Channel Z (a, a)) inBox :: (Elt a, IsNum a, IsScalar a) => (Exp a, Exp a) -> (Exp a, Exp a) -> Exp Bool validCoords :: (Elt a, IsFloating a) => (Exp Int, Exp Int) -> Acc (Channel Z (a, a)) -> Acc (Channel Z Bool) replicateChannel :: (Slice ix, Shape ix, Elt a) => Exp ((ix :. Int) :. Int) -> Acc (Channel Z a) -> Acc (Channel ix a) -- | rotateStretchMove rot mov first rotate and stretches the -- image according to rot and then moves the picture. rotateStretchMove :: (Slice ix, Shape ix, Elt a, IsFloating a) => (Exp a, Exp a) -> (Exp a, Exp a) -> ExpDIM2 ix -> Acc (Channel ix a) -> (Acc (Channel Z Bool), Acc (Channel ix a)) rotateLeftTop :: (Slice ix, Shape ix, Elt a, IsFloating a) => (Exp a, Exp a) -> Acc (Channel ix a) -> ((Acc (Scalar a), Acc (Scalar a)), Acc (Channel ix a)) rotate :: (Slice ix, Shape ix, Elt a, IsFloating a) => (Exp a, Exp a) -> Acc (Channel ix a) -> Acc (Channel ix a) brightnessPlane :: (Slice ix, Shape ix) => Acc (Channel (ix :. Int) Float) -> Acc (Channel ix Float) rowHistogram :: Acc (Channel DIM1 Float) -> Acc (Array DIM1 Float) rotateHistogram :: Float -> Array DIM3 Word8 -> (Array DIM3 Word8, Array DIM1 Float) analyseRotations :: [Float] -> Array DIM3 Word8 -> IO () differentiate :: (Elt a, IsNum a) => Acc (Array DIM1 a) -> Acc (Array DIM1 a) scoreRotation :: Float -> Array DIM3 Word8 -> Float findOptimalRotation :: [Float] -> Array DIM3 Word8 -> Float magnitudeSqr :: (Elt a, IsNum a) => Exp (Complex a) -> Exp a fourierTransformationRun :: Array DIM3 Word8 -> IO (Array DIM2 Word8) fourierTransformation :: Option -> FilePath -> Array DIM3 Word8 -> IO () scoreSlopes :: (Elt a, IsFloating a) => (Exp Int, Exp Int) -> Acc (Channel Z (Complex a)) -> Acc (Array DIM1 a) radonAngle :: (Float, Float) -> Array DIM3 Word8 -> IO Float rotateManifest :: Float -> Array DIM3 Word8 -> Array DIM3 Float prepareOverlapMatching :: Int -> (Float, Array DIM3 Word8) -> ((Float, Float), Channel Z Float) ceilingPow2 :: Exp Int -> Exp Int pad :: Elt a => Exp a -> Exp DIM2 -> Acc (Channel Z a) -> Acc (Channel Z a) mulConj :: (Elt a, IsFloating a) => Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a) fft2DGen :: (Elt e, Real e) => Mode DIM2 e a b -> DIM2 -> Transform DIM2 a b fft2DPlain :: (Elt e, Real e, Elt a, Elt b) => Mode DIM2 e a b -> Channel Z a -> Acc (Channel Z b) fft2D :: (Elt e, Real e, Elt a, Elt b) => Mode DIM2 e a b -> Int -> Int -> Acc (Channel Z a) -> Acc (Channel Z b) correlateImpossible :: (Elt a, Real a) => Acc (Channel Z a) -> Acc (Channel Z a) -> Acc (Channel Z a) removeDCOffset :: (Elt a, IsFloating a) => Acc (Channel Z a) -> Acc (Channel Z a) clearDCCoefficient :: (Elt a, IsFloating a) => Acc (Array DIM2 (Complex a)) -> Acc (Array DIM2 (Complex a)) lowpass :: (Elt a, IsFloating a) => Exp Int -> Acc (Channel Z a) -> Acc (Channel Z a) highpass :: (Elt a, IsFloating a) => Exp Int -> Acc (Channel Z a) -> Acc (Channel Z a) correlatePaddedSimple :: (Elt a, Real a) => DIM2 -> Acc (Channel Z a) -> Acc (Channel Z a) -> Acc (Channel Z a) correlatePadded :: (Elt a, Real a) => DIM2 -> Acc (Channel Z a) -> Acc (Channel Z a) -> Acc (Channel Z a) wrap :: Exp Int -> Exp Int -> Exp Int -> Exp Int displacementMap :: Exp Int -> Exp Int -> Exp DIM2 -> Acc (Channel Z (Int, Int)) attachDisplacements :: (Elt a, IsScalar a) => Exp Int -> Exp Int -> Acc (Channel Z a) -> Acc (Channel Z (a, (Int, Int))) -- | Set all scores to zero within a certain border. Otherwise the matching -- algorithm will try to match strong bars at the borders that are -- actually digitalization artifacts. minimumOverlapScores :: (Elt a, IsFloating a, IsScalar a) => ((Exp Int, Exp Int) -> Exp a -> Exp a) -> Exp Int -> (Exp Int, Exp Int) -> (Exp Int, Exp Int) -> Acc (Channel Z (a, (Int, Int))) -> Acc (Channel Z (a, (Int, Int))) allOverlaps :: DIM2 -> Exp Float -> Acc (Channel Z Float) -> Acc (Channel Z Float) -> Acc (Channel Z (Float, (Int, Int))) allOverlapsRun :: DIM2 -> Float -> Channel Z Float -> Channel Z Float -> Channel Z Word8 optimalOverlap :: DIM2 -> Float -> Channel Z Float -> Channel Z Float -> (Float, (Int, Int)) shrink :: (Slice ix, Shape ix, Elt a, IsFloating a) => GenDIM2 (Exp Int) -> Acc (Channel ix a) -> Acc (Channel ix a) type GenDIM2 a = (Z :. a) :. a shrinkFactors :: Integral a => DIM2 -> GenDIM2 a -> GenDIM2 a -> GenDIM2 a optimalOverlapBig :: DIM2 -> Float -> Channel Z Float -> Channel Z Float -> (Float, (Int, Int)) clip :: (Slice ix, Shape ix, Elt a) => (Exp Int, Exp Int) -> (Exp Int, Exp Int) -> Acc (Channel ix a) -> Acc (Channel ix a) overlappingArea :: (Ord a, Num a) => GenDIM2 a -> GenDIM2 a -> (a, a) -> ((a, a), (a, a), (a, a)) optimalOverlapBigFine :: DIM2 -> Float -> Channel Z Float -> Channel Z Float -> (Float, (Int, Int)) optimalOverlapBigMulti :: DIM2 -> DIM2 -> Int -> Float -> Float -> Channel Z Float -> Channel Z Float -> [(Float, (Int, Int), (Int, Int))] overlapDifference :: (Slice ix, Shape ix, Elt a, IsFloating a) => (Exp Int, Exp Int) -> Acc (Channel ix a) -> Acc (Channel ix a) -> Acc (Scalar a) overlapDifferenceRun :: (Int, Int) -> Channel Z Float -> Channel Z Float -> Float overlap2 :: (Slice ix, Shape ix) => (Exp Int, Exp Int) -> (Acc (Channel ix Float), Acc (Channel ix Float)) -> Acc (Channel ix Float) composeOverlap :: (Int, Int) -> ((Float, Array DIM3 Word8), (Float, Array DIM3 Word8)) -> Array DIM3 Word8 emptyCountCanvas :: (Slice ix, Shape ix) => (ix :. Int) :. Int -> (Channel Z Int, Channel ix Float) addToCountCanvas :: (Slice ix, Shape ix, Elt a, IsNum a) => (Acc (Channel Z Bool), Acc (Channel ix a)) -> (Acc (Channel Z Int), Acc (Channel ix a)) -> (Acc (Channel Z Int), Acc (Channel ix a)) updateCountCanvas :: ((Float, Float), (Float, Float), Array DIM3 Word8) -> (Channel Z Int, Channel DIM1 Float) -> (Channel Z Int, Channel DIM1 Float) finalizeCountCanvas :: (Channel Z Int, Channel DIM1 Float) -> Array DIM3 Word8 maybePlus :: Elt a => (Exp a -> Exp a -> Exp a) -> Exp (Bool, a) -> Exp (Bool, a) -> Exp (Bool, a) maskedMinimum :: (Shape ix, Elt a, IsScalar a) => Vector ix (Bool, a) -> Scalar ix (Bool, a) maskedMaximum :: (Shape ix, Elt a, IsScalar a) => Vector ix (Bool, a) -> Scalar ix (Bool, a) project :: (Elt a, IsFloating a) => Point2 (Exp a) -> (Point2 (Exp a), Point2 (Exp a)) -> (Exp Bool, Point2 (Exp a)) distanceMapEdges :: (Elt a, IsFloating a) => Exp DIM2 -> Acc (Array DIM1 ((a, a), (a, a))) -> Acc (Channel Z a) distanceMapEdgesRun :: DIM2 -> Array DIM1 ((Float, Float), (Float, Float)) -> Channel Z Word8 type Geometry a = Geometry Int a distanceMapBox :: (Elt a, IsFloating a) => Exp DIM2 -> Exp (Geometry a) -> Acc (Channel Z (Bool, (((a, (a, a)), (a, (a, a))), ((a, (a, a)), (a, (a, a)))))) outerVector :: (Slice ix, Shape ix, Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> Scalar ix a -> Vector Z b -> Vector ix c separateDistanceMap :: Elt a => Acc (Channel Z (Bool, ((a, a), (a, a)))) -> Acc (Array DIM3 (Bool, a)) distanceMapBoxRun :: DIM2 -> ((Float, Float), (Float, Float), (Int, Int)) -> Channel Z Word8 -- | We use it as a work-around. Fusion of fold1 and -- replicate would be very welcome but it seems to fail with -- current accelerate version. breakFusion :: Arrays a => Acc a -> Acc a array1FromList :: Elt a => [a] -> Array DIM1 a containedAnywhere :: (Elt a, IsFloating a) => Acc (Array DIM1 (Geometry a)) -> Acc (Array DIM3 (a, a)) -> Acc (Array DIM3 Bool) distanceMapContained :: (IsFloating a, Elt a) => Exp DIM2 -> Exp (Geometry a) -> Acc (Array DIM1 (Geometry a)) -> Acc (Channel Z a) distanceMapContainedRun :: DIM2 -> Geometry Float -> [Geometry Float] -> Channel Z Word8 pixelCoordinates :: (Elt a, IsFloating a) => Exp DIM2 -> Acc (Channel Z (a, a)) distanceMapPoints :: (Slice ix, Shape ix, Elt a, IsFloating a) => Acc (Array ix (a, a)) -> Acc (Array DIM1 (a, a)) -> Acc (Array ix a) distanceMapPointsRun :: DIM2 -> [Point2 Float] -> Channel Z Word8 -- | For every pixel it computes the distance to the closest point on the -- image part boundary which lies in any other image. The rationale is -- that we want to fade an image out, wherever is another image that can -- take over. Such a closest point can either be a perpendicular point at -- one of the image edges, or it can be an image corner or an -- intersection between this image border and another image border. The -- first kind of points is computed by distanceMapContained and -- the second kind by distanceMapPoints. We simply compute the -- distances to all special points and chose the minimal distance. distanceMap :: (Elt a, IsFloating a) => Exp DIM2 -> Exp (Geometry a) -> Acc (Array DIM1 (Geometry a)) -> Acc (Array DIM1 (a, a)) -> Acc (Channel Z a) distanceMapRun :: DIM2 -> Geometry Float -> [Geometry Float] -> [Point2 Float] -> Channel Z Word8 distanceMapGamma :: (Elt a, IsFloating a) => Exp a -> Exp DIM2 -> Exp (Geometry a) -> Acc (Array DIM1 (Geometry a)) -> Acc (Array DIM1 (a, a)) -> Acc (Channel Z a) emptyWeightedCanvas :: (Slice ix, Shape ix) => (ix :. Int) :. Int -> (Channel Z Float, Channel ix Float) addToWeightedCanvas :: (Slice ix, Shape ix, Elt a, IsNum a) => (Acc (Channel Z a), Acc (Channel ix a)) -> (Acc (Channel Z a), Acc (Channel ix a)) -> (Acc (Channel Z a), Acc (Channel ix a)) updateWeightedCanvasMerged :: Geometry Float -> [Geometry Float] -> [Point2 Float] -> Array DIM3 Word8 -> (Channel Z Float, Channel DIM1 Float) -> (Channel Z Float, Channel DIM1 Float) updateWeightedCanvas :: Float -> Geometry Float -> [Geometry Float] -> [Point2 Float] -> Array DIM3 Word8 -> (Channel Z Float, Channel DIM1 Float) -> (Channel Z Float, Channel DIM1 Float) updateWeightedCanvasSplit :: Geometry Float -> [Geometry Float] -> [Point2 Float] -> Array DIM3 Word8 -> (Channel Z Float, Channel DIM1 Float) -> (Channel Z Float, Channel DIM1 Float) finalizeWeightedCanvas :: (Channel Z Float, Channel DIM1 Float) -> Array DIM3 Word8 processOverlap :: Args -> [(Float, Array DIM3 Word8)] -> [((Int, (FilePath, ((Float, Float), Channel Z Float))), (Int, (FilePath, ((Float, Float), Channel Z Float))))] -> IO ([(Float, Float)], [((Float, Float), Array DIM3 Word8)]) processOverlapRotate :: Args -> [(Float, Array DIM3 Word8)] -> [((Int, (FilePath, ((Float, Float), Channel Z Float))), (Int, (FilePath, ((Float, Float), Channel Z Float))))] -> IO ([(Float, Float)], [((Float, Float), Array DIM3 Word8)]) process :: Args -> IO () main :: IO ()