Dynamic Range Optimization (ETTR) - Feature Requests - CHDK Forum  

Dynamic Range Optimization (ETTR)

  • 9 Replies
  • 4966 Views
*

Offline mkmenuts

  • **
  • 61
  • SD700 (1.01b)
Dynamic Range Optimization (ETTR)
« on: 25 / February / 2008, 14:36:11 »
Advertisements
I would like to propose a new CHDK feature and get your feedback.

The main idea is to better utilize the (limited) dynamic range available on the digital camera by:

1. Making sure no color channel (R, G or B) is saturated (blown)
2. Optimizing for the linear property of the image sensor by putting in POSITIVE exposure compensation (as long as rule [1] is kept)

This will result in Raw/Jpeg files that do not have the same brightness as the scene (a bad thing) but with either positive or negative EV/Curve post-processing you will get better pictures.

This is similar to the way Active D-Lighting (Nikon) works, but sadly, the second step of applying the right curve to the RAW file will need to be done manually (unless someone figures a way to do it automagically).

PROs:

1. Correct colors and no need for highlight recovery (which is never 100% effective).
2. Better shadow detail for scenes with lower dynamic range than the camera's full potential.
3. Better handling of the varying dynamic range when changing ISO setting (Manually or Automatically).
4. Should be great in low ISOs (50-80) where DR is relatively big.

CONs:
1. More noise when overcoming saturation (blown highlights)
2. Slight changes in intended shutter speed
3. Requires post-processing for many pictures. Image review not bright like final output.
4. Works better if RAW data available
5. May be problematic in high ISOs where DR is relatively small.

Feature description:
1. DRO will be a menu option in Extra Photo Operations
2. Submenu will include: Enable, maximal negative and positive change (in 1/3 EV steps, 0-2 EV), maximal ISO to operate in.
3. When DRO is on it will replace the EXP label and display DRO [+/-] ?.? [EXP] (+/- EV correction, the actual amount, and EXP if there's still over exposure.
4. DRO will be active always (not just after half-press).

Comments are welcome,

mkmenuts

*

Offline whim

  • ******
  • 2022
  • A495/590/620/630 ixus70/115/220/230/300/870 S95
Re: Dynamic Range Optimization (ETTR)
« Reply #1 on: 27 / February / 2008, 07:30:50 »
So this would be like a Dynamic Range Compression/Expansion as an alternative to HDR bracketing ?
Sounds cool, HDR without the flashcard space penalty  ( & maybe the expansion could be integrated into dng4ps-2  :))
Some kind of name change to the RAW name suffix or prefix would probably also be practical.

wim
 

Re: Dynamic Range Optimization (ETTR)
« Reply #2 on: 17 / July / 2008, 21:32:00 »
So this would be like a Dynamic Range Compression/Expansion as an alternative to HDR bracketing ?
Sounds cool, HDR without the flashcard space penalty  ( & maybe the expansion could be integrated into dng4ps-2  :))
Some kind of name change to the RAW name suffix or prefix would probably also be practical.

wim
 

Should this help? Custom processing for JPEG (Tone curve, CA ...)

The principle is to decrease the EV (using camera exposure control) until the Zebra warning areas are reduced to a satifactory level. You would have to expose for the dark area though (point the camera to the dark area during metering and select the EV and curve, half press, recompose and shoot).
Apply the EV base tone curve to amplify the dark area (the curve is linear up to a certain point and start compressing the highlight). For example: If you do -1EV you would apply a x2 multiplicator curve. Dark areas would end up looking almost the same as before EV reduction and highlight is compressed. (FujiFilm FinePix S100fs Review: 16. Photographic tests: Digital Photography Review). You don't even need to save RAW since we messed up with the RAW data before it is JPEG'ed.
« Last Edit: 17 / July / 2008, 22:07:55 by toinech »

*

Offline LjL

  • ****
  • 266
  • A720IS
Re: Dynamic Range Optimization (ETTR)
« Reply #3 on: 18 / July / 2008, 07:11:04 »
Ok, I haven't followed the whole reasoning since all the increase-EV-decrease-range-increase-that-decrease-this confuses me :P

But as for exposing so that no parts of the image are blown out, that has been discussed before and it should be possible to do it automatically - and if it's possible (i.e. the exposure adjustment functions are well behaved during half-shoot), then it's also easy, because it's a matter of adding a couple of lines to the zebra code.

Basically: if more than n pixels are out of scale, step down by the minimum possible amount (here the question is, step down shutter speed, aperture or ISO? I guess it would depend on the mode dial), repeat the process.


Re: Dynamic Range Optimization (ETTR)
« Reply #4 on: 18 / July / 2008, 22:15:57 »
Ok, I haven't followed the whole reasoning since all the increase-EV-decrease-range-increase-that-decrease-this confuses me :P

It definitely is.
For example you underexpose the picture by 1EV => RAW values are half of what they should be.
You then apply a curve that would multiple the RAW values of the dark portion by 2.
The trick is not to x2 the RAW value if it is greater than 450 for example.
Any values above 450 will be mutiplied by a factor less than 2 (it is where the highlite compression trick goes).

Usually I don't like to play with the Av because it may change your DOF.
I always try to shoot with the lowest ISO possible to avoid excessive noise.
My favorite is Tv for stepping down.

Re: Dynamic Range Optimization (ETTR)
« Reply #5 on: 18 / July / 2008, 22:26:13 »
But as for exposing so that no parts of the image are blown out, that has been discussed before and it should be possible to do it automatically - and if it's possible (i.e. the exposure adjustment functions are well behaved during half-shoot), then it's also easy, because it's a matter of adding a couple of lines to the zebra code.

Basically: if more than n pixels are out of scale, step down by the minimum possible amount (here the question is, step down shutter speed, aperture or ISO? I guess it would depend on the mode dial), repeat the process.

I did try my luck  for auto contrast using the histogram over/under expose warning flag instead of the Zebra thing without success. I may have missed something there.
There is also a histogram shoot feature in the Jucifer build. But I don't know how to use it.

*

Offline mkmenuts

  • **
  • 61
  • SD700 (1.01b)
Re: Dynamic Range Optimization (ETTR)
« Reply #6 on: 19 / July / 2008, 01:11:01 »
I actually implemented the real-time histogram "fixing" in my private build. It detects overexposure and reduces ISO accordingly. Anyone interested in this?

*

Offline LjL

  • ****
  • 266
  • A720IS
Re: Dynamic Range Optimization (ETTR)
« Reply #7 on: 19 / July / 2008, 07:31:54 »
mkmenuts, of course we are. But is it implemented using the histogram data? I ask because the histogram data is not entirely accurate, as the histogram width is less than 256, so you risk detecting overexposure even when there is none, if you just check for the presence of pixels at 0 or 256. Using the warning flags is another matter I guess, but I haven't looked at how they work yet.

toinech, what did you try changing, shutter speed, aperture or ISO? I've tried with shutter speed, and it "works" in the sense that shutter speed does indeed get changed, but the camera is unaware of it (as it often happens with CHDK functions), so it doesn't change the display brightness accordingly, which results in CHDK keeping reducing exposure ad infinitum.
And you won't see the new shutter speed, either, until you're finished shooting.


*

Offline Jucifer

  • *****
  • 251
  • [A710IS]
Re: Dynamic Range Optimization (ETTR)
« Reply #8 on: 19 / July / 2008, 09:41:13 »
toinech, the shot histogram (by fbonomi) data is a table, whose values are gotten from the raw data. The data is used to adjust Tv when making time lapses requiring long exposures.


mkmenuts, I'm interested. :]

*

Offline mkmenuts

  • **
  • 61
  • SD700 (1.01b)
Re: Dynamic Range Optimization (ETTR)
« Reply #9 on: 20 / July / 2008, 03:57:13 »
Well, here it is. This is a patch to the latest AllBest released (2 month ago?). I hope it is not too far behind.

Code: [Select]
diff -r f2cf9e6b707f core/conf.c
--- a/core/conf.c Tue Apr 01 12:30:59 2008 +0300
+++ b/core/conf.c Thu Apr 03 11:17:01 2008 +0300
@@ -291,6 +291,7 @@
     CONF_INFO(162, conf.autoiso_max_iso_hi,  CONF_DEF_VALUE, i:55, NULL),
     CONF_INFO(163, conf.autoiso_max_iso_auto,  CONF_DEF_VALUE, i:35, NULL),
     CONF_INFO(164, conf.autoiso_min_iso,  CONF_DEF_VALUE, i:5, NULL),
+    CONF_INFO(165, conf.autoiso_reduce_overexpo,  CONF_DEF_VALUE, i:0, NULL),
 
 };
 #define CONF_NUM (sizeof(conf_info)/sizeof(conf_info[0]))
diff -r f2cf9e6b707f core/gui.c
--- a/core/gui.c Tue Apr 01 12:30:59 2008 +0300
+++ b/core/gui.c Thu Apr 03 11:17:01 2008 +0300
@@ -133,6 +133,7 @@
 static const char* gui_raw_ext_enum(int change, int arg);
 static const char* gui_raw_nr_enum(int change, int arg);
 static const char* gui_autoiso_shutter_enum(int change, int arg);
+static const char* gui_autoiso_overexpo_enum(int change, int arg);
 static const char* gui_reader_codepage_enum(int change, int arg);
 static const char* gui_zoom_value_enum(int change, int arg);
 static const char* gui_show_values_enum(int change, int arg);
@@ -228,6 +229,7 @@
     {LANG_MENU_AUTOISO_MAX_ISO_HI,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_hi, MENU_MINMAX(20, 160)  },
     {LANG_MENU_AUTOISO_MAX_ISO_AUTO, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_auto, MENU_MINMAX(10, 80)  },
     {LANG_MENU_AUTOISO_MIN_ISO,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_min_iso, MENU_MINMAX(1, 20)  },
+    {LANG_MENU_AUTOISO_REDUCE_OVEREXPO,   MENUITEM_ENUM,    (int*)gui_autoiso_overexpo_enum },
     {LANG_MENU_BACK,                    MENUITEM_UP },
     {0}
 };
@@ -780,6 +782,19 @@
         conf.autoiso_shutter=0;
 
     return shutter[conf.autoiso_shutter];
+}
+
+//-------------------------------------------------------------------
+const char* gui_autoiso_overexpo_enum(int change, int arg) {
+    static const char* expo[]={ "Off", "1/3 EV", "2/3 EV", "1 EV"};
+
+    conf.autoiso_reduce_overexpo+=change;
+    if (conf.autoiso_reduce_overexpo<0)
+        conf.autoiso_reduce_overexpo=(sizeof(expo)/sizeof(expo[0]))-1;
+    else if (conf.autoiso_reduce_overexpo>=(sizeof(expo)/sizeof(expo[0])))
+        conf.autoiso_reduce_overexpo=0;
+
+    return expo[conf.autoiso_reduce_overexpo];
 }
 
 //-------------------------------------------------------------------
diff -r f2cf9e6b707f core/gui_lang.c
--- a/core/gui_lang.c Tue Apr 01 12:30:59 2008 +0300
+++ b/core/gui_lang.c Thu Apr 03 11:17:01 2008 +0300
@@ -408,11 +408,12 @@
 "322 \"Custom Auto ISO->\"\n"
 "323 \"Enable Custom Auto ISO\"\n"
 "324 \"Minimal Shutter speed\"\n"
-"325 \"User Factor (1/FL/factor)\"\n"
-"326 \"IS Factor (Tv*factor)\"\n"
+"325 \" User Factor (1/FL/factor)\"\n"
+"326 \" IS Factor (Tv*factor)\"\n"
 "327 \"Max ISO HI (x10)\"\n"
 "328 \"Max ISO AUTO (x10)\"\n"
 "329 \"Min ISO (x10)\"\n"
+"330 \"Reduce OverExposure\"\n"
 
 
 
diff -r f2cf9e6b707f core/gui_lang.h
--- a/core/gui_lang.h Tue Apr 01 12:30:59 2008 +0300
+++ b/core/gui_lang.h Thu Apr 03 11:17:01 2008 +0300
@@ -423,9 +423,11 @@
 #define LANG_MENU_AUTOISO_MAX_ISO_HI 327
 #define LANG_MENU_AUTOISO_MAX_ISO_AUTO 328
 #define LANG_MENU_AUTOISO_MIN_ISO 329
+#define LANG_MENU_AUTOISO_REDUCE_OVEREXPO 330
+
 //-------------------------------------------------------------------
 
-#define GUI_LANG_ITEMS                  329
+#define GUI_LANG_ITEMS                  330
 
 //-------------------------------------------------------------------
 extern void gui_lang_init();
diff -r f2cf9e6b707f core/gui_osd.c
--- a/core/gui_osd.c Tue Apr 01 12:30:59 2008 +0300
+++ b/core/gui_osd.c Thu Apr 03 11:17:01 2008 +0300
@@ -710,8 +710,10 @@
     if (conf.nd_filter_state || gui_mode==GUI_MODE_OSD)
     gui_print_osd_state_string_chr("NDFILTER:", ((conf.nd_filter_state==1)?"IN":"OUT"));
 #endif   
-    if ((conf.autoiso_enable && shooting_get_iso_mode()<=0 && !(m==MODE_M || m==MODE_TV) && shooting_get_flash_mode()) || gui_mode==GUI_MODE_OSD) 
-     gui_print_osd_state_string_chr("AUTOISO:", "ON");
+    if ((conf.autoiso_enable && shooting_get_iso_mode()<=0 && !(m==MODE_M || m==MODE_TV) && shooting_get_flash_mode()) || gui_mode==GUI_MODE_OSD)  {
+     static const char* shutter[]={ "Auto", "1/8", "1/15", "1/30", "1/60", "1/125", "1/250", "1/500", "1/1000"};
+     gui_print_osd_state_string_chr("I-A: ", shutter[conf.autoiso_shutter]);
+    }
     if ((conf.subj_dist_override_value && conf.subj_dist_override_koef && shooting_can_focus()) || ((gui_mode==GUI_MODE_ALT) && shooting_get_common_focus_mode()) || gui_mode==GUI_MODE_OSD)   {
      gui_print_osd_state_string_int("SD:",shooting_get_subject_distance_override_value());
         if (gui_mode==GUI_MODE_ALT) 
diff -r f2cf9e6b707f include/conf.h
--- a/include/conf.h Tue Apr 01 12:30:59 2008 +0300
+++ b/include/conf.h Thu Apr 03 11:17:01 2008 +0300
@@ -153,6 +153,7 @@
     int autoiso_max_iso_hi;
     int autoiso_max_iso_auto;
     int autoiso_min_iso;
+    int autoiso_reduce_overexpo;
 
     int recalc_exposure;
     int tv_exposure_order;
diff -r f2cf9e6b707f lang/english.lng
--- a/lang/english.lng Tue Apr 01 12:30:59 2008 +0300
+++ b/lang/english.lng Thu Apr 03 11:17:01 2008 +0300
@@ -423,11 +423,12 @@
 322 "Custom Auto ISO->"
 323 "Enable Custom Auto ISO"
 324 "Minimal Shutter speed"
-325 "User Factor (1/FL/factor)"
-326 "IS Factor (Tv*factor)"
+325 " User Factor (1/FL/factor)"
+326 " IS Factor (Tv*factor)"
 327 "Max ISO HI (x10)"
 328 "Max ISO AUTO (x10)"
 329 "Min ISO (x10)"
+330 "Reduce Overexposure"
 
 
 
diff -r f2cf9e6b707f platform/generic/shooting.c
--- a/platform/generic/shooting.c Tue Apr 01 12:30:59 2008 +0300
+++ b/platform/generic/shooting.c Thu Apr 03 11:17:01 2008 +0300
@@ -5,6 +5,7 @@
 #include "math.h"
 #include "stdlib.h"
 #include "conf.h"
+#include "histogram.h"
 
 #define SS_SIZE (sizeof(shutter_speeds_table)/sizeof(shutter_speeds_table[0]))
 #define SSID_MIN (shutter_speeds_table[0].id)
@@ -895,7 +896,10 @@
  float current_shutter = shooting_get_shutter_speed_from_tv96(shooting_get_tv96());
 
  short current_iso=shooting_get_iso_real();
-
+
+ static const float reduce_overexpo[]={1.0, 0.8, 0.63, 0.5}; //0-1 EV reduction
+ if (over_exposed) current_iso *= reduce_overexpo[conf.autoiso_reduce_overexpo];
+
  short min_shutter = shutter[conf.autoiso_shutter];
  if (min_shutter == 0)
  {
@@ -903,7 +907,7 @@
  min_shutter = get_focal_length(lens_get_zoom_point())*conf.autoiso_user_factor / (IS_factor*1000);
      //min_shutter is NOT 1/Xs but optimized for the calculation.
  }
-
+
  short target_iso = current_iso * min_shutter * current_shutter;
  short min_iso = conf.autoiso_min_iso*10;
 
diff -r f2cf9e6b707f version.inc
--- a/version.inc Tue Apr 01 12:30:59 2008 +0300
+++ b/version.inc Thu Apr 03 11:17:01 2008 +0300
@@ -1,1 +1,1 @@
-BUILD_NUMBER := 49
+BUILD_NUMBER := 72


 

Related Topics