Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Although the following code is hackish, it is pretty fast.</p> <ul> <li><p>Proceeds 75x75 image in 0.03 ms (16 tics / pixel) => approx. 10-20 ms for 300 images</p></li> <li><p>512x512 (Lenna) in 1 ms (13.5 tics / pixel)</p></li> <li><p>2560x1600 in 12 ms (9.2 tics / pixel)</p></li> </ul> <p><code>yarr</code> was specially designed to solve the tasks like yours, unfortunately there are some problems (pointed in comments to the code) which don't allow to make the code really succinct and fast simultaneously.</p> <p>One pixel routine is 3 memory reads + 3 <code>add</code>s, so I roughly expect 3 tics / pixel as the limit of this task.</p> <p>Your can also easily parallelize computation using <a href="http://hackage.haskell.org/packages/archive/parallel-io/0.3.3/doc/html/Control-Concurrent-ParallelIO-Global.html#v%3aparallel" rel="nofollow"><code>parallel</code></a> from <code>parallel-io</code> package.</p> <pre><code>{-# LANGUAGE FlexibleContexts, TypeFamilies #-} import System.Environment import Data.Yarr import Data.Yarr.IO.Image import Data.Yarr.Walk import Data.Yarr.Utils.FixedVector as V import Data.Yarr.Shape as S main :: IO () main = do [file] &lt;- getArgs print =&lt;&lt; getAverage file getAverage :: FilePath -&gt; IO (Int, Int, Int) getAverage file = do -- Meaningful choice, for homogenious images, -- in preference to readRGB(Vectors). -- readRGB make the case of representation -&gt; polymorfic access -&gt; -- poor performance (RGB imageArr) &lt;- readImage file -- let imageArr = readRGBVectors file let ext = extent imageArr avs &lt;- averageColour imageArr return $ V.inspect avs (Fun (,,)) averageColour :: (Vector v Int, Dim v ~ N3, Integral e, UVecSource r slr l Dim2 v e, PreferredWorkIndex l Dim2 i) =&gt; UArray r l Dim2 (v e) -&gt; IO (VecList N3 Int) {-# INLINE averageColour #-} averageColour image = fmap (V.map (`div` (w * h))) compSums where -- `walk (reduce ... (V.zipWith (+))) (return V.zero) image` -- would be more idiomatic and theoretically faster, -- but had problems with perf too :( compSums = walkSlicesSeparate sum (return 0) image -- would better to `mapElems fromIntegral imageArr` before counting, -- but faced some performance problems and I have no time to dig them {-# INLINE sum #-} sum = reduceL sumFold (\x y -&gt; x + (fromIntegral y)) sumFold = S.unrolledFoldl n8 noTouch (w, h) = extent image </code></pre> <p>Compile</p> <pre><code>ghc-7.6.1 --make -Odph -rtsopts -threaded -fno-liberate-case -funbox-strict-fields -funfolding-keeness-factor1000 -fllvm -optlo-O3 -fexpose-all-unfoldings -fsimpl-tick-factor=500 -o avc average-color.hs </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload