GithubHelp home page GithubHelp logo

raphaelj / friday Goto Github PK

View Code? Open in Web Editor NEW
276.0 276.0 19.0 12.67 MB

Fast image IO and transformations.

Home Page: https://hackage.haskell.org/package/friday

License: GNU Lesser General Public License v3.0

Haskell 100.00%

friday's People

Contributors

amrhassan avatar johnquitno avatar k-bx avatar larskuhtz avatar raphaelj avatar rycee avatar stoltene2 avatar svmhdvn avatar tarrasch avatar tommd avatar tvh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

friday's Issues

Bicubic interpolation

In cases where artifacts are critical to avoid bicubic interpolation would be nice to have.

Add to Stackage

Would you mind adding this package to Stackage? The instructions can be found here.

API thoughts

I'm fairly new to haskell (~1 year) and the only bigger lib I've used for some time now is Diagrams.

Now I was looking into basic image processing and wanted to do stuff like image noise reduction by calculating the average of a number of images.

The functions fromFunction and map are fairly basic, so I tried a few hacks like:

map2 :: (I.Image src1, I.Image src2, I.FromFunction res)
     => Size
     -> (I.ImagePixel src1 -> I.ImagePixel src2 -> I.FromFunctionPixel res)
     -> src1
     -> src2
     -> res
map2 s f img1 img2 =
  I.fromFunction s $ \pix ->
       f (img1 `I.index` pix) (img2 `I.index` pix)


foldImg :: (I.Image i, I.FromFunction i)
        => Size
        -> (I.ImagePixel i -> I.ImagePixel i -> I.FromFunctionPixel i)
        -> [i]
        -> i
foldImg s f = foldl1 (map2 s f)

Maybe I missed something, but I think this library could benefit from a more powerful interface.

Consider providing a bridge to JuicyPixels for IO

That would give a very attractive all-in-Haskell solution for the basic image processing needs of most web applications.

No need to install IMagick or similar, or a C library -- just cabal install all the way :)

Compile failure with pre-AMP base

I went ahead and added base >= 4.8 constraints:

Configuring component lib from friday-0.2.3.1
Preprocessing library friday-0.2.3.1...
[ 1 of 28] Compiling Vision.Primitive.Shape ( src/Vision/Primitive/Shape.hs, /tmp/matrix-worker/1482012292/dist-newstyle/build/x86_64-linux/ghc-7.8.4/friday-0.2.3.1/build/Vision/Primitive/Shape.o )

src/Vision/Primitive/Shape.hs:87:40:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeNew :: Control.Monad.Primitive.PrimMonad m =>
                                   Int -> m (VU.MVector (Control.Monad.Primitive.PrimState m) Z)
      at src/Vision/Primitive/Shape.hs:87:3-16
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeNew :: Control.Monad.Primitive.PrimMonad m =>
                            Int -> m (VU.MVector (Control.Monad.Primitive.PrimState m) Z)
    In the expression: MV_Z `fmap` basicUnsafeNew i
    In an equation for ‘basicUnsafeNew’:
        basicUnsafeNew i = MV_Z `fmap` basicUnsafeNew i
    In the instance declaration for ‘MVector VU.MVector Z’

src/Vision/Primitive/Shape.hs:94:38:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeFreeze :: Control.Monad.Primitive.PrimMonad m =>
                                      VG.Mutable VU.Vector (Control.Monad.Primitive.PrimState m) Z
                                      -> m (VU.Vector Z)
      at src/Vision/Primitive/Shape.hs:94:3-19
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeFreeze :: Control.Monad.Primitive.PrimMonad m =>
                               VG.Mutable VU.Vector (Control.Monad.Primitive.PrimState m) Z
                               -> m (VU.Vector Z)
    In the expression: V_Z `fmap` VG.basicUnsafeFreeze v
    In an equation for ‘basicUnsafeFreeze’:
        basicUnsafeFreeze (MV_Z v) = V_Z `fmap` VG.basicUnsafeFreeze v
    In the instance declaration for ‘VG.Vector VU.Vector Z’

src/Vision/Primitive/Shape.hs:95:39:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeThaw :: Control.Monad.Primitive.PrimMonad m =>
                                    VU.Vector Z
                                    -> m (VG.Mutable
                                            VU.Vector (Control.Monad.Primitive.PrimState m) Z)
      at src/Vision/Primitive/Shape.hs:95:3-17
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeThaw :: Control.Monad.Primitive.PrimMonad m =>
                             VU.Vector Z
                             -> m (VG.Mutable VU.Vector (Control.Monad.Primitive.PrimState m) Z)
    In the expression: MV_Z `fmap` VG.basicUnsafeThaw v
    In an equation for ‘basicUnsafeThaw’:
        basicUnsafeThaw (V_Z v) = MV_Z `fmap` VG.basicUnsafeThaw v
    In the instance declaration for ‘VG.Vector VU.Vector Z’

src/Vision/Primitive/Shape.hs:108:49:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (Unbox t, Unbox h)
      bound by the instance declaration
      at src/Vision/Primitive/Shape.hs:104:10-58
    or from (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeRead :: Control.Monad.Primitive.PrimMonad m =>
                                    VU.MVector (Control.Monad.Primitive.PrimState m) (t :. h)
                                    -> Int -> m (t :. h)
      at src/Vision/Primitive/Shape.hs:108:3-17
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeRead :: Control.Monad.Primitive.PrimMonad m =>
                             VU.MVector (Control.Monad.Primitive.PrimState m) (t :. h)
                             -> Int -> m (t :. h)
        or the instance declaration
    In the expression: pairToPoint `fmap` basicUnsafeRead v i
    In an equation for ‘basicUnsafeRead’:
        basicUnsafeRead (MV_Dim v) i
          = pairToPoint `fmap` basicUnsafeRead v i
    In the instance declaration for ‘MVector VU.MVector (t :. h)’

src/Vision/Primitive/Shape.hs:109:44:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (Unbox t, Unbox h)
      bound by the instance declaration
      at src/Vision/Primitive/Shape.hs:104:10-58
    or from (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeNew :: Control.Monad.Primitive.PrimMonad m =>
                                   Int
                                   -> m (VU.MVector (Control.Monad.Primitive.PrimState m) (t :. h))
      at src/Vision/Primitive/Shape.hs:109:3-16
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeNew :: Control.Monad.Primitive.PrimMonad m =>
                            Int
                            -> m (VU.MVector (Control.Monad.Primitive.PrimState m) (t :. h))
        or the instance declaration
    In the expression: MV_Dim `fmap` basicUnsafeNew i
    In an equation for ‘basicUnsafeNew’:
        basicUnsafeNew i = MV_Dim `fmap` basicUnsafeNew i
    In the instance declaration for ‘MVector VU.MVector (t :. h)’

src/Vision/Primitive/Shape.hs:116:42:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (MVector (VG.Mutable VU.Vector) (t :. h),
                      Unbox t,
                      Unbox h)
      bound by the instance declaration
      at src/Vision/Primitive/Shape.hs:113:10-59
    or from (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeFreeze :: Control.Monad.Primitive.PrimMonad m =>
                                      VG.Mutable
                                        VU.Vector (Control.Monad.Primitive.PrimState m) (t :. h)
                                      -> m (VU.Vector (t :. h))
      at src/Vision/Primitive/Shape.hs:116:3-19
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeFreeze :: Control.Monad.Primitive.PrimMonad m =>
                               VG.Mutable VU.Vector (Control.Monad.Primitive.PrimState m) (t :. h)
                               -> m (VU.Vector (t :. h))
        or the instance declaration
    In the expression: V_Dim `fmap` VG.basicUnsafeFreeze v
    In an equation for ‘basicUnsafeFreeze’:
        basicUnsafeFreeze (MV_Dim v) = V_Dim `fmap` VG.basicUnsafeFreeze v
    In the instance declaration for ‘VG.Vector VU.Vector (t :. h)’

src/Vision/Primitive/Shape.hs:117:43:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (MVector (VG.Mutable VU.Vector) (t :. h),
                      Unbox t,
                      Unbox h)
      bound by the instance declaration
      at src/Vision/Primitive/Shape.hs:113:10-59
    or from (Control.Monad.Primitive.PrimMonad m)
      bound by the type signature for
                 basicUnsafeThaw :: Control.Monad.Primitive.PrimMonad m =>
                                    VU.Vector (t :. h)
                                    -> m (VG.Mutable
                                            VU.Vector
                                            (Control.Monad.Primitive.PrimState m)
                                            (t :. h))
      at src/Vision/Primitive/Shape.hs:117:3-17
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeThaw :: Control.Monad.Primitive.PrimMonad m =>
                             VU.Vector (t :. h)
                             -> m (VG.Mutable
                                     VU.Vector (Control.Monad.Primitive.PrimState m) (t :. h))
        or the instance declaration
    In the expression: MV_Dim `fmap` VG.basicUnsafeThaw v
    In an equation for ‘basicUnsafeThaw’:
        basicUnsafeThaw (V_Dim v) = MV_Dim `fmap` VG.basicUnsafeThaw v
    In the instance declaration for ‘VG.Vector VU.Vector (t :. h)’

src/Vision/Primitive/Shape.hs:119:48:
    Could not deduce (Functor m) arising from a use of ‘fmap’
    from the context (MVector (VG.Mutable VU.Vector) (t :. h),
                      Unbox t,
                      Unbox h)
      bound by the instance declaration
      at src/Vision/Primitive/Shape.hs:113:10-59
    or from (Monad m)
      bound by the type signature for
                 basicUnsafeIndexM :: Monad m =>
                                      VU.Vector (t :. h) -> Int -> m (t :. h)
      at src/Vision/Primitive/Shape.hs:119:3-19
    Possible fix:
      add (Functor m) to the context of
        the type signature for
          basicUnsafeIndexM :: Monad m =>
                               VU.Vector (t :. h) -> Int -> m (t :. h)
        or the instance declaration
    In the expression: pairToPoint `fmap` VG.basicUnsafeIndexM v i
    In an equation for ‘basicUnsafeIndexM’:
        basicUnsafeIndexM (V_Dim v) i
          = pairToPoint `fmap` VG.basicUnsafeIndexM v i
    In the instance declaration for ‘VG.Vector VU.Vector (t :. h)

Remove the hard dependency between friday and DevIL

The dependency between friday and DevIL will be removed in friday 0.2.

I/O functions will be provided by two separate packages, friday-devil and friday-juicypixels. Both will use a different I/O backend.

Warnings when compiling my code using the Friday library: "match_co: needs more cases"

Hi, sorry if this is a simple question (I'm new to Haskell), but
I'm using Friday in an application for some simple
image operations (source).

Did I do something wrong to cause the following warning message when compiling? Full build info is available at https://travis-ci.org/bamos/augment/builds/62451721

match_co: needs more cases
    friday-0.2.1.2:Vision.Image.Type.TFCo:R:ImagePixelManifest{tc r3AS}[0]
      (Sym
         (friday-0.2.1.2:Vision.Image.Type.TFCo:R:FromFunctionPixelManifest{tc r3B9}[0]
            <friday-0.2.1.2:Vision.Image.RGB.Type.RGBPixel{tc ray}>_N))

Does not compile with stackage lts-7 & ghc-8

cat /root/ocr/learn/learn/.stack-work/logs/friday-0.2.2.0.log

Configuring friday-0.2.2.0...
setup-Simple-Cabal-1.24.0.0-ghc-8.0.1: Encountered missing dependencies:
transformers >=0.3 && <0.5 && ==0.5.2.0

Q: indication from creating an image painting a rectangle with specified rgb

Hi,
thansk for sharing this very helpful library, samples and additional documentation. I'm new to Haskell and even new to this library (since after some research I think this is the more suitable for the thing I'm trying to do).

What I'm trying to do is translating this F# snippet for Random Art: http://fssnip.net/si.

To implement the function draw at line 122, I must be able to:

  • set up an image of defined height and width
  • draw a rectangle with coordinates (x,y) and its height/width with the specified R,G,B

Can I have some indications for accomplish this task and put me on right direction, if possible.

Thanks, Giacomo.

P.S.: finished the porting, I obviously share my work.

ImageType from Storage.hsc

Hello! Just tried to use your library, but found one bad thing.

When I am writing something like

image :: Maybe Vision.Image.Storage.ImageType -> IO (Either StorageError StorageImage)
image = load "img.png"

Compiler is arguing that type constructor or class Vision.Image.Storage.ImageType`` is not in scope. Please, export ImageType constructor from Storage.hsc.

BTW, it will be great to write something like

image :: IO (Either StorageError StorageImage)
image = load "img.png" PNG

Best wishes!

Add pre-multiplied RGBA

Some operations are more efficient with pre-multiplied RGBA. The conversion from RGBA to RGB assumes normal RGBA. I'm not sure what else does, but I bet a lot of code could be shared with a newtype.

Add contour support

Contours are obviously a common mechanism to filter out unwanted artifacts based on facts such as size and dimensions. It would be nice if Friday included contours.

[1] Topological Structural Analysis of Digitized Binary Images by Border Following

draw shapes

Sorry if this is a really banal question, but how can I draw simple shapes like rectangles and ovals using friday?

How can I construct (and destruct) masked images?

I have some problems with using masked images. I try to create a masked image from a normal one by using a fromFunction and although the function itself compiles correctly, the application of the function yields a type error during compilation. I set up an equivalent example to illustrate the problem as my original function is a bit complex.

{-# LANGUAGE ScopedTypeVariables, TypeFamilies #-}

import Vision.Image
import Vision.Image.Storage.DevIL (Autodetect (..), load)
import Vision.Primitive


maskImage :: (Image i1, FromFunction i,
              FromFunctionPixel i ~ Maybe (ImagePixel i1))
          => i1 -> i
maskImage img = fromFunction (shape img) maskPixel
    where maskPixel p = Just $ img `index` p


main = do
    io <- load Autodetect "../test.jpg"

    case io of
        Right (rgb :: RGB) -> do
            let i' = maskImage rgb

            print "Processed image"

The snippet yields the compilation error:

Main.hs:27:22:
    Couldn't match type ‘FromFunctionPixel i0’ with ‘Maybe RGBPixel’
    The type variable ‘i0’ is ambiguous
    Expected type: Maybe (ImagePixel RGB)
      Actual type: FromFunctionPixel i0
    Relevant bindings include i' :: i0 (bound at Main.hs:27:17)
    In the expression: maskImage rgb
    In an equation for ‘i'’: i' = maskImage rgb
    In the expression:
      do { let i' = maskImage rgb;
           print "Processed image" }

I also tried to create to unmask the image afterwards but this didn't work either. So how would one create a masked image with fromFunction and destruct it later again? Or why doesn't my code compile correctly?

Background: I try to implement an image registration algorithm. One step of the algorithm is to interpolate the moved image at the points of the orgiinal image. As usually not all pixels of the original and the moved image overlap, a masked image was my data structure of choice to represent the result of this processing step.

Blurring RGB images?

Right now the functions blur and gaussianBlur in Vision.Image.Filter impose the constraint Integral (ImagePixel src) on the source image. However, this seems like an unnecessary constraint, which prevents one from, for example, blurring RGB or RGBA images. As I understand it, only addition and multiplication (by a scalar) operations are required for the pixels in order to do the convolution. One could sensibly define these operations for RGB and RGBA pixels. Maybe one could find or define a weaker typeclass to use as a constraint. Another option would be to have an intermediate function which would allow applying a filter component-wise.

Test-suite failure for friday-0.2.3.2 on stackage ghc-9.4.5/nightly-2023-06-19

During stackage build - skip tests during stackage build for now...

Images:
  Conversions identities:
    RGB to/from RGBA: [OK, passed 100 tests]
    RGB to/from HSV: [OK, passed 100 tests]
  Nearest-neighbor resize:
    Grey: [OK, passed 100 tests]
    RGBA: [OK, passed 100 tests]
    RGB: [OK, passed 100 tests]
  Horizontal flip is symetric:
    Grey: [OK, passed 100 tests]
    RGBA: [OK, passed 100 tests]
    RGB: [OK, passed 100 tests]
  Vertical flip is symetric:
    Grey: [OK, passed 100 tests]
    RGBA: [OK, passed 100 tests]
    RGB: [OK, passed 100 tests]
  Storable can roundtrip:
    HSVPixel: [OK, passed 100 tests]
    RGBPixel: [OK, passed 100 tests]
    RGBAPixel: [OK, passed 100 tests]
Histograms:
  Sum of bins equals the number of pixels: [OK, passed 100 tests]
  The reduction of a 2D histogram gives the linear one.: [OK, passed 100 tests]
  Resizing an histogram equals computing the smallest one.: [OK, passed 100 tests]
  Cumulative histogram last bin equals original's sum: [OK, passed 100 tests]
  Sum of an normalized histogram equals its size: [Failed]
*** Failed! Falsified (after 56 tests and 1 shrink):
0.5
Histogram {shape = Z :. 256, vector = [2588874,3760359,720623,88493,4765925,5214786,5380910,4626141,7918821,7446416,3783668,612062,4038479,7289132,1352859,3938527,5584479,5991528,3790679,1200055,7266956,6545644,8350728,6068,5911822,80365,5815394,8125574,1552477,8335872,1895585,2522358,8060338,1630125,8048094,7093748,7597141,7055715,7801283,5166461,3218385,1981296,5122197,5018516,3416502,5994008,4118715,3241077,518360,1226086,6173995,6581931,46094,7641231,5976849,3941604,7141244,3355327,425080,3985695,3981092,3873933,5876040,7122121,1830567,4239503,2460593,550065,5182582,5078395,3343104,8065700,1464768,8359395,7670869,8037245,5099700,1688109,1547349,7559159,3163754,4926297,7557779,2010891,286426,6590163,6801928,5160241,3242684,6813917,209062,2272301,4675019,6401681,3307865,1083211,2977412,1556369,5435021,1100831,2097022,2774904,6543436,775072,2815747,8313874,2255342,7961863,1752217,719501,5029710,972296,7493596,4910195,6976062,2933023,5634015,6137366,3574115,115922,7106588,3627508,383144,612447,2000036,8039585,1080023,2244073,2028864,1801145,1387871,6200798,4511775,3552288,8221410,6203173,6348402,345730,180126,703001,3561976,5401644,7454871,5123947,98963,2149606,4542793,5665716,3171722,4873149,2723720,2111702,3397665,534161,936519,1951229,4938908,835757,2239384,1509722,8384313,7575338,7262226,7188603,6687242,5462495,4964740,2498214,7811518,5866802,325808,1731506,6396768,7648192,7317367,4119641,5177891,4527696,8280161,4758006,506218,502291,4842982,3916590,2181837,6795571,2760904,3965138,3826875,1245163,4394544,8171111,6559579,3994998,3581740,3324137,5249736,3135469,7686012,3746885,5540664,626998,1227559,6233003,6200155,6514254,7908587,3388038,6394697,4497512,1935612,1930081,5635603,3937621,627211,8177324,6301896,1151766,7362785,5810577,3976349,1822969,945906,3436015,7360081,2905572,7804879,4769035,8328918,7274822,7925791,8002429,7719314,2394158,5364619,3419256,469723,3866018,3586478,166900,485407,7298211,2013272,2007539,5932427,1893309,7353049,5867370,5398137,672492,95457,4466659,1751082,644808,1630605,7451234]}
(used seed 1704976077533009389)
  Comparing the same histogram returns a perfect correlation: [OK, passed 100 tests]
  Comparing the same histogram returns a 0 chi-square value: [OK, passed 100 tests]
  The intersection of an histogram with itself is the sum of its values.: [OK, passed 100 tests]
  Comparing the same histogram returns a 0 EMD value: [OK, passed 100 tests]
Primitives:
  Storable can roundtrip:
    DIM0: [OK, passed 100 tests]
    DIM1: [OK, passed 100 tests]
    DIM2: [OK, passed 100 tests]
    DIM3: [OK, passed 100 tests]
    DIM4: [OK, passed 100 tests]
    DIM5: [OK, passed 100 tests]
    DIM6: [OK, passed 100 tests]
    DIM7: [OK, passed 100 tests]
    DIM8: [OK, passed 100 tests]
    DIM9: [OK, passed 100 tests]

         Properties   Total
 Passed  32           32
 Failed  1            1
 Total   33           33

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.