Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
|
Thread Tools | Search this Thread | Display Modes |
27th June 2013, 20:03 | #1 | Link |
Registered User
Join Date: Oct 2004
Posts: 131
|
Layer and Overlay operation giving wrong results with RGBA image source
I would like to compose two image sources on each other, using alpha blending.
My problem is that: 1. If I just simply load the image with imagesource, the result is OK (I think it just discards the alpha channel) 2. However as soon as I do an Overlay or Layer operation, Avisynth seems to handle the alpha of the image wrong. 3. I believe the problem is pre-multiplied vs. post-multiplied alpha. I found a filter especially for fixing this, avisynth-unpremultiply (https://code.google.com/p/avisynth-unpremultiply/), however it made a totally crazy buggy colors with rainbow like blends and other bugs. Is there any way to tell AviSynth to handle the alpha in my foreground images properly? Here is my bg image: https://dl.dropbox.com/s/fdq7hfm679hbmh2/composebug_bg.png My foreground image: https://dl.dropbox.com/s/t5c8rt0psu0l56o/composebug_fg.png How it looks in AviSynth: https://dl.dropbox.com/s/h7412jh6e81t1pl/composebug_avisynth.png And how it should look, as when composed in After Effect, and selecting "premultiplied" for the foreground's alpha: https://dl.dropbox.com/s/xb9igdqd8yyby4y/ae_00000.png This is the Avisynth script I'm trying to use (in 2.60 b4): Code:
background = ImageSource( "e:\render_outside\draft%05d.png", 1, 5600, 24, pixel_type="RGB24" ).ConvertToRGB32() foreground = ImageSource( "e:\render_mixer\image%05d.png", 1, 5600, 24, pixel_type="RGB32" ) Layer( background, foreground ) |
28th June 2013, 00:53 | #2 | Link |
Registered User
Join Date: Jun 2013
Posts: 24
|
Funny, I was thinking of making a thread for the same problem.
However, I'm not sure whether it is a matter of pre/post-multiplied alpha. To be honest, I didn't even consider the possibility before you mentioned it, mostly because I was thinking it would be caused by something like a RGB <-> YUV conversion. For instance, this script is supposed to return the overlay layer (basic ColorBars clip fading out via alpha channel) untouched by overlaying it over a blank, transparent clip. It doesn't. It even looks like it changes the RGB values for some reason. Code:
ColorBars(width=640, height=480, pixel_type="RGB32") KillAudio Trim(0, length=255) MergeARGB(BlankClip(last, color=$FF000000).FadeOut(framecount-1, color=$00000000), \ ShowRed, \ ShowGreen, \ ShowBlue) top_layer=last Layer(BlankClip(last, color=$00000000), last, op="add", level=257) Compare(top_layer, channels="RGBA", show_graph=false) # try with channels="R", "G", "B" and "A" |
28th June 2013, 01:26 | #3 | Link |
Avisynth Developer
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
|
Yes the alpha mask scaling is incompatible.
See this thread, "Alternative to the old Unpremultiply() plugin?", for a fixed version of the unpremultiply plugin and discussion on alternatives (lutxy etc). |
28th June 2013, 01:49 | #4 | Link |
Registered User
Join Date: Oct 2004
Posts: 131
|
Thanks IanB,
I've tried the linked version, and while it is indeed better, it's still way off from the real solution. https://dl.dropbox.com/s/lat7axfw9in...remult_new.png Actually, this image looks really similar to what After Effects looks when I'm in 8 bit mode. I had to put After Effects to 32 bit floating point mode to get the correct results. Which is strange to me! Do pre-multiplying really need 32-bit floating point operation? |
28th June 2013, 15:13 | #5 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,377
|
Quote:
Code:
fg=ImageSource("composebug_fg.png", pixel_type="rgb32") bg=ImageSource("composebug_bg.png", pixel_type="rgb32") overlay(bg, fg, mask=fg.showalpha.unpremultiply) |
|
28th June 2013, 16:13 | #6 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
OK, I'm puzzled for many reasons: 1. The method poisondeathray looks good, however it's just a coincidence. Upon looking at the mask, it's clear that we are pretty much discarding all the grayscale information and making a binary mask. Thus, the background is _totally_ not visible behind those areas. Look: normal alpha unpremultiplied's alpha 2. Upon looking at the code, I'm even more confused. I don't understand 2 things: 1. How could a 32-bit float operation help here. The result I get with Layer seems really similar to AE's 8-bit mode. 2. Upon looking at the code, it seems to me that alpha should stay intact. However fg.showalpha.unpremultiply() clearly shows different results compared to the normal one. How is this possible? From cpp: Code:
const int srcapix = srcp[w+3] ; dstp[w+0] = lookup[ (srcp[w+0]<<8) + srcapix ]; dstp[w+1] = lookup[ (srcp[w+1]<<8) + srcapix ]; dstp[w+2] = lookup[ (srcp[w+2]<<8) + srcapix ]; dstp[w+3] = srcapix; Last edited by pancserzso; 28th June 2013 at 16:37. |
|
28th June 2013, 16:31 | #7 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
How can that work?
ShowAlpha() copies the alpha channel into R, G and B. Unpremultiply then divides R, G and B by alpha, so you should end up with a mask with all pixels 255. Quote:
The result of the premultiplication needs to be stored in at least 16 bits to preserve precision. |
|
28th June 2013, 16:38 | #8 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
|
|
28th June 2013, 16:50 | #9 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
2. unpremultiply preserves alpha, but mask in Overlay() does not use alpha, it uses the RGB as greyscale. |
|
28th June 2013, 18:18 | #10 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
For reference, here is how After Effects looks in 8-bit mode and 32-bit float mode (just with blank background): 8-bit 32-bit float And the Avisynth output: unpremultiply new Last edited by pancserzso; 28th June 2013 at 18:21. |
|
28th June 2013, 18:42 | #11 | Link | ||
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
Avisynth by itself can process only 8-bit inputs (although perhaps something could be done with dithertools?). Quote:
output = fg*alpha + bg*(1-alpha) However, the same formula is used for output alpha, which appears to be incorrect. |
||
28th June 2013, 18:47 | #12 | Link |
Formerly davidh*****
Join Date: Jan 2004
Posts: 2,496
|
Code:
background = ImageSource( "composebug_bg.png", 1, 5600, 24, pixel_type="RGB24" ).ConvertToRGB32() foreground = ImageSource( "composebug_fg.png", 1, 5600, 24, pixel_type="RGB32" ) foreground.showalpha m_background=overlay(background,foreground.showalpha,mode="multiply",pc_range=true) overlay(m_background,foreground,mode="add",pc_range=true) David |
28th June 2013, 18:50 | #13 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
So, the source image is 8-bit, and somehow it's still possible to have the correct output in AE. |
|
28th June 2013, 18:56 | #14 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
|
|
28th June 2013, 19:15 | #15 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
Code:
m_background=overlay(background,foreground.showalpha.invert(),mode="multiply",pc_range=true) |
|
28th June 2013, 19:38 | #16 | Link |
Registered User
Join Date: Oct 2004
Posts: 131
|
Wow, thanks, this is finally it! Perfect!
Code:
background = ImageSource( "composebug_bg.png", pixel_type="RGB24" ).ConvertToRGB32() foreground = ImageSource( "composebug_fg.png", pixel_type="RGB32" ) m_background=overlay(background,foreground.showalpha.invert(),mode="multiply",pc_range=true) overlay(m_background,foreground,mode="add",pc_range=true) |
28th June 2013, 19:44 | #18 | Link | |
Registered User
Join Date: Oct 2004
Posts: 131
|
Quote:
To make a crazy illustration, here is on a rainbow background: with invert: without invert: |
|
28th June 2013, 21:58 | #20 | Link | ||
Registered User
Join Date: Jul 2010
Location: Germany
Posts: 357
|
Quote:
Quote:
|
||
|
|