Skip to content

Commit

Permalink
Added manual exposure settings
Browse files Browse the repository at this point in the history
Co-authored-by: Benn Snyder <benn.snyder@gmail.com>
Signed-off-by: Benn Snyder <benn.snyder@gmail.com>
Reviewed-by: Benn Snyder <benn.snyder@gmail.com>
  • Loading branch information
dudeofea and piedar committed Apr 3, 2023
1 parent 478b68b commit 0f8d11e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 2 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ include (FindOS)
include (SetupDirectories)

set (PROJECT_VER_MAJOR 0)
set (PROJECT_VER_MINOR 6)
set (PROJECT_VER_PATCH 5)
set (PROJECT_VER_MINOR 7)
set (PROJECT_VER_PATCH 0)
set (PROJECT_VER
"${PROJECT_VER_MAJOR}.${PROJECT_VER_MINOR}.${PROJECT_VER_PATCH}")
set (PROJECT_APIVER
Expand Down
2 changes: 2 additions & 0 deletions examples/glview.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ void keyPressed(unsigned char key, int x, int y)
if (key == 'e') {
static freenect_flag_value auto_exposure = FREENECT_ON;
freenect_set_flag(f_dev, FREENECT_AUTO_EXPOSURE, auto_exposure);
freenect_set_flag(f_dev, FREENECT_AUTO_FLICKER, auto_exposure);
freenect_set_flag(f_dev, FREENECT_AUTO_WHITE_BALANCE, auto_exposure);
auto_exposure = auto_exposure ? FREENECT_OFF : FREENECT_ON;
}
if (key == 'b') {
Expand Down
29 changes: 29 additions & 0 deletions include/libfreenect.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ typedef enum {
typedef enum {
// values written to the CMOS register
FREENECT_AUTO_EXPOSURE = 1 << 14,
FREENECT_AUTO_FLICKER = 1 << 7,
FREENECT_AUTO_WHITE_BALANCE = 1 << 1,
FREENECT_RAW_COLOR = 1 << 4,
// arbitrary bitfields to support flag combination
Expand Down Expand Up @@ -670,6 +671,34 @@ FREENECTAPI int freenect_set_depth_mode(freenect_device* dev, const freenect_fra
*/
FREENECTAPI int freenect_set_flag(freenect_device *dev, freenect_flag flag, freenect_flag_value value);

/**
* Get the current exposure in microseconds
*
* @param dev Device to set exposure
* @param time_us exposure time in microseconds
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_get_exposure(freenect_device *dev, int *time_us);

/**
* Sets a static exposure time in microseconds
* note: you must turn off auto-exposure before calling this function
*
* Sample usage with 33.333ms exposure:
*
* freenect_set_flag(fn_dev, FREENECT_AUTO_EXPOSURE, FREENECT_OFF);
* freenect_set_flag(fn_dev, FREENECT_AUTO_FLICKER, FREENECT_OFF);
* freenect_set_flag(fn_dev, FREENECT_AUTO_WHITE_BALANCE, FREENECT_OFF);
* freenect_set_exposure(fn_dev, 33333);
*
* @param dev Device to set exposure
* @param time_us exposure time in microseconds
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_set_exposure(freenect_device *dev, int time_us);

/**
* Returns the brightness of the IR sensor.
*
Expand Down
52 changes: 52 additions & 0 deletions src/flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,58 @@ int freenect_set_flag(freenect_device *dev, freenect_flag flag, freenect_flag_va
return write_cmos_register(dev, 0x0106, cmos_value);
}

int freenect_get_exposure(freenect_device *dev, int *time_us)
{
freenect_context *ctx = dev->parent;

uint16_t shutter_width = read_cmos_register(dev, 0x0009);
if (shutter_width == UINT16_MAX)
{
return -1;
}
switch (dev->video_format) {
case FREENECT_VIDEO_RGB:
case FREENECT_VIDEO_BAYER:
*time_us = shutter_width * SHUTTER_WIDTH_TO_EXP_RGB;
break;
case FREENECT_VIDEO_YUV_RGB:
case FREENECT_VIDEO_YUV_RAW:
*time_us = shutter_width * SHUTTER_WIDTH_TO_EXP_YUV;
break;
case FREENECT_VIDEO_DUMMY:
case FREENECT_VIDEO_IR_8BIT:
case FREENECT_VIDEO_IR_10BIT:
case FREENECT_VIDEO_IR_10BIT_PACKED:
FN_WARNING("Could not get exposure, invalid video format");
return -1;
}
return 0;
}

int freenect_set_exposure(freenect_device *dev, int time_us)
{
freenect_context *ctx = dev->parent;

uint16_t cmos_value = 0;
switch (dev->video_format) {
case FREENECT_VIDEO_RGB:
case FREENECT_VIDEO_BAYER:
cmos_value = time_us / SHUTTER_WIDTH_TO_EXP_RGB;
break;
case FREENECT_VIDEO_YUV_RGB:
case FREENECT_VIDEO_YUV_RAW:
cmos_value = time_us / SHUTTER_WIDTH_TO_EXP_YUV;
break;
case FREENECT_VIDEO_DUMMY:
case FREENECT_VIDEO_IR_8BIT:
case FREENECT_VIDEO_IR_10BIT:
case FREENECT_VIDEO_IR_10BIT_PACKED:
FN_WARNING("Could not set exposure, invalid video format");
return -1;
}
return write_cmos_register(dev, 0x0009, cmos_value);;
}

int freenect_get_ir_brightness(freenect_device *dev)
{
freenect_context *ctx = dev->parent;
Expand Down
6 changes: 6 additions & 0 deletions src/freenect_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ static inline int32_t fn_le32s(int32_t s)
#define PID_K4W_AUDIO_ALT_1 0x02c3
#define PID_K4W_AUDIO_ALT_2 0x02bb

// Conversion from shutter width to exposure in microseconds
// Measured using camtest.c with various very long exposure times
// TODO: calculate this from camera registers instead of magic numbers
#define SHUTTER_WIDTH_TO_EXP_RGB 54.21
#define SHUTTER_WIDTH_TO_EXP_YUV 63.25

typedef struct {
int running;
uint8_t flag;
Expand Down

0 comments on commit 0f8d11e

Please sign in to comment.