Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lanczos resampling #38

Open
kirisaki opened this issue May 3, 2020 · 6 comments
Open

Lanczos resampling #38

kirisaki opened this issue May 3, 2020 · 6 comments

Comments

@kirisaki
Copy link
Contributor

kirisaki commented May 3, 2020

Description

I thought "Bicubic" which is used in raster graphic editors like Photoshop, GIMP and so on used "Bicubic interpolation", but, I hear that they really use Lanczos filter or Mitchell-Netravali filter (This so confused me!:confused:).

I want to downsize images so need Lanczos filter and plan to implement it. Lanczos filter takes a positive integer value as the size of the kernel. I have three suggestions about implementation.

Implementation

A. Let ADT have the kernel size

Define such that:

data Lanczos = Lanczos Natural

This way is simple but needs to allocate memory by dynamic way, so it maybe causes slow.

B. Let the name of ADT have kernel size

data Lanczos3 = Lanczos3

This way is simple too, but not cool. To take into account that it can use several kernel sizes only, this selection may be good. And it require implementation each data type, so not need dynamic memory allocation.

C. Use type level number

Black magic:

data Lanczos (n :: Nat) = Lanczos

instance Interpolation (Lanczos 3) where
...

The way of implementation is same as B, but looks cooler. It requires type annotation to use:

writeImage "sample.jpg" $ resize (Lanczos :: Lanczos 3) Edge (300, 400) img

D. Implement only Lanczos-3

It's a possibly.

@lehins
Copy link
Owner

lehins commented May 3, 2020

I think the suggested approach C. is the best one. Making it even slightly more general would be even better:

data Lanczos (n :: Nat) = Lanczos

instance (KnownNat n, 1 <= n) => Interpolation (Lanczos n) where

Later it would be possible to simplify it for users a bit with PatternSynonyms, which can be defined for common case of 2 through 4

type Lanczos2 = Lanczos 2
pattern Lanczos2 :: Lanczos2
pattern Lanczos2 = Lanczos

type Lanczos3 = Lanczos 3
pattern Lanczos3 :: Lanczos3
pattern Lanczos3 = Lanczos

type Lanczos4 = Lanczos 4
pattern Lanczos4 :: Lanczos4
pattern Lanczos4 = Lanczos

@lehins
Copy link
Owner

lehins commented May 3, 2020

Regardless of the approach if at least one of those is implemented (eg. Lanczos3 ) then we can refactor to make it more general later

@kirisaki
Copy link
Contributor Author

kirisaki commented May 3, 2020

Great idea! PatternSynonyms is used like this, isn't it!

Does it require a collection like Array in implementation? Or divide into cases by the kernel size? The former generalize code against the kernel size but slow, the latter requires implementation each kernel sizes and throw an error when a kernel size isn't supported.

@lehins
Copy link
Owner

lehins commented May 3, 2020

I guess it all depends on the implementation. Try getting the one you suggested first

instance Interpolation (Lanczos 3) where

and then I can recommend a proper way going forward from there.

@kirisaki
Copy link
Contributor Author

kirisaki commented May 3, 2020

OK, I challenge it.

@YellowOnion
Copy link

If you're thinking of adding any other algorithms, there's a selection of filters here, with some key details about their implementation. : https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/resize.html

It might also help or hinder the the understanding of what a bicubic filter really is :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants