Determining value of brightest pixel in most recent image. - Script Writing - CHDK Forum  

Determining value of brightest pixel in most recent image.

  • 16 Replies
  • 5446 Views
*

Offline Atnas

  • *
  • 29
Determining value of brightest pixel in most recent image.
« on: 04 / July / 2009, 18:39:48 »
Advertisements
What I am trying to do is to make a scipt that will take HDR and automatically decide when the dynamic range has been covered. Such as:

Take a picture
Look at the picture and determine if any pixels brightness is above a set threshold.
Take a darker picture
If the darker picture has no pixel above the threshold, the script should start over, trying to cover dark pixels this time.

Just because this would make it ten times easier for noobs as myself to take point and shoot HDR images, not having to think about how big the dynamic range is, thus not deciding how many pictures to take. The user would only have to select the EV step, and the rest would be automatic.

I am also a noob to uBasic, but it seems approachable enough :)
A710 - SD1000(IXUS70)

*

Offline reyalp

  • ******
  • 12102
Re: Determining value of brightest pixel in most recent image.
« Reply #1 on: 04 / July / 2009, 19:12:46 »
check out shot_histogram

Note that it doesn't sample every pixel in the image.
Don't forget what the H stands for.

*

Offline Atnas

  • *
  • 29
Re: Determining value of brightest pixel in most recent image.
« Reply #2 on: 04 / July / 2009, 21:21:52 »
Thanks, just what i was looking for.
Btw, it is called get_histo_range :)

Hopefully I can make a script tomorrow.
A710 - SD1000(IXUS70)

*

Offline Atnas

  • *
  • 29
Re: Determining value of brightest pixel in most recent image.
« Reply #3 on: 05 / July / 2009, 12:07:40 »
EDIT: MY BAD! Ignore this post. I was using an allbest from 2008... fail.

If I put a shot_histo_enable 1 or get_histo_range 512 1024 g in my script, it crashes. Is this because it is not included in my build? What should I do?
« Last Edit: 05 / July / 2009, 14:38:24 by Atnas »
A710 - SD1000(IXUS70)


*

Offline reyalp

  • ******
  • 12102
Re: Determining value of brightest pixel in most recent image.
« Reply #4 on: 05 / July / 2009, 18:30:09 »
Note that max bightness is 1023, not 1024. Black level is at 31. On 12 bit cameras, the values are shifted right 2 bits so they still fall in this range.

and yes, you should be using the latest autobuild ;)
Don't forget what the H stands for.

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Determining value of brightest pixel in most recent image.
« Reply #5 on: 05 / July / 2009, 18:31:43 »
Does it crash in Lua too? I wouldn't be overly surprised if those commands hadn't been properly with ubasic (I didn't know they were even implemented).

*

Offline Atnas

  • *
  • 29
Re: Determining value of brightest pixel in most recent image.
« Reply #6 on: 05 / July / 2009, 19:28:22 »
Wait, are you telling me that the black level is 31 for all cams?
That I for dark frames should do: h=get_histo_range D 31?
Havent seen any info about this other places, so I did some tests with this script.
Code: [Select]
Z=0
:asdf

if 0<>get_histo_range Z Z then print Z , get_histo_range Z Z

Z=Z+1

goto "asdf"
This printed the following:
29 3
30 10
31 38
32 34
33 12
Which makes me think that the black level is 29 (with get_histo_range ofc) for SD1000 (IXUS 70)
Does this differ from cam to cam since you said 31?

fudgey:
It doesn't crash after I updated my outdated build, so I don't know about lua, but it works in uBasic atm  :D
A710 - SD1000(IXUS70)

*

Offline reyalp

  • ******
  • 12102
Re: Determining value of brightest pixel in most recent image.
« Reply #7 on: 05 / July / 2009, 20:09:50 »
I was going by what's in camera.h, but I'm not sure how that was determined.
Don't forget what the H stands for.


*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Determining value of brightest pixel in most recent image.
« Reply #8 on: 06 / July / 2009, 15:25:32 »
Havent seen any info about this other places, so I did some tests with this script.

This histogram thing originated here: http://chdk.setepontos.com/index.php/topic,1145.0.html

*

Offline Atnas

  • *
  • 29
Re: Determining value of brightest pixel in most recent image.
« Reply #9 on: 07 / July / 2009, 18:02:35 »
Thanks, looked through the thread, but I didn't find any mentioning of black levels.
Anyhow, I have written a script that works. It does not 100% guarantee that no pixels peak, because the get_histo_range works in some way I can't quite grasp, but I've found some values that work well, as long as it is not a small bright spot. It will probably take pictures of a wider range than actually needed, but rather more than not enough. (And you can just change the values if you disagree with my defaults)

If somebody could test this on a DIGIC II cam, and confirm that it works, it should.

Code: [Select]
@title AutoHDR 1.0

rem The step between images
@param i EV Step
@default i 1
@param j EV Step (x/3)
@default j 0

rem The wait before the first picture is taken
@param t Initial Delay (s)
@default t 1

rem Feel free to expiriment with the threshold values, I have just found these to work OK
rem Lower highlight threshold = More dark pictures (more highlighs probably covered)
rem Higher highlight threshold = Less dark pictures (more highlighs probably peaking)
@param b Highlight threshold (29-1023)
@default b 150

rem Lower dark threshold = Less bright pictures (more darks probably peaking)
rem Higher dark threshold = More bright pictures (more darks probably covered)
@param d Dark threshold (29-1023)
@default d 100

rem Prints the script to a file, so you can see what exposures you have afterwards.
print_screen 1

rem Making sure the variables are within range
if i<0 then i=0
if j<0 then j=0
if j=0 then if j=i then i=1
if e<1 then e=1
if p<1 then p=10
if b<29 then b=29
if b>1023 then b=0
if d<29 then d=29
if d>1023 then d=1023

rem Enables the histogram
shot_histo_enable 1

rem Calculates the step between frames as decided by the user
i=j*32+i*96

rem Disable flash
f=get_flash_mode
F=2
gosub "set_flash_mode"

rem Get the shutter speed
rem Print 0 EV because e=0 (see subroutine for details)
gosub "EVprint"
rem Delay before first shot
sleep t*1000
rem Take the EV=0 shot
shoot
rem Get the shutter speed just used
get_tv96 g
rem Lock the AF so it doesnt have to focus later
set_aflock 1

H=g
:highs
rem Decrease exposure time by step (i)
H=H+i
set_tv96_direct H
rem Display exposure (difference from origrinal exposure)
e=g-H
gosub "EVprint"
rem Takes the picture
shoot
rem Check the threshold on the histogram
h=get_histo_range b 1023
rem If too many pixels are too bright, it goes to "highs" (take a darker picture)
if h<>0 then goto "highs"

print "Darks"

D=g
:darks
rem Increase exposure time by step (i)
D=D-i
set_tv96_direct D
rem Display exposure (difference from origrinal exposure)
e=g-D
gosub "EVprint"
rem Takes the picture
shoot
rem Check the threshold on the histogram
h=get_histo_range 0 d
rem If too many pixels are too dark, it goes to "darks" (take a brighter picture)
if h<>0 then goto "darks"

rem Unlock AF, since we are done taking photos
set_aflock 0

rem Set flash back to initial state
F=f
gosub "set_flash_mode"

rem Print interesting information to screen
e=H-D
print "Total pics:"
print e/i+1
print "Total exposure range:"
gosub "EVprint"

end

rem The only way I could figure out to do it, because I wanted it to be DIGIC II/III universal
rem set_flash_mode could be really usefull as a function :)
:set_flash_mode
w=0
rem Reads the current flash mode to j
j=get_flash_mode
rem Checks if this is the same as prop 16 (DIGIC II), if it is, then it sets J<>j and J>-1
if j=get_prop 16 then if j-1<0 then J=1 else J=j-1
if j=get_prop 16 then w=1
rem If j=prop 16 then it changes prop 16 to a new value (J)
if j=get_prop 16 then set_prop 16 J
rem If the flash mode has changed it is prop 16 (DIGIC II), else it sets prop 16 back (dont wanna mess with unknown props)
if J=get_flash_mode then J=16 else if w=1 then set_prop 16 j
rem Sets the flash mode to F on both DIGIC II and III
if J=16 then set_prop 16 F else set_prop 143 F
return

rem Made this subroutine to print the EV number in a readable format
rem This can probably be done simpler... just like the rest of my script..
:EVprint
w=0
e=e/32
rem if e is negative, it makes it positive and sets w=1
if e<0 then w=1
if e<0 then e=e*-1

E=e/3
E=E*3
e=e-E
E=E/3
if w=1 then E=E*-1

if e=0 then print E,"EV"
if e=1 then print E,"1/3 EV"
if e=2 then print E,"2/3 EV"
return
« Last Edit: 07 / July / 2009, 18:10:02 by Atnas »
A710 - SD1000(IXUS70)

 

Related Topics