1.3 development proposal - exposure conversion functions - page 5 - General Discussion and Assistance - CHDK Forum

1.3 development proposal - exposure conversion functions

  • 58 Replies
  • 25189 Views
*

Offline reyalp

  • ******
  • 14082
Re: 1.3 development proposal - exposure conversion functions
« Reply #40 on: 13 / September / 2013, 17:04:39 »
Advertisements
The purpose of the function is to convert tv96 into something photographers can understand.
I disagree, the purpose is to convert tv96 values into microseconds. The valid values are limited to the same range of values the camera can actually use, since it ultimately uses an integer number of microseconds. This seems very clear and well defined to me. It's not a generic power function, it converts between the two time systems the camera actually uses.

The fact that you want to pass a negative value to get the inverse so you can display it as a fraction is a problem you have created for yourself.
Quote
As far as casting float to int, I can't believe you'd actually argue to keep that sloppy code in CHDK. You still haven't given me a reason to use float instead of double. I can give you several reasons to use double.
I don't care if it's a float or a double, but when the reason is that you need to distinguish between 1/3201 and 1/3205 it tells me that I probably don't need to spend any more time thinking about it.

If you want to log values for analysis, you should probably stick to native values like APEX96 or microseconds. (It should be noted that within the range it operates, Canon apex2us likely does not always give exactly the same results as our version). If you are going to do calculations on the exposure, you should do them all in one system (almost certainly APEX96), and only convert the final inputs or outputs if needed. This will give far better precision than any amount of tweaking the conversion functions.

If you want pretty values for display, prettify them however suits your fancy and accept that the pretty values will have less precision than the native values. Canon's pretty values are off by as much as a 1 second from the actual value...
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: 1.3 development proposal - exposure conversion functions
« Reply #41 on: 27 / September / 2013, 23:02:46 »
These are the changes I added to my CHDK custom build that correct the problems with the shutter time conversions. It doesn't look like anyone else wants this in the trunk, so I won't bother with a patch file. Unfortunately, I can't write an acceptable shutter time display function with the usec function as is.

The only change for scripts is a new, optional scale factor, which defaults to usec:

tv96_to_usec(tv96[,scale])

Code: [Select]
//in shooting.h
extern short shooting_get_tv96_from_shutter_speed(double t); //changed to double
extern double shooting_get_shutter_speed_from_tv96(short tv96); //changed to double

//in shooting.c
short shooting_get_tv96_from_shutter_speed(double t) //changed to double
{
    if (t > 0)
    {
        t = ((96.0 * -log(t)) * inv_log_2);
        if (t < 0)
            return (short)(t - 0.5);
        return (short)(t + 0.5);
    }
    return -10000;
}

double shooting_get_shutter_speed_from_tv96(short tv96) //changed to double
{
    return pow(2,((double)(-tv96))/96.0);
}

//in luascript.c
static int luaCB_usec_to_tv96( lua_State* L )
{
  lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((double)luaL_checknumber(L, 1)/1000000.0));
  return 1;
}

static int luaCB_tv96_to_usec( lua_State* L )
{
  lua_pushnumber(L, (int)(shooting_get_shutter_speed_from_tv96(luaL_checknumber(L, 1)) *
    (double)luaL_optnumber(L, 2, 1000000) + 0.5));
  return 1;
}
The lua function to convert tv96 to a time string becomes much simpler. Also, using a scale factor returns rounded values based on that scale. Rounding to the nearest usec, as the current function does, isn't  useful.

Here's the lua time string function that works with these changes:
Code: [Select]
function seconds(tv) -- tv96 to time string i.e. print(seconds(tv))
  local pre=""
  if(tv>=96)then
    tv=-tv
    pre="1/"
  end
  tv=tv96_to_usec(tv,1000)
  local ti=tv/1000 -- integer part
  local ts=string.format("%s%u.%03u",pre,ti,tv%1000) -- xx.xxx or 1/xx.xxx
  if(ti>1)then -- truncate digits to reflect decimal precision
    if(ti>149)then ti=-5
    elseif(ti>14)then ti=-3
    else ti=-2 end
    ts=string.sub(ts,1,ti)
  end
  return ts
end
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: 1.3 development proposal - exposure conversion functions
« Reply #42 on: 28 / September / 2013, 03:55:26 »
These are the changes I added to my CHDK custom build that correct the problems with the shutter time conversions. It doesn't look like anyone else wants this in the trunk, so I won't bother with a patch file. Unfortunately, I can't write an acceptable shutter time display function with the usec function as is.

The only change for scripts is a new, optional scale factor, which defaults to usec:

tv96_to_usec(tv96[,scale])

Code: [Select]
//in shooting.h
extern short shooting_get_tv96_from_shutter_speed(double t); //changed to double
extern double shooting_get_shutter_speed_from_tv96(short tv96); //changed to double

//in shooting.c
short shooting_get_tv96_from_shutter_speed(double t) //changed to double
{
    if (t > 0)
    {
        t = ((96.0 * -log(t)) * inv_log_2);
        if (t < 0)
            return (short)(t - 0.5);
        return (short)(t + 0.5);
    }
    return -10000;
}

double shooting_get_shutter_speed_from_tv96(short tv96) //changed to double
{
    return pow(2,((double)(-tv96))/96.0);
}

//in luascript.c
static int luaCB_usec_to_tv96( lua_State* L )
{
  lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((double)luaL_checknumber(L, 1)/1000000.0));
  return 1;
}

static int luaCB_tv96_to_usec( lua_State* L )
{
  lua_pushnumber(L, (int)(shooting_get_shutter_speed_from_tv96(luaL_checknumber(L, 1)) *
    (double)luaL_optnumber(L, 2, 1000000) + 0.5));
  return 1;
}
The lua function to convert tv96 to a time string becomes much simpler. Also, using a scale factor returns rounded values based on that scale. Rounding to the nearest usec, as the current function does, isn't  useful.

Here's the lua time string function that works with these changes:
Code: [Select]
function seconds(tv) -- tv96 to time string i.e. print(seconds(tv))
  local pre=""
  if(tv>=96)then
    tv=-tv
    pre="1/"
  end
  tv=tv96_to_usec(tv,1000)
  local ti=tv/1000 -- integer part
  local ts=string.format("%s%u.%03u",pre,ti,tv%1000) -- xx.xxx or 1/xx.xxx
  if(ti>1)then -- truncate digits to reflect decimal precision
    if(ti>149)then ti=-5
    elseif(ti>14)then ti=-3
    else ti=-2 end
    ts=string.sub(ts,1,ti)
  end
  return ts
end

So what you really need is a function to generate a human readable string from the Tv96 shutter speed value?

Since this would also be useful for ubasic it should probably be in the core C code.

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: 1.3 development proposal - exposure conversion functions
« Reply #43 on: 28 / September / 2013, 10:28:36 »
So what you really need is a function to generate a human readable string from the Tv96 shutter speed value?
Can't find the links right now,  but I believe we've discussed this in a more general way a couple of times.   

To make my script UI's "pretty",  I'm still not using the new APEX96 functions to create output strings.  Nothing wrong with the functions but what I want is shutter speeds in the same increments that Canon provides so that they match the exif values. So for example, any tv96 value between 560 & 592 is displayed as 1/60 sec.

Code: [Select]
tv_ref = {    -- note : tv_ref values set 1/2 way between shutter speed values
-608, -560, -528, -496, -464, -432, -400, -368, -336, -304,
-272, -240, -208, -176, -144, -112,  -80,  -48,  -16,   16,
  48,   80,  112,  144,  176,  208,  240,  272,  304,  336,
 368,  400,  432,  464,  496,  528,  560,  592,  624,  656,
 688,  720,  752,  784,  816,  848,  880,  912,  944,  976,
1008, 1040, 1072, 1096, 1129, 1169, 1192, 1225, 1265, 1376  }

function print_tv(val)
    if ( val == nil ) then return("-") end
    local i = 1
    local tv_str = {
       ">64",
        "64",    "50",    "40",   "32",   "25",   "20",   "16",   "12",    "10",   "8.0",
       "6.0",   "5.0",   "4.0",  "3.2",  "2.5",  "2.0",  "1.6",  "1.3",   "1.0",   "0.8",
       "0.6",   "0.5",   "0.4",  "0.3",  "1/4",  "1/5",  "1/6",  "1/8",  "1/10",  "1/13",
      "1/15",  "1/20",  "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125",
     "1/160", "1/200", "1/250","1/320","1/400","1/500","1/640","1/800","1/1000","1/1250",
    "1/1600","1/2000","1/2500","1/3200","1/4000","1/5000","1/6400","1/8000","1/10000","hi"  }
    while (i <= #tv_ref) and (val > tv_ref[i]) do i=i+1 end
    return tv_str[i]
end
I think the original code here is something I got from msl.

I've also mused in the past about maybe having script access to the aperture_sizes_table[] in shooting.c so that scripts can generically "know" what f-stops are available on the camera (assuming the table is not just c&p'd from another camera and that it somehow still works at different zoom positions).
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline lapser

  • *****
  • 1093
Re: 1.3 development proposal - exposure conversion functions
« Reply #44 on: 28 / September / 2013, 15:05:02 »
So what you really need is a function to generate a human readable string from the Tv96 shutter speed value?

Since this would also be useful for ubasic it should probably be in the core C code.
YES!!!! Great idea, Phil. Now I'm excited again.

Here's how I would implement it:

sv96_to_string(sv96,precision)
av96_to_string(av96,precision)
tv96_to_string(tv96,precision)

precision is the number of digits after the decimal point. If 0, it would skip the decimal point.

By specifying the precision, the functions would round to the nearest digit. I.E.
av96_to_string(av96,1) would produce:   f 2.6 instead of f 2.612

The precision variable is important to me for sv96 too, for low ISO values. Each sv96 value should be able to produce a unique ISO result. It's not any more trouble to implement, and it might be useful in other ways we don't know about.

tv96_to_string(tv96,3) would produce "xx.xxx" for tv96<192 (>0.25 second), and "1/xx.xxx" for tv96>=192.

It might be useful to be able to force "xx.xxx" format. The easiest way to implement that would be to define precision<0 as "xx.xxx" only.

I'll see if I can get it working and post a patch and test script. The goal is to be able to use the functions directly in a "print" statement.

To make my script UI's "pretty",  I'm still not using the new APEX96 functions to create output strings.  Nothing wrong with the functions but what I want is shutter speeds in the same increments that Canon provides so that they match the exif values. So for example, any tv96 value between 560 & 592 is displayed as 1/60 sec.
Yes, I think we're on the same page here. That should work for 1/4 second or less with:
tv96_to_string(tv96,0)

But for >1/4, you'd want to use at least:
tv96_to_string(tv96,1)

This could be done easily in a script:

precision=0
if(tv96<192)then precision=1
print(tv96_to_string(tv96,precision))
=======
As for matching the EXIF values, that would require a table lookup, like the one in your script. It's probably better to keep doing that in the script, since it doesn't require floating point calculations. You might want to experiment with using the camera specific shutter and aperture tables in a separate function, kind of like set_tv96() and set_tv96_direct().
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Apex96 to string functions
« Reply #45 on: 08 / October / 2013, 22:55:48 »
I've finished writing 3 new CHDK functions for Lua to convert and display tv96, av96, and sv96 to human readable strings. Please take a look at them and let me know if you want to add them to the trunk as is. If so, I'll add them for uBasic and post a patch. Here's a description of the functions, a test Lua script that uses them, and the log produced by the script (attached):

tv96_to_string(tv96 [,ndig] [,scale])
  ndig: 0..9  precision (digits after decimal point) 1/x format starts at 1/4 second
          10..19 no 1/x format  precision is last digit (%10)
          -1: (default) automatic ndig   Change of 1 tv96 unit always gives unique result (see log)
          -2: automatic ndig   No 1/x format
  scale: (default 1) Result multiplier. I.E. 1000 for msec

av96_to_string(av96 [,ndig] [,scale])
  ndig: 0..9  precision (digits after decimal point)
          -1: (default) automatic ndig   Change of 1 av96 unit always gives unique result
  scale: (default 1) Result multiplier

sv96_to_string(sv96 [,ndig] [,scale])
  ndig: 0..9  precision (digits after decimal point)   MARKET ISO result
          10..19 REAL ISO result    precision is last digit (%10)
          -1: (default) automatic ndig   MARKET ISO
          -2: automatic ndig   REAL ISO
  scale: (default 1) Result multiplier

Code: [Select]
--[[
@title ApexStr 1
@param d Dummy
@default d 1
--]]
print_screen(1)
print("Apex to String Test")
set_console_autoredraw(-1)
print()
av=aperture_to_av96(1000)
avlast=aperture_to_av96(40000)
print("av96 from",av,"to",avlast)
av=0
avlast=1000 -- aperture_to_av96 overflows
print("av96 | aperture_to_av96 | to_aperture | to_string 3 | to_string -1")
repeat
  f0=av96_to_aperture(av)
  print(string.format("%d | %d | %d | %s | %s",av,aperture_to_av96(f0),f0,av96_to_string(av,3),av96_to_string(av,-1)))
  av=av+1
until av>avlast

print()
sv=iso_to_sv96(25);
svlast=iso_to_sv96(6400);
print("sv96 from",sv,"to",svlast)
print("sv96 | to_iso | to_string 10 | to_string -2 | to_string -1")
repeat
  print(string.format("%d | %s | %s | %s | %s",sv,sv96_to_iso(sv),sv96_to_string(sv,10),sv96_to_string(sv,-2),sv96_to_string(sv)))
  sv=sv+1
until sv>svlast

print()
tv=seconds_to_tv96(256,1)
tvlast=seconds_to_tv96(1,8192)
print("tv96 from",tv,"to",tvlast)
print("tv96 | to_usec | to_string 10,1000000 | to_string -2,1000 | to_string -1")
repeat
  print(string.format("%d | %s | %s | %s | %s",tv,tv96_to_usec(tv),tv96_to_string(tv,10,1000000),tv96_to_string(tv,-2,1000),tv96_to_string(tv)))
  tv=tv+1
until tv>tvlast
set_console_autoredraw(1)

« Last Edit: 08 / October / 2013, 23:11:31 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Apex96 to string functions
« Reply #46 on: 08 / October / 2013, 23:13:42 »
I've finished writing 3 new CHDK functions for Lua to convert and display tv96, av96, and sv96 to human readable strings.
While technically correct,  these functions don't do anything useful for me.   

As per my previous post,  what I'm looking for is functions that convert APEX96 values to stings that look like the rounded values that Canon will use in their EXIF data.   These functions are for display only but would make it much easier to produce UI's that show Tv, Av, & Sv values users understand.

For example,  I would like Tv96 values between 560 &  592 to simply display as 1/60,  not 1/57.0 to 1/71.8.

Sorry - just MHO.
Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline lapser

  • *****
  • 1093
Re: Apex96 to string functions
« Reply #47 on: 08 / October / 2013, 23:52:28 »
As per my previous post,  what I'm looking for is functions that convert APEX96 values to stings that look like the rounded values that Canon will use in their EXIF data.   These functions are for display only but would make it much easier to produce UI's that show Tv, Av, & Sv values users understand.

For example,  I would like Tv96 values between 560 &  592 to simply display as 1/60,  not 1/57.0 to 1/71.8.
Don't you have a Lua script function that does that? It involves a table look up, and only integer math, so a CHDK function isn't really necessary.

We could put the table into CHDK and do the look up in C code instead of script, I suppose. Are we sure the table is camera independent? Each camera must have its own table in firmware somewhere, wouldn't it? Has anyone ever found that table in the firmware? Does the EXIF data end up showing values that the camera can't input using its own settings? How well does your script version match the EXIF data?

I think there are too many questions to be able to add that feature to my new functions at the moment. It could be easily added as a new option in the future, if we can figure out the correct table values.

But the question for now is, do you want to add these functions, as is, to the trunk? They're really useful to me to watch the exposure gradually change during a time lapse, in understandable units instead of apex96 numbers. The automatic precision works really well too. I couldn't do that properly in Lua. As Phil said, it would be useful to have this capability in uBasic too.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Apex96 to string functions
« Reply #48 on: 09 / October / 2013, 00:03:00 »
As per my previous post,  what I'm looking for is functions that convert APEX96 values to stings that look like the rounded values that Canon will use in their EXIF data.   These functions are for display only but would make it much easier to produce UI's that show Tv, Av, & Sv values users understand.

For example,  I would like Tv96 values between 560 &  592 to simply display as 1/60,  not 1/57.0 to 1/71.8.
Don't you have a Lua script function that does that? It involves a table look up, and only integer math, so a CHDK function isn't really necessary.

We could put the table into CHDK and do the look up in C code instead of script, I suppose. Are we sure the table is camera independent? Each camera must have its own table in firmware somewhere, wouldn't it? Has anyone ever found that table in the firmware? Does the EXIF data end up showing values that the camera can't input using its own settings? How well does your script version match the EXIF data?

I think there are too many questions to be able to add that feature to my new functions at the moment. It could be easily added as a new option in the future, if we can figure out the correct table values.

But the question for now is, do you want to add these functions, as is, to the trunk? They're really useful to me to watch the exposure gradually change during a time lapse, in understandable units instead of apex96 numbers. The automatic precision works really well too. I couldn't do that properly in Lua. As Phil said, it would be useful to have this capability in uBasic too.

Hard to review without the source code?

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: Apex96 to string functions
« Reply #49 on: 09 / October / 2013, 00:07:08 »
Don't you have a Lua script function that does that? It involves a table look up, and only integer math, so a CHDK function isn't really necessary.
True.  But the script has no idea of the valid shutter speed and aperture discrete values & range of the camera.

Quote
We could put the table into CHDK and do the look up in C code instead of script, I suppose. Are we sure the table is camera independent? Each camera must have its own table in firmware somewhere, wouldn't it?
I believe you will find that in the shooting.c file in the each camera's platform/camera directory.  Although its probably not safe to assume those are all correct and not just C&P from other posts,  it would be a good reason to clean them up on a camera by camera basis.

Quote
I think there are too many questions to be able to add that feature to my new functions at the moment. It could be easily added as a new option in the future, if we can figure out the correct table values.
I wasn't proposing adding it to your new functions.

Quote
But the question for now is, do you want to add these functions, as is, to the trunk? They're really useful to me to watch the exposure gradually change during a time lapse, in understandable units instead of apex96 numbers.
I think I may understand your fascination with three decimal accuracy for Tv, Av, & Sv values,  but I'm pretty sure most people don't really care that much.  And I'm almost certain you won't tell the difference in the images you shoot.
« Last Edit: 09 / October / 2013, 00:15:19 by waterwingz »
Ported :   A1200    SD940   G10    Powershot N    G16

 

Related Topics