Log in

View Full Version : Gamma-aware, dithered colorspace conversion and resizing


Pages : 1 [2] 3 4 5 6

Gavino
25th March 2011, 14:25
If the final output is to be YV12, the chroma accuracy could potentially be improved by having a separate chroma conversion path using resampled luma. Instead of effectively doing this:
YV12->YV24->sRGB->linear RGB->resample->sRGB->YV24->YV12
which involves chroma resampling as both the first and last steps, do this:

YV12->YV24->sRGB->linear RGB->resample->sRGB->luma
and
YV12->resample luma to chroma grid->sRGB->linear RGB->resample to destn chroma grid->sRGB->chroma

Whether this would make a visible difference, I don't know.

kolak
26th March 2011, 19:03
and if we convert to RGB32
ResampleHQ(1280,720,"RGB32","TV.709","TV.709",false,198,22,-48,-164)
http://www.cbland.net/images4/ResampleHQRGB32.png
there are no more artefacts




This has also chroma problems- not as visible as direct YV12, but visible enough.


Andrew

PhrostByte
30th March 2011, 02:07
Got caught up in Crysis 2 for most of this past week -- it's like a frakkin' Michael Bay movie in all the right ways.

I'm going full-speed on ResampleHQ now. Should have something new up in the next couple days.

PhrostByte
5th April 2011, 19:02
For chroma upsampling I'd suggest a soft filter to avoid aliasing artifacts.

I'm going to default it to bilinear like Avisynth does, but let it be customized. Can you post code for the SoftCubic kernel you use? I'd like to add support for it.

madshi
5th April 2011, 19:09
Ok, here goes:

float Cubic(float distance, float param1, float param2)
// return cubic weight coefficients
{
float P0, P1, P2, P3;
float result = 0;

if (distance <= 2.0f)
{
if (distance < 1.0f)
{
P0 = (+ 1.0f - 1.0f/3.0f * param1 - 0.0f * param2);
P1 = 0;
P2 = (- 3.0f + 2.0f * param1 + 1.0f * param2);
P3 = (+ 2.0f - 3.0f/2.0f * param1 - 1.0f * param2);
} else {
P0 = (- 0.0f + 4.0f/3.0f * param1 + 4.0f * param2);
P1 = (+ 0.0f - 2.0f * param1 - 8.0f * param2);
P2 = (- 0.0f + 1.0f * param1 + 5.0f * param2);
P3 = (+ 0.0f - 1.0f/6.0f * param1 - 1.0f * param2);
}
result = P0 + P1 * distance + P2 * distance * distance + P3 * distance * distance * distance;
}
return result;
}

float GetFilterCoeffs(float distance, RESAMPLING_FILTER filter)
// return coeffecients for the specified resampling filter
{
float result = 0;

switch (filter)
{
case rfCatmullRom :
case rfBicubic50 : result = Cubic(distance, 0.00f, 0.50f); break;
case rfBicubic60 : result = Cubic(distance, 0.00f, 0.60f); break;
case rfBicubic75 : result = Cubic(distance, 0.00f, 0.75f); break;
case rfSoftCubic100 : result = Cubic(distance, 1.00f, 0.00f); break;
case rfSoftCubic80 : result = Cubic(distance, 0.80f, 0.20f); break;
case rfSoftCubic70 : result = Cubic(distance, 0.70f, 0.30f); break;
case rfSoftCubic60 : result = Cubic(distance, 0.60f, 0.40f); break;
case rfSoftCubic50 : result = Cubic(distance, 0.50f, 0.50f); break;
case rfMitchell : result = Cubic(distance, 1.0f/3.0f, 1.0f/3.0f); break;
[...]

Gavino
5th April 2011, 19:37
float Cubic(float distance, float param1, float param2)
Looks like that is just the same as Avisynth's BicubicResize, where param1 and param2 represent the b and c arguments.
Then, in the 'soft' settings, used with 0.5<= b <=1 and c = 1-b.
case rfSoftCubic100 : result = Cubic(distance, 1.00f, 0.00f); break;
case rfSoftCubic80 : result = Cubic(distance, 0.80f, 0.20f); break;
case rfSoftCubic70 : result = Cubic(distance, 0.70f, 0.30f); break;
case rfSoftCubic60 : result = Cubic(distance, 0.60f, 0.40f); break;
case rfSoftCubic50 : result = Cubic(distance, 0.50f, 0.50f); break;

madshi
5th April 2011, 20:44
Looks like that is just the same as Avisynth's BicubicResize
Is it? Well, there's only one way to do the math correctly, I guess... ;)

Gavino
5th April 2011, 21:50
Is it? Well, there's only one way to do the math correctly, I guess... ;)
Actually, there is more than one way of doing it. In the Avisynth implementation, your line:
result = P0 + P1 * distance + P2 * distance * distance + P3 * distance * distance * distance;
is effectively replaced by:
result = P0 + distance * (P1 + distance * (P2 + distance * P3));
which is marginally faster (fewer multiplies). ;)

PhrostByte
6th April 2011, 05:24
Ok, here goes:
Thanks!

Looks like that is just the same as Avisynth's BicubicResize, where param1 and param2 represent the b and c arguments.
Then, in the 'soft' settings, used with 0.5<= b <=1 and c = 1-b.
So it does.

henryho_hk
7th April 2011, 03:18
Found an interesting diagram about cubic resizers: http://www.imagemagick.org/Usage/resize/#mitchell

madshi
7th April 2011, 07:15
Actually, there is more than one way of doing it. In the Avisynth implementation, your line [...] is effectively replaced by [...] which is marginally faster (fewer multiplies). ;)
Haha - you're right... :p

That said, the weights are usually only calculated once and then stored in some array. So it's not a few saved multiplies per pixel, not even per frame.

PhrostByte
7th April 2011, 09:10
Here's version 5. Hopefully the last of the chroma bugs. Been hitting F2 so much in Virtualdub that I've started hitting F2 instead of F5 in browsers, lol.

Download for 32-bit and 64-bit:
http://sourceforge.net/projects/int64/files/ResampleHQ/ResampleHQ-v5.zip/download

Full documentation:
http://svn.int64.org/viewvc/int64/resamplehq/doc/index.html?revision=268

Changelog:

Catmull–Rom, Gaussian, Hermite, Mitchell–Netraveli, Robidoux, Sinc, and SoftCubic kernels.
SMPTE 240M and FCC matrices.
Customization of kernel support scale.
Customization of chroma kernel.
Support for SetMTMode(2).
More SSE versions of colorspace conversions.
Bug fix: make SSE paths work with unaligned sources.
Bug fix: scale chroma correctly.

SubJunk
7th April 2011, 09:12
Thanks a lot :)

Dogway
7th April 2011, 10:09
Thank you!
I can't make RGB work, either input or ouput. I get a crash (my fault?):
crashinfo.txt (http://www.mediafire.com/?bj7furs34bh7ff2)

edit: that was in avs 2.57 MT winXP SP3
edit2: It worked if dither=false, so its a dither thing in RGB.

PhrostByte
7th April 2011, 13:00
Thank you!
I can't make RGB work, either input or ouput. I get a crash (my fault?):
crashinfo.txt (http://www.mediafire.com/?bj7furs34bh7ff2)

i can't download that file, for some reason mediafire gives me an invalid url. do you have a script that reproduces it?

edit: nevermind, i got it through another browser.

Yellow_
7th April 2011, 13:28
Is there anything to gain from implementing yesgrey's high precision 3D LUT (yCMS) for colourspace conversions used in conjunction with the necessary bits of Triticals t3dlut plugin?

http://forum.doom9.org/showthread.php?t=154719

PhrostByte
7th April 2011, 14:22
Is there anything to gain from implementing yesgrey's high precision 3D LUT (yCMS) for colourspace conversions used in conjunction with the necessary bits of Triticals t3dlut plugin?

http://forum.doom9.org/showthread.php?t=154719

Not sure, I'll check it out.

Actual colorspace conversion is the cheapest part of ResampleHQ right now -- resampling takes up a huge amount of time compared to it.

I'm currently experimenting with OpenCL which should give a pretty nice speedup as is, though it can also use 3D LUTs so it could also help assuming you've got enough vram.

Archimedes
7th April 2011, 14:39
Thanks for the update. Hermite and Robidoux do not working (unsupported kernels).

LoRd_MuldeR
7th April 2011, 14:45
Also "Spline32" (mentioned in the docs) does not work, but "Spline36" (undocumented) does ;)

PhrostByte
7th April 2011, 15:15
Thanks for the update. Hermite and Robidoux do not working (unsupported kernels).

Fixed. You can use Bicubic with b/c set manually until I get a new version out.

Also "Spline32" (mentioned in the docs) does not work, but "Spline36" (undocumented) does ;)

Doh!

Thank you!
I can't make RGB work, either input or ouput. I get a crash (my fault?):
crashinfo.txt (http://www.mediafire.com/?bj7furs34bh7ff2)

edit: that was in avs 2.57 MT winXP SP3

Still trying to reproduce this. Strange crashdump, it includes instructions that don't exist in my filter, like movups.

ganymede
7th April 2011, 23:04
Mitchell–NetraveliIt's a typo, the name of the filter should be Mitchell–Netravali (from the name of Don P. Mitchell and Arun N. Netravali).

PhrostByte
9th April 2011, 00:11
Version 6. Fixes Dogway's crash and some other things.

Download for 32-bit and 64-bit:
http://sourceforge.net/projects/int64/files/ResampleHQ/ResampleHQ-v6.zip/download

Full documentation:
http://svn.int64.org/viewvc/int64/resamplehq/doc/index.html?revision=272

Changelog:

SSE Y'CbCr output conversions. All conversions now have SSE implementations.
Bug fix: correct rounding in SSE output conversions.
Bug fix: allocate dithering error buffers.
Bug fix: Hermite and Robidoux kernels are now enabled.
Bug fix: correct spelling of Spline36 and Mitchell–Netravali.

SubJunk
9th April 2011, 00:36
Nice one, thanks

PhrostByte
10th April 2011, 18:43
Anyone have a shiny new Sandy Bridge CPU willing to run a lengthy benchmark? I wrote a bunch of AVX stuff but have no way of testing if it is actually any faster.

Yellow_
13th April 2011, 08:07
Enjoying using your plugin and have a query, not a bug to report but I notice when converting to RGB that I see faint red/blue rectangular blocks along the edges of content in any chosen image frame. The source is h264AVC from a Canon DSLR. I can put up a sample but guess the description is enough. Assume this is result of chroma subsampling / moire / line skipping. They also appear to be non square even though its square pixel source

So query is, is there anything that can be done in the interpolation of chroma, assume its going 4:2:0 to 4:2:2 to RGB that could subdue the alternate red blue blocks its like chequreboard

I notice this with other conversion methods to RGB including yCMS 3DLUT + Triticals t3dlut plugin

ChaosKing
13th April 2011, 12:26
Anyone have a shiny new Sandy Bridge CPU willing to run a lengthy benchmark? I wrote a bunch of AVX stuff but have no way of testing if it is actually any faster.
I can test it. Have a SB 2500 CPU

PhrostByte
13th April 2011, 15:39
Enjoying using your plugin and have a query, not a bug to report but I notice when converting to RGB that I see faint red/blue rectangular blocks along the edges of content in any chosen image frame. The source is h264AVC from a Canon DSLR. I can put up a sample but guess the description is enough. Assume this is result of chroma subsampling / moire / line skipping. They also appear to be non square even though its square pixel source

So query is, is there anything that can be done in the interpolation of chroma, assume its going 4:2:0 to 4:2:2 to RGB that could subdue the alternate red blue blocks its like chequreboard

I notice this with other conversion methods to RGB including yCMS 3DLUT + Triticals t3dlut plugin

I suspect it's caused by chroma bleeding into luma because of subsampling. Some colors right next to each other can react particularly bad. If you post an example image I can take a look.

I can test it. Have a SB 2500 CPU

Here it is. It'll create a "benchmark results.txt" once it's done, you can just paste the results here.

http://sourceforge.net/projects/int64/files/ResampleHQ/resamplehq-v7pre-avxbench.zip/download

Dogway
13th April 2011, 16:01
I made some tests. I use an image I used once before because it has good features to test on like small details, big details, and some well defined letters.
From what I observed most of the scaling kernels show the ringing I described a few weeks back. So this is how I classify the different algorithms:

blurry: principally because of this (http://forum.doom9.org/showthread.php?)p=1474853#post1474853)
bilinear
rubidoux

ringing:
lanczos4
spline64
spline36

good balance of both of them:
lanczos (best in my opinion)
blackman (2nd best)
spline16
catmull

I also included automttap3 for comparison, it was the one who retained most detail in my last test, but I wouldnt use it for graphics or cartoons because it also creates some ugly ringing repetition. Also added spline64.
If I tell you the truth I was a bit dissappointed concerning the ringing thing, even if that was what it was supposed to do :/

Pack with the tests, .psd file and separated .png files
35Mb rar:
http://www.mediafire.com/?16a31o7v0im652o

ChaosKing
13th April 2011, 16:24
Benchmark results
------------------

The AVX version seems to be very slow :/

RGB24 -> linear RGB C: (fastest/slowest/average) wall time speed is 6.59281/6.10231/6.51858 runs/second.
RGB24 -> linear RGB C relative speed: 1.0x
RGB24 -> linear RGB SSSE3: (fastest/slowest/average) wall time speed is 37.5498/33.94/36.5475 runs/second.
RGB24 -> linear RGB SSSE3 relative speed: 5.69557x
RGB24 -> linear RGB AVX: (fastest/slowest/average) wall time speed is 3.00409/2.71127/2.94455 runs/second.
RGB24 -> linear RGB AVX relative speed: 0.455661x
RGB32 -> linear RGB C: (fastest/slowest/average) wall time speed is 4.67475/3.83495/4.55645 runs/second.
RGB32 -> linear RGB C relative speed: 1.0x
RGB32 -> linear RGB SSE2: (fastest/slowest/average) wall time speed is 37.7303/35.7484/37.0366 runs/second.
RGB32 -> linear RGB SSE2 relative speed: 8.07107x
RGB32 -> linear RGB AVX: (fastest/slowest/average) wall time speed is 2.76705/2.44912/2.72385 runs/second.
RGB32 -> linear RGB AVX relative speed: 0.591913x
RGB32 -> linear RGBA C: (fastest/slowest/average) wall time speed is 4.55221/4.31145/4.49747 runs/second.
RGB32 -> linear RGBA C relative speed: 1.0x
RGB32 -> linear RGBA SSE2: (fastest/slowest/average) wall time speed is 36.1119/33.9868/35.8453 runs/second.
RGB32 -> linear RGBA SSE2 relative speed: 7.93283x
RGB32 -> linear RGBA AVX: (fastest/slowest/average) wall time speed is 2.85771/2.20617/2.79098 runs/second.
RGB32 -> linear RGBA AVX relative speed: 0.627764x
YV12 -> YUV C: (fastest/slowest/average) wall time speed is 165.108/157.79/163.724 runs/second.
YV12 -> YUV C relative speed: 1.0x
YV12 -> YUV SSE2: (fastest/slowest/average) wall time speed is 300.263/286.618/295.344 runs/second.
YV12 -> YUV SSE2 relative speed: 1.81859x
YV12 -> YUV AVX: (fastest/slowest/average) wall time speed is 19.5201/18.1788/19.3726 runs/second.
YV12 -> YUV AVX relative speed: 0.118226x
YUY2 -> YUV C: (fastest/slowest/average) wall time speed is 204.879/178.597/199.624 runs/second.
YUY2 -> YUV C relative speed: 1.0x
YUY2 -> YUV SSE2: (fastest/slowest/average) wall time speed is 424.132/361.432/417.757 runs/second.
YUY2 -> YUV SSE2 relative speed: 2.07016x
YUY2 -> YUV AVX: (fastest/slowest/average) wall time speed is 32.1951/28.7248/31.7467 runs/second.
YUY2 -> YUV AVX relative speed: 0.157142x
YUV -> linear RGB C: (fastest/slowest/average) wall time speed is 16.9974/12.2325/16.4998 runs/second.
YUV -> linear RGB C relative speed: 1.0x
YUV -> linear RGB SSE2: (fastest/slowest/average) wall time speed is 37.3566/35.0877/36.9554 runs/second.
YUV -> linear RGB SSE2 relative speed: 2.19778x
YUV -> linear RGB AVX: (fastest/slowest/average) wall time speed is 3.72789/3.47262/3.68511 runs/second.
YUV -> linear RGB AVX relative speed: 0.219321x
linear RGB -> RGB24 C: (fastest/slowest/average) wall time speed is 6.25605/5.79279/6.17731 runs/second.
linear RGB -> RGB24 C relative speed: 1.0x
linear RGB -> RGB24 SSSE3: (fastest/slowest/average) wall time speed is 40.4334/33.1002/39.0018 runs/second.
linear RGB -> RGB24 SSSE3 relative speed: 6.46308x
linear RGB -> RGB24 AVX: (fastest/slowest/average) wall time speed is 3.30754/2.9804/3.24551 runs/second.
linear RGB -> RGB24 AVX relative speed: 0.528695x
linear RGB -> RGB32 C: (fastest/slowest/average) wall time speed is 4.37648/4.11399/4.33744 runs/second.
linear RGB -> RGB32 C relative speed: 1.0x
linear RGB -> RGB32 SSE2: (fastest/slowest/average) wall time speed is 41.4194/40.0089/41.09 runs/second.
linear RGB -> RGB32 SSE2 relative speed: 9.46409x
linear RGB -> RGB32 AVX: (fastest/slowest/average) wall time speed is 3.57475/3.04053/3.43611 runs/second.
linear RGB -> RGB32 AVX relative speed: 0.816809x
linear RGBA -> RGB32 C: (fastest/slowest/average) wall time speed is 4.44825/4.36037/4.42751 runs/second.
linear RGBA -> RGB32 C relative speed: 1.0x
linear RGBA -> RGB32 SSE2: (fastest/slowest/average) wall time speed is 39.6152/36.8389/39.01 runs/second.
linear RGBA -> RGB32 SSE2 relative speed: 8.90578x
linear RGBA -> RGB32 AVX: (fastest/slowest/average) wall time speed is 3.31775/2.84886/3.2405 runs/second.
linear RGBA -> RGB32 AVX relative speed: 0.745854x
YUV -> YV12 C: (fastest/slowest/average) wall time speed is 155.964/138.181/153.442 runs/second.
YUV -> YV12 C relative speed: 1.0x
YUV -> YV12 SSE2: (fastest/slowest/average) wall time speed is 450.69/430.569/445.116 runs/second.
YUV -> YV12 SSE2 relative speed: 2.88972x
YUV -> YV12 AVX: (fastest/slowest/average) wall time speed is 15.0684/14.3686/14.9177 runs/second.
YUV -> YV12 AVX relative speed: 0.0966147x
YUV -> YUY2 C: (fastest/slowest/average) wall time speed is 201.52/167.831/199.426 runs/second.
YUV -> YUY2 C relative speed: 1.0x
YUV -> YUY2 SSE2: (fastest/slowest/average) wall time speed is 659.215/645.618/654.092 runs/second.
YUV -> YUY2 SSE2 relative speed: 3.2712x
YUV -> YUY2 AVX: (fastest/slowest/average) wall time speed is 21.4287/20.0173/21.215 runs/second.
YUV -> YUY2 AVX relative speed: 0.106335x
linear RGB -> YUV C: (fastest/slowest/average) wall time speed is 8.66521/8.32953/8.50003 runs/second.
linear RGB -> YUV C relative speed: 1.0x
linear RGB -> YUV SSE2: (fastest/slowest/average) wall time speed is 38.0747/33.7847/37.6462 runs/second.
linear RGB -> YUV SSE2 relative speed: 4.39398x
linear RGB -> YUV AVX: (fastest/slowest/average) wall time speed is 3.74787/3.71133/3.74012 runs/second.
linear RGB -> YUV AVX relative speed: 0.432519x

PhrostByte
13th April 2011, 17:39
I made some tests. I use an image I used once before because it has good features to test on like small details, big details, and some well defined letters.
From what I observed most of the scaling kernels show the ringing I described a few weeks back. So this is how I classify the different algorithms:

Thanks for the analysis. My own eyeballed tests tend to agree, I've seen the best downsizing results with Lanczos2/3 and Spline16.

Benchmark results
------------------

The AVX version seems to be very slow :/

Very bizarre results indeed. I'll have to look things over closely, because those can't be correct.

markanini
13th April 2011, 19:00
It does accent ringing, sometimes beneficial, sometimes detrimental depending on the source. A question I want to ask is when dealing with a difficult source what's a good kernel to use when spline16 and lanczos2 has too much ringing and you want to retain decent sharpness still.

Yellow_
14th April 2011, 00:21
I suspect it's caused by chroma bleeding into luma because of subsampling. Some colors right next to each other can react particularly bad. If you post an example image I can take a look.

Thanks, here's the link. It's a 400x zoom of a 1920x1088 frame h264AVC.

http://www.yellowspace.webspace.virginmedia.com/1920x1088_DSLR_400xZoom.png

PhrostByte
14th April 2011, 04:03
It does accent ringing, sometimes beneficial, sometimes detrimental depending on the source. A question I want to ask is when dealing with a difficult source what's a good kernel to use when spline16 and lanczos2 has too much ringing and you want to retain decent sharpness still.

Try Blackman2. I made this nifty little webpage to help people choose a kernel:
http://svn.int64.org/viewvc/int64/resamplehq/doc/kernels.html

You'll need a browser that supports HTML5 canvas.

Thanks, here's the link. It's a 400x zoom of a 1920x1088 frame h264AVC.

http://www.yellowspace.webspace.virginmedia.com/1920x1088_DSLR_400xZoom.png

Yea, that's chroma bleeding. It's more noticeable when color meets white/black/gray/etc., because grays don't actually have chroma. When chroma gets subsampled, it gives the gray some of the surrounding colors' chroma and results in weird colors.

There actually is something I can do to help combat this, though I haven't started any work on it as it's a little complex.

Archimedes
14th April 2011, 14:34
Spline36Resize >> (http://img232.imageshack.us/i/sn850652spline36resize.png/)
ResampleHQ, Spline36 >> (http://img641.imageshack.us/i/sn850652spline36.png/)

Depending on the source and the used kernel, gamma aware resizing produces dark lines around bright areas where the same 8 bit resizer in AviSynth did not fail (see example above). Tested also with Image Analyzer (which is also capable of gamma aware resizing).

The effect decrease with Lanczos (2 lobes), but not completely. Same with Spline16. With Blackman (2 lobes) and Bicubic (b=0.33, c=0.33) the effect is gone.

ResampleHQ, Lanczos (2 lobes) >> (http://img810.imageshack.us/i/sn850652lanczos.png/)
ResampleHQ, Blackman (2 lobes) >> (http://img28.imageshack.us/i/sn850652blackman.png/)
ResampleHQ, Bicubic (b=0.33, c=0.33) >> (http://img191.imageshack.us/i/sn850652bicubic.png/)

Yellow_
14th April 2011, 18:29
Yea, that's chroma bleeding. It's more noticeable when color meets white/black/gray/etc., because grays don't actually have chroma. When chroma gets subsampled, it gives the gray some of the surrounding colors' chroma and results in weird colors.

Ok, thanks for the explanation.

There actually is something I can do to help combat this, though I haven't started any work on it as it's a little complex.

Good news, look forward to that all in good time.

Archimedes
15th April 2011, 09:47
good balance of both of them:
lanczos (best in my opinion)
blackman (2nd best)
spline16
catmull

Did some further tests and came to similar results. A good compromise between blurring, sharpening and ringing seems to be: Lanczos (2 lobes) and CatmullRom (which is practically the same as Lanczos with 2 lobes).

Bicubic >> (http://img691.imageshack.us/i/pditargetbicubic.png/)
Blackman (2 lobes) >> (http://img585.imageshack.us/i/pditargetblackman.png/)
CatmullRom >> (http://img864.imageshack.us/i/pditargetcatmullrom.png/)
Lanczos (2 lobes) >> (http://img834.imageshack.us/i/pditargetlanczos.png/)
Spline16 >> (http://img853.imageshack.us/i/pditargetspline16.png/)

TinTime
15th April 2011, 11:25
All looks very interesting - thanks for this!

Anyway, I've just found a small bug. If you set src_width or src_height to -0 then it produces some peculiar (although not unattractive :)) results. Presumably it should use default values if either of these are set to 0, like AVISynth's resizers.

PhrostByte
19th April 2011, 22:10
Benchmark results
------------------

The AVX version seems to be very slow :/

If you don't mind trying a new version, I think I figured out what was going on.

http://sourceforge.net/projects/int64/files/ResampleHQ/ResampleHQ-v7pre2-avxbench.zip/download

ChaosKing
20th April 2011, 21:52
Looks good now or should I say: an amazing speedup :P

It could be that since "linear RGB -> x ", the values ​​are slightly distorted, because my brother started to play Portal 2 on that PC. ^^"

RGB24 -> linear RGB C: (fastest/slowest/average) wall time speed is 4.64519/4.6013/4.63308 runs/second.
RGB24 -> linear RGB C relative speed: 1.0x
RGB24 -> linear RGB SSSE3: (fastest/slowest/average) wall time speed is 36.5916/36.1973/36.4791 runs/second.
RGB24 -> linear RGB SSSE3 relative speed: 7.8773x
RGB24 -> linear RGB AVX: (fastest/slowest/average) wall time speed is 63.7797/63.3852/63.5543 runs/second.
RGB24 -> linear RGB AVX relative speed: 13.7303x
RGB32 -> linear RGB C: (fastest/slowest/average) wall time speed is 1.96892/1.95244/1.96175 runs/second.
RGB32 -> linear RGB C relative speed: 1.0x
RGB32 -> linear RGB SSE2: (fastest/slowest/average) wall time speed is 38.7904/38.4984/38.6492 runs/second.
RGB32 -> linear RGB SSE2 relative speed: 19.7014x
RGB32 -> linear RGB AVX: (fastest/slowest/average) wall time speed is 61.5876/60.6015/61.2052 runs/second.
RGB32 -> linear RGB AVX relative speed: 31.2799x
RGB32 -> linear RGBA C: (fastest/slowest/average) wall time speed is 1.89056/1.88258/1.8879 runs/second.
RGB32 -> linear RGBA C relative speed: 1.0x
RGB32 -> linear RGBA SSE2: (fastest/slowest/average) wall time speed is 37.478/37.2069/37.377 runs/second.
RGB32 -> linear RGBA SSE2 relative speed: 19.8238x
RGB32 -> linear RGBA AVX: (fastest/slowest/average) wall time speed is 58.1383/57.8567/58.0005 runs/second.
RGB32 -> linear RGBA AVX relative speed: 30.7519x
YV12 -> YUV C: (fastest/slowest/average) wall time speed is 49.1157/48.8132/48.9772 runs/second.
YV12 -> YUV C relative speed: 1.0x
YV12 -> YUV SSE2: (fastest/slowest/average) wall time speed is 293.662/276.124/290.44 runs/second.
YV12 -> YUV SSE2 relative speed: 5.97899x
YV12 -> YUV AVX: (fastest/slowest/average) wall time speed is 291.98/290.154/291.136 runs/second.
YV12 -> YUV AVX relative speed: 5.94473x
YUY2 -> YUV C: (fastest/slowest/average) wall time speed is 73.0191/72.4696/72.8227 runs/second.
YUY2 -> YUV C relative speed: 1.0x
YUY2 -> YUV SSE2: (fastest/slowest/average) wall time speed is 418.173/407.67/416.318 runs/second.
YUY2 -> YUV SSE2 relative speed: 5.7269x
YUY2 -> YUV AVX: (fastest/slowest/average) wall time speed is 441.182/376.143/405.183 runs/second.
YUY2 -> YUV AVX relative speed: 6.04201x
YUV -> linear RGB C: (fastest/slowest/average) wall time speed is 6.26964/5.08769/6.1638 runs/second.
YUV -> linear RGB C relative speed: 1.0x
YUV -> linear RGB SSE2: (fastest/slowest/average) wall time speed is 38.2352/37.4367/37.9741 runs/second.
YUV -> linear RGB SSE2 relative speed: 6.09846x
YUV -> linear RGB AVX: (fastest/slowest/average) wall time speed is 59.4667/59.0774/59.3507 runs/second.
YUV -> linear RGB AVX relative speed: 9.48486x
linear RGB -> RGB24 C: (fastest/slowest/average) wall time speed is 1.91731/1.89385/1.90992 runs/second.
linear RGB -> RGB24 C relative speed: 1.0x
linear RGB -> RGB24 SSSE3: (fastest/slowest/average) wall time speed is 39.3451/38.7191/39.0217 runs/second.
linear RGB -> RGB24 SSSE3 relative speed: 20.521x
linear RGB -> RGB24 AVX: (fastest/slowest/average) wall time speed is 53.6576/51.0381/52.9992 runs/second.
linear RGB -> RGB24 AVX relative speed: 27.9859x
linear RGB -> RGB32 C: (fastest/slowest/average) wall time speed is 1.82714/1.79387/1.81084 runs/second.
linear RGB -> RGB32 C relative speed: 1.0x
linear RGB -> RGB32 SSE2: (fastest/slowest/average) wall time speed is 44.3867/44.0377/44.1762 runs/second.
linear RGB -> RGB32 SSE2 relative speed: 24.293x
linear RGB -> RGB32 AVX: (fastest/slowest/average) wall time speed is 53.4973/45.477/51.7734 runs/second.
linear RGB -> RGB32 AVX relative speed: 29.2792x
linear RGBA -> RGB32 C: (fastest/slowest/average) wall time speed is 1.72983/1.65757/1.71013 runs/second.
linear RGBA -> RGB32 C relative speed: 1.0x
linear RGBA -> RGB32 SSE2: (fastest/slowest/average) wall time speed is 42.1848/39.7659/41.8548 runs/second.
linear RGBA -> RGB32 SSE2 relative speed: 24.3867x
linear RGBA -> RGB32 AVX: (fastest/slowest/average) wall time speed is 48.3195/46.7094/47.833 runs/second.
linear RGBA -> RGB32 AVX relative speed: 27.9332x
YUV -> YV12 C: (fastest/slowest/average) wall time speed is 146.967/143.542/145.766 runs/second.
YUV -> YV12 C relative speed: 1.0x
YUV -> YV12 SSE2: (fastest/slowest/average) wall time speed is 390.946/370.838/383.787 runs/second.
YUV -> YV12 SSE2 relative speed: 2.66009x
YUV -> YV12 AVX: (fastest/slowest/average) wall time speed is 392.435/299.917/359.429 runs/second.
YUV -> YV12 AVX relative speed: 2.67022x
YUV -> YUY2 C: (fastest/slowest/average) wall time speed is 187.74/182.522/186.619 runs/second.
YUV -> YUY2 C relative speed: 1.0x
YUV -> YUY2 SSE2: (fastest/slowest/average) wall time speed is 521.429/455.525/489.856 runs/second.
YUV -> YUY2 SSE2 relative speed: 2.77739x
YUV -> YUY2 AVX: (fastest/slowest/average) wall time speed is 492.264/432.675/468.23 runs/second.
YUV -> YUY2 AVX relative speed: 2.62205x
linear RGB -> YUV C: (fastest/slowest/average) wall time speed is 2.94834/2.44282/2.75141 runs/second.
linear RGB -> YUV C relative speed: 1.0x
linear RGB -> YUV SSE2: (fastest/slowest/average) wall time speed is 38.0381/36.8236/37.6511 runs/second.
linear RGB -> YUV SSE2 relative speed: 12.9016x
linear RGB -> YUV AVX: (fastest/slowest/average) wall time speed is 56.6484/54.8323/56.095 runs/second.
linear RGB -> YUV AVX relative speed: 19.2137x

PhrostByte
22nd April 2011, 02:35
Looks good now or should I say: an amazing speedup :P

Sweet, glad it worked. Those results were about what I expected.

henryho_hk
13th May 2011, 02:59
V6 x64 is giving me a blank screen in occasions. I am trying to prepare for a simple and reproducible scenario.....

markanini
18th May 2011, 00:35
http://svn.int64.org/viewvc/int64/resamplehq/doc/kernels.html
I take it from studying your graph that Blackman3, Catmull-Rom, Lanczos2, Spline16 would all make good general purpose resizing kernels and some quick visual test I made seem to confirm this, atleast to the extent that I can't tell them apart and they all look perfectly fine.

PhrostByte
18th May 2011, 01:05
V6 x64 is giving me a blank screen in occasions. I am trying to prepare for a simple and reproducible scenario.....

Let me know!

I take it from studying your graph that Blackman3, Catmull-Rom, Lanczos2, Spline16 would all make good general purpose resizing kernels and some quick visual test I made seem to confirm this, atleast to the extent that I can't tell them apart and they all look perfectly fine.

Yes. Start from one of those and if it doesn't look good, try something that improves in the areas you need.

Lyle_JP
20th May 2011, 07:26
V6 x64 is giving me a blank screen in occasions. I am trying to prepare for a simple and reproducible scenario.....

Unfortunately, I have nothing but reproducible scenarios. I am trying to run the x64 version on sET's 64-bit Avisynth 2.5.8, and every video I feed to ResampleHQ comes out as nothing but a properly resized black screen. It doesn't matter what arguments I use, even all defaults. Source doesn't matter, either. I wish I could be more help narrowing down the issue, but for now this plug-in simply doesn't work at all in my environment.

PhrostByte
25th May 2011, 01:09
V6 x64 is giving me a blank screen in occasions. I am trying to prepare for a simple and reproducible scenario.....

Unfortunately, I have nothing but reproducible scenarios. I am trying to run the x64 version on sET's 64-bit Avisynth 2.5.8, and every video I feed to ResampleHQ comes out as nothing but a properly resized black screen. It doesn't matter what arguments I use, even all defaults. Source doesn't matter, either. I wish I could be more help narrowing down the issue, but for now this plug-in simply doesn't work at all in my environment.

found the problem. will put a fix out shortly.

NicolasRobidoux
3rd June 2011, 21:37
...

blurry: principally because of this (http://forum.doom9.org/showthread.php?)p=1474853#post1474853)
bilinear
rubidoux
...

Warning:

The robidoux cubic filter is meant to be used with Clamped EWA (Elliptical Weighted Averaging) resampling, which is different from the way the other cubic filters are generally used.

It is meant to be used with a technique originating from the field of texture mapping, adapted to perform resizing and resampling.
See ImageMagick Examples (http://www.imagemagick.org/Usage/distorts/#area_resample), the Better and faster image resizing and resampling Libre Graphics Meeting 2011 presentation video (http://river-valley.tv/better-and-faster-image-resizing-and-resampling/) as well as http://www.imagemagick.org/Usage/resize/#distort_resize and http://www.imagemagick.org/Usage/resize/#robidoux for details.

This being said, the best Clamped EWA method is the filter known in recent ImageMagick as lanczossharp (IMHO).
That is, "convert -filter lanczossharp -distort resize..." with a very recent version of ImageMagick.

IMHO Clamped EWA lanczossharp is actually a fantastic resizing and resampling filter. Better than anything on your list.

This does not mean that the robidoux filter will "break things" if used like the other bicubic filters. It is just that, the way you are using it, it is not supposed to be very good. Indeed, it is quite blurry.

madshi
3rd June 2011, 22:22
Hi Nicolas,

nice to see you here, welcome to the forum!

One thing I don't understand is how "Elliptical" has anything to do with simple image up-/downscaling. I mean if there's no perspective transformation, how can there be ellipses? How can it matter whether you use EWA or conventional distance weighting if all ellipses are actually circles?

BTW, how do you like this idea:

http://forum.doom9.org/showthread.php?t=145358

NicolasRobidoux
4th June 2011, 00:49
Thanks for the update. Hermite and Robidoux do not working (unsupported kernels).

Note: Robidoux is a recent addition to ImageMagick.

NicolasRobidoux
4th June 2011, 01:04
Hi Nicolas,

nice to see you here, welcome to the forum!


Hello Madshi.

(I won't be too good of a poster for a bit: I'm reading the threads a bit too fast to make sure all my comments are on target.)

I actually joined Doom9 in March to push some my goods unto unsuspecting passerbys. And lo and behold, some relevant threads just sprouted!

One thing I don't understand is how "Elliptical" has anything to do with simple image up-/downscaling. I mean if there's no perspective transformation, how can there be ellipses? How can it matter whether you use EWA or conventional distance weighting if all ellipses are actually circles?...
I could go into a longwinded explanation, but won't.

Let me just say that if you are preserving aspect ratios exactly, then you won't have ellipses: only disks.

If you don't reduce in any of the two directions (for example, if you are enlarging in both directions, or keeping one dimension the same and enlarging in the other), you will get disks, not ellipses.

But if your resize ratio is slightly different horizontally and vertically, and you are downsampling in at least one direction, then you'll get ellipses aligned with the axes instead of disks.

More wishy washy: Your image may have sampled the world on a uniform grid, but the world is not laid out on a uniform grid. Some of the artifacts one gets with common samplers are a consequence of being enslaved to Descartes. Using rotationally invariant samplers takes off these shackles.

But really, the proof is in the pudding:

Install a recent version of ImageMagick and try any resizing task (up/down/mix and match) with "convert -filter lanczossharp -distort resize".

Documentation: http://www.imagemagick.org/Usage/distorts/#resize and http://www.imagemagick.org/Usage/resize/#distort_resize.

If you find something that works, overall, better with natural images, let me know.

(Warning: The Jinc EWA code is going to see some major optimizations this Summer. So will the (regular) tensor Lanczos code.)

Mini-Me
4th June 2011, 04:58
Hello Madshi.

(I won't be too good of a poster for a bit: I'm reading the threads a bit too fast to make sure all my comments are on target.)

I actually joined Doom9 in March to push some my goods unto unsuspecting passerbys. And lo and behold, some relevant threads just sprouted!

I could go into a longwinded explanation, but won't.

Let me just say that if you are preserving aspect ratios exactly, then you won't have ellipses: only disks.

If you don't reduce in any of the two directions (for example, if you are enlarging in both directions, or keeping one dimension the same and enlarging in the other), you will get disks, not ellipses.

But if your resize ratio is slightly different horizontally and vertically, and you are downsampling in at least one direction, then you'll get ellipses aligned with the axes instead of disks.

More wishy washy: Your image may have sampled the world on a uniform grid, but the world is not laid out on a uniform grid. Some of the artifacts one gets with common samplers are a consequence of being enslaved to Descartes. Using rotationally invariant samplers takes off these shackles.

But really, the proof is in the pudding:

Install a recent version of ImageMagick and try any resizing task (up/down/mix and match) with "convert -filter lanczossharp -distort resize".

Documentation: http://www.imagemagick.org/Usage/distorts/#resize and http://www.imagemagick.org/Usage/resize/#distort_resize.

If you find something that works, overall, better with natural images, let me know.

(Warning: The Jinc EWA code is going to see some major optimizations this Summer. So will the (regular) tensor Lanczos code.)

Whoa...
A few years ago I was thinking about texture magnification for 3D graphics, and I idly wondered if using the radial distance from source samples might be better for rotational invariance than using traditional resizing kernels...but trying to figure out things like zero crossings made my brain hurt. I'm sooooo happy that someone else actually went forward with the legwork! It's probably still a long way from being put into GPU's, and it isn't used in Avisynth yet either, but it's really cool to see that it exists. :)