Fandom

CHDK Wiki

Lua/Raw Hook Operations

< Lua

598pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

IntroductionEdit

CHDK 1.4 adds the ability to read and manipulate the raw image data inside the raw script hook, before the CHDK raw and camera jpeg are saved. This can be used to calculate subsequent exposure or modify the image. A flexible alternative to the shot_histogram function is included.

Development thread http://chdk.setepontos.com/index.php?topic=11081.msg119265#msg119265

General usageEdit

The core functions are provided in a library called rawop, which is available by default. Some auxiliary functions are provide in the lua module rawoplib.

To use rawop, you must

  • Ensure the camera is in a shooting mode with raw data available (get_raw_support() == true)
  • Set the raw hook, with a timeout sufficient for all the operations you want to perform
  • Start a shot using scripted key presses (not using the shoot() function)
  • Wait for the raw hook to become ready
  • Analyze and/or modify the raw data using the rawop functions
  • Call hook_raw.continue() to allow the shooting process to continue

Functions which access raw data are only valid inside the raw hook. If called when the raw hook is not active, they throw an error. These functions will also throw an error if valid raw data is known to be unavailable in the current shooting mode.

Functions for querying raw buffer characteristicsEdit

These functions may be called at any time, but some depend on values that can change between shots (currently on G1X only) so in general, it is recommended that they be called inside the hook. In future versions, more values may change at runtime.

rawop.get_cfaEdit

cfa=rawop.get_cfa()

cfa: CFA pattern as a 32 bit interger, as used in DNG

rawop.get_cfa_offsetsEdit

cfa_offsets=rawop.get_cfa_offsets()

cfa_offsets: offsets of color filter elements with respect to an even valued x,y pair, in the form

{
 r={ y=1, x=0, },
 g1={ y=0, x=0, },
 b={ y=0, x=1, },
 g2={ y=1, x=1, },
}

rawop.get_bits_per_pixelEdit

bpp=rawop.get_bits_per_pixel()

bpp: sensor bit depth. 10, 12, or 14 in currently supported cameras

rawop.get_raw_neutralEdit

neutral=rawop.get_raw_neutral()

neutral: approximate raw value of a neutral grey target exposed with Canon AE. This is designed such that raw values can be expressed as an Ev offset from "correct" exposure, so raw_to_ev(neutral) = 0

This is not aware of CFA, it is based on an average of all color elements

NOTE on G1x, the value may change depending on ISO settings. The value is only updated when the raw hook is entered for the shot so for maximum portability, this function should only be called inside the raw hook.

rawop.get_black_levelEdit

blacklevel=rawop.get_black_level()

blacklevel: sensor black level value. This is theoretically the value of a pixels which has received no detectable light. However un-exposed pixels may have higher values due to sensor effects (hot pixels, dark current etc) and can also have lower values in some cases.

NOTE on G1x, the value may change depending on ISO settings. The value is only updated when the raw hook is entered for the shot so for maximum portability, this function should only be called inside the raw hook.

rawop.get_white_levelEdit

whitelevel=rawop.get_white_level()

whitelevel: sensor white level value (currently 2^bpp - 1 for all known sensors), the maximum value a pixel can have.

Functions for querying raw dimensionsEdit

The values returned by these functions do not currently change at runtime, but it is possible they could change with shooting mode in future versions.

Active area generally includes all of the sensor area known to contain image data. This often includes dark borders of pixels which contain recognizable image data that is not exposed the same as the majority of the sensor. JPEG area may be a better choice for whole scene measurements.

Active area coordinates in CHDK are guaranteed to be even. If the sensor active area physically occupies odd values, they will be excluded.

JPEG area represents the approximate area of the sensor used for the JPEG, but may not exactly match either the pixel dimensions or sensor area.

JPEG area generally will not include the dark borders that can affect active area, so jpeg area is a good choice for measuring the whole scene.

These JPEG area functions return sensor coordinates, unlike the DNG specification which gives default crop in terms of active area.

Both active area and JPEG area are defined in the port, and are not affected by the "Crop size" DNG menu option.

rawop.get_raw_widthEdit

width=rawop.get_raw_width()

width: The width of the sensor in pixels.

rawop.get_raw_heightEdit

height=rawop.get_raw_height()

height: The height of the sensor in pixels.

rawop.get_active_leftEdit

left=rawop.get_active_left()

left: X coordinate of the leftmost pixel in the active area

rawop.get_active_topEdit

top=rawop.get_active_top()

top: y coordinate of the topmost pixel in the active area

rawop.get_active_widthEdit

width=rawop.get_active_width()

width: width of the active area, in pixels

rawop.get_active_heightEdit

height=rawop.get_active_height()

height: height of the active area, in pixels

rawop.get_jpeg_leftEdit

left=rawop.get_jpeg_left()

left: X coordinate of the leftmost pixel in the jpeg area

rawop.get_jpeg_topEdit

top=rawop.get_jpeg_top()

top: y coordinate of the topmost pixel in the jpeg area

rawop.get_jpeg_widthEdit

width=rawop.get_jpeg_width()

width: width of the jpeg area, in pixels

rawop.get_jpeg_heightEdit

height=rawop.get_jpeg_height()

height: height of the jpeg area, in pixels

Functions for querying and modifying raw dataEdit

An error is generated if the these functions are called outside the raw hook, or in a shooting mode for which raw data is not available.

Functions with rgbg in the name operate on "quads" of pixels. Coordinates are truncated to even values, so the function will operate on the quad containing the specified coordinates. When rgbg values are specified, the second G will default to the value of the first if not given.

rawop.get_pixelEdit

v=rawop.get_pixel(x,y)

v: raw value, or nil if out of bounds

rawop.set_pixelEdit

rawop.set_pixel(x,y,v)

Sets pixel at x,y to value v. If x or y fall outside the sensor area, the call is ignored. If the v is larger than allowed by the camera bit depth, the behavior is unspecified.

rawop.get_pixels_rgbgEdit

r,g1,b,g2=rawop.get_pixels_rgbg(x,y)

r,g1,b,g2: Red, green, blue and green values of the quad containing x,y, or nil if out of bounds.

rawop.set_pixels_rgbgEdit

rawop.set_pixels_rgbg(x,y,r,g1,b[,g2])

Sets the values of the CFA quad containing x,y. If g2 is not specified, it is set to g1. If x or y fall outside the sensor area, the call is ignored. If the color valuers are larger than allowed by the camera bit depth, the behavior is unspecified.

rawop.fill_rectEdit

rawop.fill_rect(x,y,width,height,val[,xstep[,ystep]])

Sets every step-th pixel of the specified rectangle to the specified value. Width and height out of bounds are clipped.

xstep defaults to 1, ystep defaults to xstep

Step 2 can be used with CFA offsets to fill RGB (see rawoplib fill_rect_rgbg)

This function can take a substantial amount of time when large areas are set (TODO example)

rawop.meterEdit

mean_raw_val=rawop.meter(x,y,x_count,y_count,x_step,y_step)

mean_raw_val: average values of count pixels in x and y, sampled at step size step, or nil if the range is invalid or the total number of pixels could result in overflow

To prevent overflow, the total number of pixels must less unsigned_max / white_level. Limits are roughly

10 bpp = 4 Mpix
12 bpp = 1 Mpix
14 bpp = 256 Kpix

To meter larger numbers of pixels, use multiple calls and average the results

To meter R G B separately, use multiple meter calls with the appropriate CFA offset and even steps (see rawoplib meter_rgb and meter_rgbg)

To ensure all CFA colors are sampled in a single call, use odd step values.

This function can take a substantial amount of time when large counts are used (TODO example)

Functions for converting raw values for exposure calculationEdit

rawop.raw_to_evEdit

ev=rawop.raw_to_ev(rawval[,scale])

ev: APEX-like "Ev" of the raw value, such that raw_to_ev(raw_neutral) == 0, and N*scale is N "stops" above or below neutral.

If rawval is <= to blacklevel, it is clamped to blacklevel + 1.

rawval > whitelevel is converted without any special treatment.

scale is optionally scales the APEX value. The default is 96, which results in values that can be used directly in calculations with the cameras normal APEX*96 exposure values. Use 1000 for imath APEX values or 96000 for APEX96 with imath.

NOTE on G1x, the result may change depending on ISO settings. The value is only updated when the raw hook is entered for the shot so for maximum portability, this function should only be called inside the raw hook.

rawop.ev_to_rawEdit

rawval=rawop.ev_to_raw(ev[,scale])

Convert an APEX-like "Ev" value as described above into a raw value. No range checking is done.

scale optionally specifies a scale factor to divide the Ev value by before conversion. The default is 96 to be compatible with camera exposure parameters and raw_to_ev defaults.

NOTE on G1x, the result may change depending on ISO settings. The value is only updated when the raw hook is entered for the shot so for maximum portability, this function should only be called inside the raw hook.

Histogram functionsEdit

rawop provides flexible raw histogram functions through histogram objects. Multiple histograms can be created, and used to sample specified regions of the raw buffer.

Except for rawop.create_histogram, all histogram functions are provided by the object. These are referred to with the notation histo:'function_name' below, but the actual name will be the variable you assigned the histogram object to.

Histograms data is built by calling histo:update(). Querying a histogram with no data generates an error.

rawop.create_histogramEdit

histo=rawop.create_historam()

histo: A new histogram object.

histo:updateEdit

histo:update(top,left,width,height,xstep,ystep[,bits])

Update histogram data using specified area of raw buffer.

Bits specifies the bit depth of histogram. Defaults to camera bit depth, and must be <= camera bit depth. The amount of memory required for the histogram data is determined by bits.

An error is generated if the called outside the raw hook, or in a shooting mode for which raw data is not available.

To generate color specific histograms, use CFA offsets and even steps. To generate a histogram including all CFA channels, use odd steps.

This function may take a substantial amount of time when used on large numbers of pixels (TODO example)

Memory is allocated for the histogram data on the first update call, and re-allocated if bit depth changes. It is freed either by normal Lua garbage collection or an explicit call to histo:free()

histo:rangeEdit

frac=histo:range(min,max[,'count'|scale])

frac: number of values in range, either as a fraction in parts per scale, or total count.

min, max: range of values to query, in raw values scaled to the bit depth specified in histo:update(). An error is generated if min > max or either falls outside the range of valid values for the histogram bit depth.

scale: defaults to 100, use the string 'count' for raw counts.

When large number of pixels are involved, calculations involving raw counts or very large scales can may result in overflow.

An error is generated if the histogram does not contain data.

This function may take a non-trivial amount of time to execute.

histo:total_pixelsEdit

total=histo:total_pixels()

total: The total number of pixels sampled by the histogram.

An error is generated if the histogram does not contain data.

histo:bitsEdit

bits=histo:bits()

bits: The bit depth specified in the last call to histo:update().

An error is generated if the histogram does not contain data.

histo:freeEdit

histo:free()

Immediately free memory used by histogram data. histo:update must be called again to before any other functions. If histo:free() is not called, memory associated with the histogram will be freed along with the histogram object following normal Lua garbage collection rules.

rawoplib Lua moduleEdit

The rawoplib module adds some additional convenence functions to rawop. To use it, just add

require'rawoplib'

to your script. The functions are added to the existing rawop table.

rawop.fill_rect_rgbgEdit

rawop.fill_rect_rgbg(x,y,width,height,r,g1,b[,g2])

Fill the specified rectangle with the given color values.

rawop.rect_rgbgEdit

rawop.rect_rgbg(x,y,width,height,linewidth,r,g1,b[,g2])

Draw an hollow rectangle with the given colors and line width.

rawop.rectEdit

rawop.rect(x,y,width,height,linewidth,v,xstep,ystep)

Draw a hollow rectangle with a single color value

rawop.meter_rgbgEdit

r,g1,b,g2=rawop.meter_rgbg(x,y,xcount,ycount,xstep,ystep)

Return the average value of pixels the each color channel in the specified area. Uses one rawop.meter call for each channel, using cfa offsets and the provided count and step values.

xstep and ystep must be even. count and step values are subject to the same limits as rawop.meter()

rawop.meter_rgbEdit

r,g1,b=rawop.meter_rgbg(x,y,xcount,ycount,xstep,ystep)

Like rawop.meter_rgbg, but only measures the "first" green channel.

Performance notesEdit

TODO

ExamplesEdit

See CHDK/SCRIPTS/TEST/DRTEST.LUA and CHDK/SCRIPTS/TEST/RAWDRAW.LUA for some examples.

TODO some simple code samples

Known issuesEdit

TODO

Also on Fandom

Random Wiki