Dual ISO - massive dynamic range improvement (dual_iso.mo)

Started by a1ex, July 16, 2013, 06:33:50 PM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

a1ex

Tried that with enfuse, but resolution was not exactly the best. Check the PDF at recovering full-res detail; the general idea still holds, but the exposure matching was improved a lot.

a1ex

I've updated the cr2hdr binary from the first post to consider two white levels (one for each exposure), and also lowered the safety margin. You will need it if you use Dual ISO with the new ADTG trick, and it might also squeeze a tiny bit of more highlight detail from plain dual ISO shots too.

As a side effect, some of your shots might become a little darker (because of the extra highlight detail) or brighter (if you have really underexposed them). Just drag the exposure slider when postprocessing.

Don't expect miracles though - most of my test shots did not change at all.

Source code on request, or after 3 weeks, as promised.

Marsu42

Quote from: a1ex on January 23, 2014, 12:11:53 PMYou will need it if you use Dual ISO with the new ADTG trick, and it might also squeeze a tiny bit of more highlight detail from plain dual ISO shots too.

Ugh - why only a tiny bit of more dr - or didn't you adjust the dual_iso module for mini_iso yet? Shouldn't the effect add up, i.e. 2x0.5ev improvement = ~1ev of more added gain for dual_iso :-o ... at least that's why I though, I hope I didn't get it completely wrong?

Btw: *Request* source code link, thanks.

a1ex

The only real change was a more robust white level detection. The old one simply failed to detect the white level properly on my test shot and defaulted to 12500 instead of over 15000. On other test shots it might just work (I only tried one).

dual_iso.mo works out of the box; the only update needed is on the UI side (to print ISO 77/1230 instead of 100/1600).


# HG changeset patch
# User alex@thinkpad
# Date 1390472019 -7200
# Branch unified
# Node ID d0ac7698f856d247ee874ffd61b7f77c23758406
# Parent  b41e4e47a8b0f6c2271216285807d44634ac25fd
cr2hdr: experimental white level routine with two separate levels for each exposure

diff -r b41e4e47a8b0 -r d0ac7698f856 modules/dual_iso/cr2hdr.c
--- a/modules/dual_iso/cr2hdr.c Wed Jan 22 11:17:25 2014 +0200
+++ b/modules/dual_iso/cr2hdr.c Thu Jan 23 12:13:39 2014 +0200
@@ -293,7 +293,7 @@
static int hdr_interpolate();
static int black_subtract(int left_margin, int top_margin);
static int black_subtract_simple(int left_margin, int top_margin);
-static int white_detect();
+static void white_detect(int* white_dark, int* white_bright);

static inline int raw_get_pixel16(int x, int y) {
     unsigned short * buf = raw_info.buffer;
@@ -493,7 +493,6 @@

         if (hdr_check())
         {
-            white_detect();
             if (!black_subtract(left_margin, top_margin))
                 printf("Black subtract didn't work\n");

@@ -544,7 +543,7 @@
     return 0;
}

-static int white_detect_brute_force()
+static void white_detect(int* white_dark, int* white_bright)
{
     /* sometimes the white level is much lower than 15000; this would cause pink highlights */
     /* workaround: consider the white level as a little under the maximum pixel value from the raw file */
@@ -553,10 +552,11 @@
     
     /* ignore hot pixels when finding white level (at least 50 pixels should confirm it) */
     
-    int white = raw_info.white_level * 5 / 6;
-    int whites[8] = {white+500, white+500, white+500, white+500, white+500, white+500, white+500, white+500};
-    int maxies[8] = {white, white, white, white, white, white, white, white};
-    int counts[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    int white = 10000;
+    int whites[2] = {0, 0};
+    int maxies[2] = {white, white};
+    int counts[2] = {0, 0};
+    int safety_margins[2] = {100, 2000}; /* use a higher safety margin for the higher ISO */

     int x,y;
     for (y = raw_info.active_area.y1; y < raw_info.active_area.y2; y ++)
@@ -564,7 +564,7 @@
         for (x = raw_info.active_area.x1; x < raw_info.active_area.x2; x ++)
         {
             int pix = raw_get_pixel16(x, y);
-            #define BIN_IDX ((y%4) + (x%2)*4)
+            #define BIN_IDX is_bright[y%4]
             if (pix > maxies[BIN_IDX])
             {
                 maxies[BIN_IDX] = pix;
@@ -575,30 +575,26 @@
                 counts[BIN_IDX]++;
                 if (counts[BIN_IDX] > 50)
                 {
-                    whites[BIN_IDX] = maxies[BIN_IDX];
+                    whites[BIN_IDX] = maxies[BIN_IDX] - safety_margins[BIN_IDX];
                 }
             }
             #undef BIN_IDX
         }
     }

-    //~ printf("%8d %8d %8d %8d %8d %8d %8d %8d\n", whites[0], whites[1], whites[2], whites[3], whites[4], whites[5], whites[6], whites[7]);
-    //~ printf("%8d %8d %8d %8d %8d %8d %8d %8d\n", counts[0], counts[1], counts[2], counts[3], counts[4], counts[5], counts[6], counts[7]);
+    /* no confirmed max? use unconfirmed ones */
+    if (whites[0] == 0) whites[0] = maxies[0] - safety_margins[0];
+    if (whites[1] == 0) whites[1] = maxies[1] - safety_margins[1];
+
+    //~ printf("%8d %8d\n", whites[0], whites[1]);
+    //~ printf("%8d %8d\n", counts[0], counts[1]);
     
-    int white1 = MIN(MIN(whites[0], whites[1]), MIN(whites[2], whites[3]));
-    int white2 = MIN(MIN(whites[4], whites[5]), MIN(whites[6], whites[7]));
-    white = MIN(white1, white2);
-    raw_info.white_level = white - 500;
-    printf("White level     : %d\n", raw_info.white_level);
-    return 1;
+    *white_dark = whites[0];
+    *white_bright = whites[1];
+   
+    printf("White levels    : %d %d\n", *white_dark, *white_bright);
}

-static int white_detect()
-{
-    return white_detect_brute_force();
-}
-
-
static int black_subtract(int left_margin, int top_margin)
{
     if (debug_black)
@@ -1028,7 +1024,7 @@
{
     /* guess ISO - find the factor and the offset for matching the bright and dark images */
     int black = raw_info.black_level;
-    int white = raw_info.white_level;
+    int white = MIN(raw_info.white_level, *white_darkened);

     int w = raw_info.width;
     int h = raw_info.height;
@@ -1492,7 +1488,10 @@

     if (!identify_bright_and_dark_fields(rggb))
         return 0;
-   
+
+    int white_bright = white;
+    white_detect(&white, &white_bright);
+
     double noise_std[4];
     double noise_avg;
     for (y = 0; y < 4; y++)
@@ -1514,6 +1513,9 @@
     bright_noise *= 4;
     dark_noise_ev += 2;
     bright_noise_ev += 2;
+    white *= 4;
+    white_bright *= 4;
+    raw_info.white_level = white;

     /* dark and bright exposures, interpolated */
     unsigned short* dark   = malloc(w * h * sizeof(unsigned short));
@@ -1578,14 +1580,14 @@
     //~ printf("Histogram matching...\n");
     /* estimate ISO difference between bright and dark exposures */
     double corr_ev = 0;
-    int white_darkened = white;
+    int white_darkened = white_bright;
     
     int ok = match_histograms(&corr_ev, &white_darkened);
     if (!ok) goto err;

     /* estimate dynamic range */
     double lowiso_dr = log2(white - black) - dark_noise_ev;
-    double highiso_dr = log2(white - black) - bright_noise_ev;
+    double highiso_dr = log2(white_bright - black) - bright_noise_ev;
     printf("Dynamic range   : %.02f (+) %.02f => %.02f EV (in theory)\n", lowiso_dr, highiso_dr, highiso_dr + corr_ev);

     /* correction factor for the bright exposure, which was just darkened */

Audionut

Quote from: a1ex on January 23, 2014, 12:35:47 PM
On other test shots it might just work (I only tried one).

Any dual_iso shots of mine in the ADTG thread, were with mini_iso. 

a1ex

I believe the only side effect in the old one was - in some cases - white level too low in the output DNG, and wrong numbers printed in the log. If the raw processing software is respecting the EXIF white level religiously (like ufraw does), this bug could have resulted in highlight clipping too (negating the advantage of mini_iso).

joeexyz

Hi, It's there has any way to use the ETTR with DUAL_ISO when Recovery ISO is - EV?
because some time I shot on the street in afternoon,
have to use ISO like 1600 or higher to get the shuter speed.
but it's seem not work if the recovery ISO at - EV.

English is not my native language, Plz Forgive me if there have some bad grammar or typo. :D

again, Very thanks to Dev team for the amazing job!

a1ex

Last time I've used this, it was working. See http://www.chiark.greenend.org.uk/~sgtatham/bugs.html

Keep in mind that properly exposed (unclipped) ISO 1600 is going to be cleaner than ISO 1600/100. Dual ISO works best when you expose to the right for ISO 100, not for a higher ISO.

joeexyz

Sorry for the incoherent,

But after read the info.  "Take a test picture.Next pic will be ETTR"

Maybe I need to check my Eyes now....  lol

Everything works perfectly now.

a1ex

With dual ISO, I'd use ETTR in LiveView (on SET). With "always on" it may require many test pictures until it settles (and in LV it has more freedom to try various settings).

joeexyz


l_d_allan

Quote from: a1ex on January 23, 2014, 12:11:53 PM
if you use Dual ISO with the new ADTG trick, and it might also squeeze a tiny bit of more highlight detail from plain dual ISO shots too

I did a search on "ADTG" and found some threads that were way over my non-dev head. I tried searching for "ADTG trick" and didn't come across anything that explained what the trick was. I infer it has something to do with Dual-ISO, and perhaps some parameter in cr2hdr.exe.

Is this something that if you have to ask what it stands for, you have no business trying it? Or re-read the .pdf?


ted ramasola

Quote from: l_d_allan on January 24, 2014, 10:55:29 PM
I did a search on "ADTG" and found some threads that were way over my non-dev head. I tried searching for "ADTG trick" and didn't come across anything that explained what the trick was. I infer it has something to do with Dual-ISO, and perhaps some parameter in cr2hdr.exe.

Is this something that if you have to ask what it stands for, you have no business trying it? Or re-read the .pdf?

http://www.magiclantern.fm/forum/index.php?topic=10111.0

http://magiclantern.wikia.com/wiki/ADTG
5DmkII  / 7D
www.ramasolaproductions.com
Texas

carpediem86

EDIT: Found it, nevermind. Its in the "EXPO" tab. Sorry for a newbie question.

"Usage
- 5D3: works for both raw photo and raw video. 7D: photo only.
- Select one ISO from Canon menu, the other from Dual ISO submenu.
- Expose to the right for the lower ISO (usually ISO 100). Maybe darken 1 stop from there.
- Start at ISO 100/800.
- Try a larger gap for really extreme situations, or a smaller gap for better midtone detail (less aliasing)."


I can't find the submenu for Dual ISO :/ I have a Canon 7d with this firmware installed and activated dual_iso in the modules menu and restarted my camera, but where is the dual iso submenu? Tried clicking the Q button but there is only some information about the author.

Marsu42

Quote from: carpediem86 on January 25, 2014, 04:41:21 PM
Tried clicking the Q button but there is only some information about the author.

Try cycling through the top icon bar with the wheel :-> and find the expo tab ... ML is loaded with features which makes it confusing for newbies, but you can hide all options you don't need with the "customize menus" option (you'll stumble upon it sooner or later in one of the menus :-)).

l_d_allan


Marsu42

Quote from: a1ex on January 23, 2014, 12:35:47 PMdual_iso.mo works out of the box; the only update needed is on the UI side (to print ISO 77/1230 instead of 100/1600).

I've got 3 dual_iso + mini_iso files that refuse to convert with current/patched cr2hdr, two show the same lines while one results in a checkerboard look I've never seen before. I'll pm you the link to the cr2 files & I'm posting the information here in case I'm not the only one.

a1ex


Marsu42


Marsu42

Concerning the cr2hdr chroma smoothing options: Is there some rule of thumb when to use what (yes, I know the default is probably the default for a reason)?

But might it be also sound to start with --no-cs and then add more --cs when aliasing (how does it look exactly?) occurs, or is the gain of --no-cs too small to be worth it, or is the --no-cs option even only there for speed?

joeexyz

Hi everyone, I noticed if use the dual_iso with the -EV (e.g. 800/100),  will get the images like this (see the bottom) :



but no problem with the +EV(100/800) 



Is it normal or just get the wrong setting?

Marsu42

Quote from: joeexyz on January 29, 2014, 05:06:25 PM
Is it normal or just get the wrong setting?

Looks like a bug, the best course of action is to submit a bug ticket to to the ml tracker with camera model, ml version, what you did yadayadayada. Probably no one noticed yet because the overwhelming majority shoots with +ev settings...

tzalman

I think that the reason is that you set the exposure according to ISO 800 but cr2hdr doesn't distinguish between 800/100 and 100/800, so to it the photo looked like an underexposed 100/800. Using -ev only makes sense if you overexpose to around ETTR + 1 stop. Whether you use +ev or -ev the higher ISO has to be for the shadows and therefore has to blow out the highlights.

swinxx

@a_d_:

i have just read that some new dual iso conversion code is available..
is there an update for the mac tool planned in the near future? would be really great.
thx.

arturochu

Is there a way to have dual iso enabled in photo mode and not in video mode? Im always switching between both and that would be a time saver.
Chu