Patch #1789 access to Android camera settings applied.

pull/13383/head
Alexander Smorkalov 13 years ago
parent 8b65286139
commit 3c08f7a14d
  1. 237
      modules/androidcamera/camera_wrapper/camera_wrapper.cpp
  2. 59
      modules/androidcamera/include/camera_properties.h
  3. 49
      modules/highgui/include/opencv2/highgui/highgui_c.h
  4. 40
      modules/highgui/src/cap_android.cpp

@ -86,6 +86,11 @@ protected:
int emptyCameraCallbackReported;
static const char* flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM];
static const char* focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM];
static const char* whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM];
static const char* antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM];
void doCall(void* buffer, size_t bufferSize)
{
if (cameraCallback == 0)
@ -156,6 +161,68 @@ protected:
camera->releaseRecordingFrame(dataPtr);
}
// Split list of floats, returns number of floats found
static int split_float(const char *str, float* out, char delim, int max_elem_num,
char **endptr = NULL)
{
// Find the first float.
char *end = const_cast<char*>(str);
int elem_num = 0;
for(; elem_num < max_elem_num; elem_num++ ){
char* curr_end;
out[elem_num] = (float)strtof(end, &curr_end);
// No other numbers found, finish the loop
if(end == curr_end){
break;
}
if (*curr_end != delim) {
// When end of string, finish the loop
if (*curr_end == 0){
elem_num++;
break;
}
else {
LOGE("Cannot find delimeter (%c) in str=%s", delim, str);
return -1;
}
}
// Skip the delimiter character
end = curr_end + 1;
}
if (endptr)
*endptr = end;
return elem_num;
}
int is_supported(const char* supp_modes_key, const char* mode)
{
const char* supported_modes = params.get(supp_modes_key);
return strstr(supported_modes, mode) > 0;
}
float getFocusDistance(int focus_distance_type){
if (focus_distance_type >= 0 && focus_distance_type < 3) {
float focus_distances[3];
const char* output = params.get(CameraParameters::KEY_FOCUS_DISTANCES);
int val_num = CameraHandler::split_float(output, focus_distances, ',', 3);
if(val_num == 3){
return focus_distances[focus_distance_type];
} else {
LOGE("Invalid focus distances.");
}
}
return -1;
}
static int getModeNum(const char** modes, const int modes_num, const char* mode_name)
{
for (int i = 0; i < modes_num; i++){
if(!strcmp(modes[i],mode_name))
return i;
}
return -1;
}
public:
CameraHandler(CameraCallback callback = 0, void* _userData = 0):
cameraId(0),
@ -220,6 +287,42 @@ public:
std::string cameraPropertyPreviewFormatString;
};
const char* CameraHandler::flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM] =
{
CameraParameters::FLASH_MODE_AUTO,
CameraParameters::FLASH_MODE_OFF,
CameraParameters::FLASH_MODE_ON,
CameraParameters::FLASH_MODE_RED_EYE,
CameraParameters::FLASH_MODE_TORCH
};
const char* CameraHandler::focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM] =
{
CameraParameters::FOCUS_MODE_AUTO,
CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
CameraParameters::FOCUS_MODE_EDOF,
CameraParameters::FOCUS_MODE_FIXED,
CameraParameters::FOCUS_MODE_INFINITY
};
const char* CameraHandler::whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM] =
{
CameraParameters::WHITE_BALANCE_AUTO,
CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
CameraParameters::WHITE_BALANCE_DAYLIGHT,
CameraParameters::WHITE_BALANCE_FLUORESCENT,
CameraParameters::WHITE_BALANCE_INCANDESCENT,
CameraParameters::WHITE_BALANCE_SHADE,
CameraParameters::WHITE_BALANCE_TWILIGHT
};
const char* CameraHandler::antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM] =
{
CameraParameters::ANTIBANDING_50HZ,
CameraParameters::ANTIBANDING_60HZ,
CameraParameters::ANTIBANDING_AUTO
};
CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters)
{
@ -229,7 +332,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
#ifdef ANDROID_r2_2_0
camera = Camera::connect();
#else
#else
/* This is 2.3 or higher. The connect method has cameraID parameter */
camera = Camera::connect(cameraId);
#endif
@ -435,7 +538,6 @@ double CameraHandler::getProperty(int propIdx)
u.str = cameraPropertySupportedPreviewSizesString.c_str();
return u.res;
}
case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING:
{
const char* fmt = params.get(CameraParameters::KEY_PREVIEW_FORMAT);
@ -456,7 +558,62 @@ double CameraHandler::getProperty(int propIdx)
u.str = cameraPropertyPreviewFormatString.c_str();
return u.res;
}
case ANDROID_CAMERA_PROPERTY_EXPOSURE:
{
int exposure = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
return exposure;
}
case ANDROID_CAMERA_PROPERTY_FPS:
{
return params.getPreviewFrameRate();
}
case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
{
int flash_mode = getModeNum(CameraHandler::flashModesNames,
ANDROID_CAMERA_FLASH_MODES_NUM,
params.get(CameraParameters::KEY_FLASH_MODE));
return flash_mode;
}
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
{
int focus_mode = getModeNum(CameraHandler::focusModesNames,
ANDROID_CAMERA_FOCUS_MODES_NUM,
params.get(CameraParameters::KEY_FOCUS_MODE));
return focus_mode;
}
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
{
int white_balance = getModeNum(CameraHandler::whiteBalanceModesNames,
ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM,
params.get(CameraParameters::KEY_WHITE_BALANCE));
return white_balance;
}
case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
{
int antibanding = getModeNum(CameraHandler::antibandingModesNames,
ANDROID_CAMERA_ANTIBANDING_MODES_NUM,
params.get(CameraParameters::KEY_ANTIBANDING));
return antibanding;
}
case ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH:
{
float focal_length = params.getFloat(CameraParameters::KEY_FOCAL_LENGTH);
return focal_length;
}
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR:
{
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_NEAR_INDEX);
}
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL:
{
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_OPTIMAL_INDEX);
}
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR:
{
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX);
}
default:
LOGW("CameraHandler::getProperty - Unsupported property.");
};
return -1;
}
@ -483,6 +640,80 @@ void CameraHandler::setProperty(int propIdx, double value)
params.setPreviewSize(w, h);
}
break;
case ANDROID_CAMERA_PROPERTY_EXPOSURE:
{
int max_exposure = params.getInt("max-exposure-compensation");
int min_exposure = params.getInt("min-exposure-compensation");
if(max_exposure && min_exposure){
int exposure = (int)value;
if(exposure >= min_exposure && exposure <= max_exposure){
params.set("exposure-compensation", exposure);
} else {
LOGE("Exposure compensation not in valid range (%i,%i).", min_exposure, max_exposure);
}
} else {
LOGE("Exposure compensation adjust is not supported.");
}
}
break;
case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
{
int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_FLASH_MODES_NUM){
const char* mode_name = flashModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mode_name))
params.set(CameraParameters::KEY_FLASH_MODE, mode_name);
else
LOGE("Flash mode %s is not supported.", mode_name);
} else {
LOGE("Flash mode value not in valid range.");
}
}
break;
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
{
int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_FOCUS_MODES_NUM){
const char* mode_name = focusModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mode_name))
params.set(CameraParameters::KEY_FOCUS_MODE, mode_name);
else
LOGE("Focus mode %s is not supported.", mode_name);
} else {
LOGE("Focus mode value not in valid range.");
}
}
break;
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
{
int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM){
const char* mode_name = whiteBalanceModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mode_name))
params.set(CameraParameters::KEY_WHITE_BALANCE, mode_name);
else
LOGE("White balance mode %s is not supported.", mode_name);
} else {
LOGE("White balance mode value not in valid range.");
}
}
break;
case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
{
int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_ANTIBANDING_MODES_NUM){
const char* mode_name = antibandingModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mode_name))
params.set(CameraParameters::KEY_ANTIBANDING, mode_name);
else
LOGE("Antibanding mode %s is not supported.", mode_name);
} else {
LOGE("Antibanding mode value not in valid range.");
}
}
break;
default:
LOGW("CameraHandler::setProperty - Unsupported property.");
};
}

@ -5,7 +5,64 @@ enum {
ANDROID_CAMERA_PROPERTY_FRAMEWIDTH = 0,
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT = 1,
ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING = 2,
ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING = 3
ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING = 3,
ANDROID_CAMERA_PROPERTY_FPS = 4,
ANDROID_CAMERA_PROPERTY_EXPOSURE = 5,
ANDROID_CAMERA_PROPERTY_FLASH_MODE = 101,
ANDROID_CAMERA_PROPERTY_FOCUS_MODE = 102,
ANDROID_CAMERA_PROPERTY_WHITE_BALANCE = 103,
ANDROID_CAMERA_PROPERTY_ANTIBANDING = 104,
ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH = 105,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR = 106,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL = 107,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR = 108
};
enum {
ANDROID_CAMERA_FLASH_MODE_AUTO = 0,
ANDROID_CAMERA_FLASH_MODE_OFF,
ANDROID_CAMERA_FLASH_MODE_ON,
ANDROID_CAMERA_FLASH_MODE_RED_EYE,
ANDROID_CAMERA_FLASH_MODE_TORCH,
ANDROID_CAMERA_FLASH_MODES_NUM
};
enum {
ANDROID_CAMERA_FOCUS_MODE_AUTO = 0,
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_PICTURE,
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_VIDEO,
ANDROID_CAMERA_FOCUS_MODE_EDOF,
ANDROID_CAMERA_FOCUS_MODE_FIXED,
ANDROID_CAMERA_FOCUS_MODE_INFINITY,
ANDROID_CAMERA_FOCUS_MODE_MACRO,
ANDROID_CAMERA_FOCUS_MODES_NUM
};
enum {
ANDROID_CAMERA_WHITE_BALANCE_AUTO = 0,
ANDROID_CAMERA_WHITE_BALANCE_CLOUDY_DAYLIGHT,
ANDROID_CAMERA_WHITE_BALANCE_DAYLIGHT,
ANDROID_CAMERA_WHITE_BALANCE_FLUORESCENT,
ANDROID_CAMERA_WHITE_BALANCE_INCANDESCENT,
ANDROID_CAMERA_WHITE_BALANCE_SHADE,
ANDROID_CAMERA_WHITE_BALANCE_TWILIGHT,
ANDROID_CAMERA_WHITE_BALANCE_WARM_FLUORESCENT,
ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM
};
enum {
ANDROID_CAMERA_ANTIBANDING_50HZ = 0,
ANDROID_CAMERA_ANTIBANDING_60HZ,
ANDROID_CAMERA_ANTIBANDING_AUTO,
ANDROID_CAMERA_ANTIBANDING_OFF,
ANDROID_CAMERA_ANTIBANDING_MODES_NUM
};
enum {
ANDROID_CAMERA_FOCUS_DISTANCE_NEAR_INDEX = 0,
ANDROID_CAMERA_FOCUS_DISTANCE_OPTIMAL_INDEX,
ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX
};
#endif // CAMERA_PROPERTIES_H

@ -436,6 +436,16 @@ enum
CV_CAP_PROP_XI_AEAG_LEVEL = 419, // Average intensity of output signal AEAG should achieve(in %)
CV_CAP_PROP_XI_TIMEOUT = 420, // Image capture timeout in milliseconds
// Properties for Android cameras
CV_CAP_PROP_ANDROID_FLASH_MODE = 8001,
CV_CAP_PROP_ANDROID_FOCUS_MODE = 8002,
CV_CAP_PROP_ANDROID_WHITE_BALANCE = 8003,
CV_CAP_PROP_ANDROID_ANTIBANDING = 8004,
CV_CAP_PROP_ANDROID_FOCAL_LENGTH = 8005,
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006,
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007,
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008,
// Properties of cameras available through AVFOUNDATION interface
CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001,
CV_CAP_PROP_IOS_DEVICE_EXPOSURE = 9002,
@ -477,6 +487,45 @@ enum
CV_CAP_ANDROID_COLOR_FRAME_RGBA = 4
};
// supported Android camera flash modes
enum {
CV_CAP_ANDROID_FLASH_MODE_AUTO = 0,
CV_CAP_ANDROID_FLASH_MODE_OFF,
CV_CAP_ANDROID_FLASH_MODE_ON,
CV_CAP_ANDROID_FLASH_MODE_RED_EYE,
CV_CAP_ANDROID_FLASH_MODE_TORCH
};
// supported Android camera focus modes
enum {
CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0,
CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO,
CV_CAP_ANDROID_FOCUS_MODE_EDOF,
CV_CAP_ANDROID_FOCUS_MODE_FIXED,
CV_CAP_ANDROID_FOCUS_MODE_INFINITY,
CV_CAP_ANDROID_FOCUS_MODE_MACRO
};
// supported Android camera white balance modes
enum {
CV_CAP_ANDROID_WHITE_BALANCE_AUTO = 0,
CV_CAP_ANDROID_WHITE_BALANCE_CLOUDY_DAYLIGHT,
CV_CAP_ANDROID_WHITE_BALANCE_DAYLIGHT,
CV_CAP_ANDROID_WHITE_BALANCE_FLUORESCENT,
CV_CAP_ANDROID_WHITE_BALANCE_INCANDESCENT,
CV_CAP_ANDROID_WHITE_BALANCE_SHADE,
CV_CAP_ANDROID_WHITE_BALANCE_TWILIGHT,
CV_CAP_ANDROID_WHITE_BALANCE_WARM_FLUORESCENT
};
// supported Android camera antibanding modes
enum {
CV_CAP_ANDROID_ANTIBANDING_50HZ = 0,
CV_CAP_ANDROID_ANTIBANDING_60HZ,
CV_CAP_ANDROID_ANTIBANDING_AUTO,
CV_CAP_ANDROID_ANTIBANDING_OFF
};
/* retrieve or set capture properties */
CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id );
CVAPI(int) cvSetCaptureProperty( CvCapture* capture, int property_id, double value );

@ -263,11 +263,30 @@ double CvCapture_Android::getProperty( int propIdx )
return (double)m_activity->getFrameWidth();
case CV_CAP_PROP_FRAME_HEIGHT:
return (double)m_activity->getFrameHeight();
case CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING);
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING);
case CV_CAP_PROP_PREVIEW_FORMAT:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING);
case CV_CAP_PROP_FPS:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FPS);
case CV_CAP_PROP_EXPOSURE:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE);
case CV_CAP_PROP_ANDROID_FLASH_MODE:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE);
case CV_CAP_PROP_ANDROID_FOCUS_MODE:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE);
case CV_CAP_PROP_ANDROID_WHITE_BALANCE:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE);
case CV_CAP_PROP_ANDROID_ANTIBANDING:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING);
case CV_CAP_PROP_ANDROID_FOCAL_LENGTH:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH);
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR);
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL);
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR);
default:
CV_Error( CV_StsOutOfRange, "Failed attempt to GET unsupported camera property." );
break;
@ -288,11 +307,24 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
case CV_CAP_PROP_FRAME_HEIGHT:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT, propValue);
break;
case CV_CAP_PROP_AUTOGRAB:
m_shouldAutoGrab=(propValue != 0);
break;
case CV_CAP_PROP_EXPOSURE:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE, propValue);
break;
case CV_CAP_PROP_ANDROID_FLASH_MODE:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE, propValue);
break;
case CV_CAP_PROP_ANDROID_FOCUS_MODE:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE, propValue);
break;
case CV_CAP_PROP_ANDROID_WHITE_BALANCE:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE, propValue);
break;
case CV_CAP_PROP_ANDROID_ANTIBANDING:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING, propValue);
break;
default:
CV_Error( CV_StsOutOfRange, "Failed attempt to SET unsupported camera property." );
return false;

Loading…
Cancel
Save