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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd April 2009, 16:02   #1  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
Demosaic

Lately i was searching for a debayer filter for AviSynth. I only found a demosaic plugin. As the interpolation methods are very simple (nearest and bilinear), the quality are not really good (aliasing, color artifacts and so on). May be good enough for previewing.

So i wrote my own debayer function in AviSynth. More precisely, a script for Fritz Photo. May be, it’s not perfect now and we have to live with the 8 bit limitations, but the results seems to be quite stable. The function needs the NNEDI3 plugin.

Input is a RGB24 or RGB32 clip and output is a RGB32 clip. The function has two modes. Mode 1 is a little bit softer, but gives good results on portraits and so on. Mode 2 keeps the most details, while color artifacts are minimized. As the bayer pattern can be implemented in different ways, the parameters xoffset and yoffset take care about. For the parameters nsize, nns, qual and pscrn, please read the documentation of NNEDI3.

Code:
function Demosaic(clip input, int "mode", int "xoffset", int "yoffset", int "nsize", int "nns", int "qual", bool "pscrn") {
  mode = Default(mode, 2)
  xoffset = Default(xoffset, 0)
  yoffset = Default(yoffset, 0)

  nsize = Default(nsize, 6)
  nns = Default(nns, 1)
  qual = Default(qual, 2)
  pscrn = Default(pscrn, True)

  clip = input.Crop(0, 0, -(input.Width % 4), -(input.Height % 4)).ShowGreen("YV12")

  last = clip
  yoffset == 0 ? AssumeFrameBased().SeparateFields().SelectOdd() : AssumeFrameBased().SeparateFields().SelectEven()
  TurnRight()
  xoffset == 0 ? AssumeFrameBased().SeparateFields().SelectEven() : AssumeFrameBased().SeparateFields().SelectOdd()
  TurnLeft()
  yoffset == 0 ? NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnRight()
  xoffset == 0 ? NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnLeft()
  R = last

  last = clip
  yoffset == 0 ? AssumeFrameBased().SeparateFields().SelectEven() : AssumeFrameBased().SeparateFields().SelectOdd()
  TurnRight()
  xoffset == 0 ? AssumeFrameBased().SeparateFields().SelectEven() : AssumeFrameBased().SeparateFields().SelectOdd()
  TurnLeft()
  yoffset == 0 ? NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnRight()
  xoffset == 0 ? NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnLeft()
  G1 = last

  last = clip
  yoffset == 0 ? AssumeFrameBased().SeparateFields().SelectOdd() : AssumeFrameBased().SeparateFields().SelectEven()
  TurnRight()
  xoffset == 0 ? AssumeFrameBased().SeparateFields().SelectOdd() : AssumeFrameBased().SeparateFields().SelectEven()
  TurnLeft()
  yoffset == 0 ? NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnRight()
  xoffset == 0 ? NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnLeft()
  G2 = last

  mode == 1  ? Eval("""
    G = G1.MergeLuma(G2, 0.5)
  """) : Eval("""
    NOP()
  """)

  mode == 2  ? Eval("""
    G1.TurnRight()
    g11 = AssumeFrameBased().SeparateFields().SelectEven()
    g12 = AssumeFrameBased().SeparateFields().SelectOdd()

    G2.TurnRight()
    g21 = AssumeFrameBased().SeparateFields().SelectEven()
    g22 = AssumeFrameBased().SeparateFields().SelectOdd()

    xoffset == 0 ? Interleave(g11, g12.MergeLuma(g22, 0.5)) : Interleave(g11.MergeLuma(g21, 0.5), g12)
    AssumeFieldBased()
    Weave()
    TurnLeft()
    G1 = last

    xoffset == 0 ? Interleave(g21.MergeLuma(g11, 0.5), g22) : Interleave(g21, g22.MergeLuma(g12, 0.5))
    AssumeFieldBased()
    Weave()
    TurnLeft()
    G2 = last

    yoffset == 0 ? Interleave(G1.AssumeFrameBased().SeparateFields().SelectEven(), G2.AssumeFrameBased().SeparateFields().SelectOdd()) : Interleave(G2.AssumeFrameBased().SeparateFields().SelectEven(), G1.AssumeFrameBased().SeparateFields().SelectOdd())
    AssumeFieldBased()
    Weave()

    nnedi3_rpow2(rfactor=2, nsize=0, nns=1, qual=2, pscrn=True, cshift="Spline36Resize", fwidth=last.Width, fheight=last.Height)

    G = last
  """) : Eval("""
    NOP()
  """)

  (mode < 1) || (mode > 2)  ? Eval("""
    G = G1.MergeLuma(G2, 0.5)
  """) : Eval("""
    NOP()
  """)

  last = clip
  yoffset == 0 ? AssumeFrameBased().SeparateFields().SelectEven() : AssumeFrameBased().SeparateFields().SelectOdd()
  TurnRight()
  xoffset == 0 ? AssumeFrameBased().SeparateFields().SelectOdd() : AssumeFrameBased().SeparateFields().SelectEven()
  TurnLeft()
  yoffset == 0 ? NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnRight()
  xoffset == 0 ? NNEDI3(dh=True, field=1, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn) : NNEDI3(dh=True, field=0, Y=True, U=False, V=False, nsize=nsize, nns=nns, qual=qual, pscrn=pscrn)
  TurnLeft()
  B = last

  MergeRGB(R, G, B)
}

Last edited by Archimedes; 21st July 2010 at 16:21.
Archimedes is offline   Reply With Quote
Old 4th April 2009, 02:59   #2  |  Link
Comatose
Registered User
 
Join Date: Dec 2007
Posts: 639
Can you show a before and after please?
Comatose is offline   Reply With Quote
Old 4th April 2009, 18:41   #3  |  Link
Sagekilla
x264aholic
 
Join Date: Jul 2007
Location: New York
Posts: 1,752
This script only seems to output a grayscale image, regardless of whether you give it regular YV12 input or grayscale YV12 input.

And it shouldn't matter whether I give it input from a non-debayerized source and a faked source like grayscale YV12, since the two should look identical to your script.
__________________
You can't call your encoding speed slow until you start measuring in seconds per frame.
Sagekilla is offline   Reply With Quote
Old 7th April 2009, 19:07   #4  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
Quote:
Originally Posted by Comatose View Post
Can you show a before and after please?
Before and after is something like this:

Before:


After (not white balanced):


And it's not a greyscale output.
Archimedes is offline   Reply With Quote
Old 7th April 2009, 19:21   #5  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
can you show a sample that is near to (or exceeds) the nyquist frequency?

ie, a sample that is prone to aliasing or false colour in highly detailed areas.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 7th April 2009, 21:44   #6  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
Here are some examples (without white balance). The original raw file has only 8 bit.

1.1 Demosaic (method=nearest):


1.2 Demosaic (method=bilinear):


1.3 FritzPhotoDemosaic (Mode=1):


1.4 FritzPhotoDemosaic (Mode=2):


2.1 Demosaic (method=nearest):


2.2 Demosaic (method=bilinear):


2.3 FritzPhotoDemosaic (Mode=1):


2.4 FritzPhotoDemosaic (Mode=2):
Archimedes is offline   Reply With Quote
Old 3rd July 2009, 23:44   #7  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
Update the script for use with NNEDI2.
Archimedes is offline   Reply With Quote
Old 4th July 2009, 14:48   #8  |  Link
AnnaFan777
Registered User
 
Join Date: Apr 2008
Posts: 51
how does it compare to DCdraw ?

http://www.cybercom.net/~dcoffin/dcraw/
AnnaFan777 is offline   Reply With Quote
Old 6th July 2009, 19:24   #9  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
I've realized, that in mode 2 the image center shift of channel G was not corrected. This is fixed now.

Quote:
Originally Posted by AnnaFan777 View Post
how does it compare to DCdraw ?
How we can compare? dcraw can handle 16 bit inputs, Demosaic, as a proof of concept, can only work in 8 bit mode. Demosaic filters each channel (R, G1, G2 and B) separately, dcraw works per default an all channels. However, it has an option (-f), to work on each channel separately.

In default mode, the results from dcraw looks much sharper (may be more detailed), but you have to deal with aliasing, color artefacts and labyrinth patterns (depending on the sources). One solution against such color artefacts and labyrinth patterns is, to interpolate the RGGB pattern as four colors (option –f). But the results looks less sharpen now (similar to the results of the demosaic function). However, a strong sharpening filter afterwards produces more aliasing on the dcraw source.

Last edited by Archimedes; 6th July 2009 at 19:27.
Archimedes is offline   Reply With Quote
Old 7th July 2009, 14:05   #10  |  Link
Mug Funky
interlace this!
 
Mug Funky's Avatar
 
Join Date: Jun 2003
Location: i'm in ur transfers, addin noise
Posts: 4,555
i wonder if at some future point we could see a tritical build of dcraw?

or a nnedi2'ed hack of the redcode codec?

that's way too much to put on the poor guy though.
__________________
sucking the life out of your videos since 2004
Mug Funky is offline   Reply With Quote
Old 11th July 2009, 13:35   #11  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
have you guys tried kolev raw so far?
it seems to implement some kind of edge directed interpolation.

I never use it though for other reasons.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 14th July 2009, 18:54   #12  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
Quote:
Originally Posted by scharfis_brain View Post
have you guys tried kolev raw so far?
it seems to implement some kind of edge directed interpolation.
Not tested. Another alternative raw converter is RAWHide which offers AAC Demosaicing.

Quote:
Advanced Chroma Corrective Demosaicing. This may be the one of most accurate and advanced routines available. This routine extracts the highest resolution and most detail with the lowest instance of moiré and color artifacts. Where the routines used in other programs fail, ACC excels. Trade-Offs: Best resolution and color artifact resistance vs. Lower point data accuracy then EWC and less natural grain in images with high ISO and extreme white balance. Red's can be "noisy".
But i haven't tested it so far.
Archimedes is offline   Reply With Quote
Old 19th December 2009, 02:14   #13  |  Link
markanini
Registered User
 
Join Date: Apr 2006
Posts: 299
Dear Archimedes,

I'm intrigued by the NNEDI2 demosiac. I found a thread in the german dslrforum http://www.dslr-forum.de/showthread.php?t=467892&page=9 your script was discussed and you posted a build of dcraw, what was the point of that build(my german is poor). Was it a patch to add 8-bit linear gamma output?

Last edited by markanini; 19th December 2009 at 04:46. Reason: forgot dcraw has a manpage...
markanini is offline   Reply With Quote
Old 21st December 2009, 10:38   #14  |  Link
Archimedes
Registered User
 
Join Date: Apr 2005
Posts: 213
I try to recapitulate it.

There was a problem with a handy photo. The handy supported an 8 bit raw format, but saved it as a non linear grayscale tiff format (with the bayer pattern). Most raw converter interpreted this format as a normal graphic format, but not as a raw. First, i tried the Demosic-Plugin, which works, but the results was not very good. The author of dcraw then make some patches, where the tiff format was interpreted as a raw format. At the same time i have the idea with NNEDI to do the demosaicing.

The answers of the author of dcraw regarding the different patches in chronological order:

Quote:
Pretty good image for a camera phone. See the patch
below.

Serious problems remain. First, the patch at 5403 makes
dcraw attempt to decode _all_ 8-bit grayscale TIFFs, which is
not good.

Secondly, the image is not white-balanced, and cannot be
without first linearizing it. The variable "use_gamma" should
be eliminated. Instead, all raw images should be linearized
upon loading.

Source >>
Quote:
The 8-bit TIFF data is gamma adjusted, and white
balance will not work until the data gets correctly
linearized. I'm updating the gamma logic to generate
inverse gamma curves for this purpose, assuming that
the camera used BT.709 or sRGB gamma.

Source >>
After he has received some test charts of the handy owner, he answered:

Quote:
This is interesting. I expected the linearization
curve to be a power function, but it's actually an
exponential with a tangent to the origin. I've updated
dcraw.c to generate such curves.

Both graphs plot calibrated patch brightness across
the bottom, and the RGB values reported by the camera in
the vertical direction.

Before
After

Source >>
Quote:
Originally Posted by markanini View Post
Was it a patch to add 8-bit linear gamma output?
So it was a patch from the author of dcraw (i only compiled the source code) to make a correct linearisation of the non linear input data (used for white balancing).

Last edited by Archimedes; 21st December 2009 at 10:54.
Archimedes is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:26.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.