View Full Version : feature request: extractred/green/blue() ; mergergb()
scharfis_brain
16th April 2005, 15:18
I want to start a feature request for a functionality AVIsynth already offers for YUV-based video:
y=greyscale()
u=utoy()
v=vtoy()
ytouv(u,v,y)
I would like to see the same for rgb24 and rgb32 chroma:
r=extractred() / rtoy()
b=extractgreen() / gtoy()
g=extractblue() / btoy()
mergergb(r,g,b)
is there a chance to get these functions?
stickboy
16th April 2005, 16:07
Splitting can be done with RGBAdjust:
r = c.RGBAdjust(1, 0, 0, 0)
g = c.RGBAdjust(0, 1, 0, 0)
b = c.RGBAdjust(0, 0, 1, 0)I haven't figured out how to merge though, if it's possible at all.
scharfis_brain
16th April 2005, 16:34
That's what I've already found out.
but merging with overlay introduces big brightness loss
and abusing subtract & invert to build an add() function also fails :(
tsp
16th April 2005, 17:57
I'm on it. First version should be ready in a couple of hours.
tsp
16th April 2005, 20:23
get it here (http://www.tsp.person.dk/RGBmanipulate.zip)
From the readme:
syntax
RtoRGB()
copies the Red value to Green and Blue resulting in a greyscale image.
GtoRGB()
copies the Green value to Red and Blue resulting in a greyscale image.
BtoRGB()
copies the Blue value to Red and Green resulting in a greyscale image.
MergeRGB(clip R,clip G,clip B)
copies the green value from G to R and the blue value from B to R
Todo:
Add mmx support.
0.1 first release.
sourcecode released under GPL se copying.txt
Mug Funky
17th April 2005, 15:13
cool! thanks! i've been wanting something like this for ages (though only idly - otherwise i'd have made a thread...).
IMHO this should end up in the avs core, alongside it's cousins utoy, vtoy, etc.
Wilbert
17th April 2005, 15:57
IMHO this should end up in the avs core, alongside it's cousins utoy, vtoy, etc.
If tsp adds mmx support i will look at it ...
scharfis_brain
17th April 2005, 17:39
Many thanks TSP!
I've digged out an about 1.5 years old function from me to test it:
Clearscale.
function clearscale(clip i, int width, int height, int "filter")
{
filter=default(filter,2)
i.converttorgb32()
#resize to destination size with triple width;
#add 3 pixels on the right side to get room for image shifting
bicubicresize((width*3),height).addborders(0,0,3,0)
#do a prefiltering to supress color speckling
(filter==0) ? last : (filter==1) ? last.blur(1,0) : last.blur(1,0).blur(1,0)
# select spatial correct color planes
R=crop(2,0,-1,0).pointresize(width,height).RtoRGB()
G=crop(1,0,-2,0).pointresize(width,height).GtoRGB()
B=crop(0,0,-3,0).pointresize(width,height).BtoRGB()
#finally merge color planes
MergeRGB(R,G,B)
}
Clearscale will scale your input video paying attention to our LCDs subpixel structure. You'll actually gain a factor of three regarding phase information in the horizontal direction.
Of coure, the images needs to be saved either lossless (PNG, BMP, TIF)
or with non-subsampled-chroma JPG.
With your plugin I got it working again without cracking my brain about subtract, layers and so on :)
vinetu
17th April 2005, 19:44
scharfis_brain,
I can't get it - the Clearscale.
In fact every 3 subpixels on LCD matrix are threaded as single pixel, so by this script you'll probably change the overall image look,collor crispness etc...
It's somehow an opposite to debayer filter?
Did you see an improvement on your side (I don't have a LCD panel around yet) ?
scharfis_brain
17th April 2005, 20:36
Nonono...
the clearscale effekt only becomes visible if you are downsizing a crisp image at least by a factor of three in the horizontal dimension!
It works similar to Microsofts Cleartype or Adobes Cooltype.
Have a look:
the original (360x360):
http://home.arcor.de/scharfis_brain/samples/cl-before.png
bicubic to 120x120: pointscaling:
http://home.arcor.de/scharfis_brain/samples/bicubic.png http://home.arcor.de/scharfis_brain/samples/point.png
clearscale with 2pass, 1pass and without filtering:
http://home.arcor.de/scharfis_brain/samples/clearscale2.png http://home.arcor.de/scharfis_brain/samples/clearscale1.png http://home.arcor.de/scharfis_brain/samples/clearscale0.png
vinetu
17th April 2005, 22:29
Ah! It's much clear now :)
Thank You for this Example!
tsp
18th April 2005, 01:12
I added some mmx optimization to the code. I'm not sure it was worth it but try and see if you get any speed increase.
link to version 0.2: http://www.tsp.person.dk/RGBmanipulate02.zip
Mug Funky
18th April 2005, 05:03
the twopass pic doesn't look any different on this LCD panel... but that might be because the screen's set to 16bpp (the viddy card is pretty old unfortunately, and can't go as high as the screen it's plugged into without going to 16bpp)
scharfis_brain
18th April 2005, 16:58
Edited my samples above.
The effect should be more visible now.
IanB
21st April 2005, 01:45
Tsp,
Neat ;)
It's not easy getting MMX to work fast. :sly: Try using flavours of punpck[lh][bwd][wdq] to distribute the colour channels throughout the pixel rather than masking and shifting. Try to access memory aligned 64bits at a time.
Dear all,
Also might it be useful (it could be faster) to export the colour channels to a YV12[0..255] luma plane, dummying up the chroma planes as grey or maybe the colour for bonus points.
This feature rates going into the core. Just need some time...
IanB
tsp
22nd April 2005, 02:29
IanB: Is it okay to overwrite the alpha channel or is there anything that uses it?
with the current optimization(not released yet) the mmx version is about 20% faster than the c version.
IanB
23rd April 2005, 09:10
tsp,
Layer and Overlay make use of the Alpha channel. Generally it is preferable not to clobber the alpha channel. However given this filter currently copies a chosen channel to the other 2 it is not a great stretch to define it to copy a channel to the other 3. It certainly makes the MMX code easier. And the core currently has a ShowAlpha(clip, string pixel_type) which is just C code, it copies the Alpha to the R, G and B channels, so there is a precedent.
For the MMX code I was thinking along the lines of
movq mm0,[src]
movq mm1,[src+8]
pand mm0,k000000ff000000ff // dd p1, p0
pand mm1,k000000ff000000ff // dd p3, p2
packssdw mm0,mm1 // dw p3, p2, p1, p0
packuswb mm0,mm0 // db p3, p2, p1, p0, p3, p2, p1, p0
punpcklbw mm0,mm0 // db p3, p3, p2, p2, p1, p1, p0, p0
movq mm1,mm0
punpcklbw mm0,mm0 // db p1, p1, p1, p1, p0, p0, p0, p0
punpckhbw mm1,mm1 // db p3, p3, p3, p3, p2, p2, p2, p2
movq [dst],mm0
movq [dst+8],mm1
as this code only uses 3 registers you could add a 2nd (or 3rd) stream and process 8 (or 12) pixels at once, it should really scream :sly:
IanB
sh0dan
24th April 2005, 18:20
Originally posted by IanB
Layer and Overlay make use of the Alpha channel.
Just for the record - overlay uses luma from a separate video stream for alpha. Too many filters destroy alpha information anyway, so I figured it was easier to not rely on it. That being said there is no reason to kill alpha on purpose. :)
tsp
25th April 2005, 00:13
more update. now the mmx should work correctly. Get version 0.3 here (http://www.tsp.person.dk/RGBmanipulate03.zip).
The current mmx code preserves the alpha channel. The reason to kill the channel would be speed. IanB's code performce about 22% faster than the c code in my last test(RtoRGB). The current mmx code is about 15% faster than the c code. I think I will just add an option to keep the alpha channel then people get a choice what to get. Also I will convert the inline assembly to softwire there is to much repeated mmx code.
tsp
30th April 2005, 01:00
Version 0.4 is ready. Get it here (http://www.tsp.person.dk/RGBManipulate04.zip).
Softwire is really nice but it's irritating that I can't convert a __cdecl function pointer to a thiscall function pointer without using inline asm. I thought reinterpret_cast would work but it didn't.
scharfis_brain: you don't need RtoRGB,GtoRGB,BtoRGB for your function MergeRGB will do.
From the readme.txt
RGBmanipulate mirrors the function utoy vtoy mergeLuma/chroma for the rgb colorspace
syntax:
RtoRGB(bool useMMX,bool overwritealpha, bool usemmx)
copies the Red channel to Green and Blue resulting in a greyscale image.
GtoRGB(bool useMMX,bool overwritealpha, bool usemmx)
copies the Green channel to Red and Blue resulting in a greyscale image.
BtoRGB(bool useMMX,bool overwritealpha, bool usemmx)
copies the Blue channel to Red and Green resulting in a greyscale image.
usemmx: enables mmx optimization. Default true
overwritealpha: If true the alpha channel is also overwriten (this is faster). Default false
MergeRGB(clip R,clip G,clip B,clip A,int alphachannel,bool usemmx)
Merge the Red channel from R the green channel from G and the blue channel from B
if A is specified(you don't have to) the alpha channel from A is used.
alphachannel specifies where the alpha channels should be used from if A isn't specified:
0 copies the alpha channel from R
1 copies the alpha channel from G
2 copies the alpha channel from B
3 zeroes the alpha channel
Default 0
vinetu
30th April 2005, 19:38
Originally posted by tsp
alphachannel specifies where the alpha channels should be used from if A isn't specified:
0 copies the alpha channel from R
1 copies the alpha channel from G
2 copies the alpha channel from B
3 zeroes the alpha channel
Default 0
Thank You tsp!
Just One remark - the Default value for alphachannel should be 3 or something like "don't touch alpha"...no?
Best Regards!
vinetu: I have set it to zero to match the default argument for RtoRGB which preserves the alpha channel. So if you use it like this:
src.RtoRGB.MergeRGB(src.GtoRGB,src.BtoRGB)
the alpha channel is unaltered. If alphachannel=3 it would be set to 0.
vinetu
1st May 2005, 18:57
OK, now i understand.
Thank You tsp!
gzarkadas
8th October 2005, 04:57
@tsp
Congratulations at first, I consider this plugin a must-to-have and I intend to use it a lot.
I have made a test script though, shown at the end of the message, and discovered (at least this is my impression) that the RtoRGB, BtoRGB functions actually return the R,B channels exchanged, ie R... returns blue, B... returns red.
This does not show up when recombining (maybe because channels are also exchanged on merge?) but it will show up if the channels are modified.
Could you check on that please?
LoadPlugin("..\RGBmanipulate.dll")
dim = 64
# create a test clip with top-row white,grey,black and bottom row pure r,g,b
c = StackVertical( \
StackHorizontal( \
BlankClip(color=$ffffff, width=dim, height=dim), \
BlankClip(color=$777777, width=dim, height=dim), \
BlankClip(color=$000000, width=dim, height=dim) ), \
StackHorizontal( \
BlankClip(color=$ff0000, width=dim, height=dim), \
BlankClip(color=$00ff00, width=dim, height=dim), \
BlankClip(color=$0000ff, width=dim, height=dim) ) )
r = c.RtoRGB()
g = c.GtoRGB()
b = c.BtoRGB()
d = MergeRGB(r,g,b)
return StackVertical( StackHorizontal( \
r.SubTitle("R"), g.SubTitle("G"), b.SubTitle("B") \
), StackHorizontal(c, c, d) )
Posted code is provided under the GNU General Public Licence (http://www.gnu.org/licenses/gpl.html), Version 2.0 or any later version published by the Free Software Foundation.
tsp
9th October 2005, 22:52
gzarkadas: hmm your right about that. It seems as if I forgot that RGB is saved as BGR . Also that script uncovered a couple of bugs that only shows up under special circumstances. I will release a bugfix shortly.
gzarkadas
10th October 2005, 15:48
.... I will release a bugfix shortly.
That's great!
I have noticed after my previous post :rolleyes: that the plugin's features have been incorporated in Avisynth 2.5.6 RC2.
Nevertheless, I am considering to include RGB channels support for version 2.5.5 in the next version of AVSLib (http://avslib.sourceforge.net/) together with some new routines to provide the ability to manipulate channels as a whole (channels fit very well with the concept of arrays that AVSLib introduces).
For this purpose it would be nice to be able to emulate all new Avisynth 2.5.6 functions (Show{Red/Green/Blue}, MergeRGB, MergeARGB) with wrapper functions calling the functions of your plugin (with due credit of course in the documentation); the import code would then detect Avisynth version and if < 2.56 would load the plugin.
However MergeRGB is clashing with the same function name in Avisynth 2.5.6. Is it possible to also consider a rename of this function (say RGBMerge or Merge_RGB) in the bugfix?
Wilbert
10th October 2005, 16:06
You can call them with the name of the dll in front of it, so
RGBmanipulate_MergeRGB, RGBmanipulate_MergeARGB, etc ...
Btw, is that bug also present in 2.5.6 RC2?
gzarkadas
10th October 2005, 17:16
You can call them with the name of the dll in front of it, so
RGBmanipulate_MergeRGB, RGBmanipulate_MergeARGB, etc ...
Btw, is that bug also present in 2.5.6 RC2?
Thanks, I had forgotten that :)
The bug is not present in 2.5.6 RC2; used a modification of the initial test script to verify (see below):
dim = 64
# create a test clip with top-row white,grey,black and bottom row pure r,g,b
c = StackVertical( \
StackHorizontal( \
BlankClip(color=$ffffff, width=dim, height=dim), \
BlankClip(color=$777777, width=dim, height=dim), \
BlankClip(color=$000000, width=dim, height=dim) ), \
StackHorizontal( \
BlankClip(color=$ff0000, width=dim, height=dim), \
BlankClip(color=$00ff00, width=dim, height=dim), \
BlankClip(color=$0000ff, width=dim, height=dim) ) )
r = c.ShowRed()
g = c.ShowGreen()
b = c.ShowBlue()
d = MergeRGB(r,g,b)
return StackVertical( StackHorizontal( \
r.SubTitle("R"), g.SubTitle("G"), b.SubTitle("B") \
), StackHorizontal(c, c, d) )
tsp
11th October 2005, 20:22
Now most of the bugs should be fixed (At least I couldn't find more). If someone looks at the source for 0.4 there are many good examples of how not to use MakeWritable. Get version 0.5 here (http://www.avisynth.org/tsp/RGBManipulate05.zip).
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.