Merge pull request #8711 from ArkadiuszRaj:aravis_autoexposure_correction

Aravis: Use of std::fabs, added support for 16-bit mono files and exposure compensation (#8711)

* Use of std::fabs, added support for 16-bit mono files

* Correction in priority2 stage &  adding exposure compensation
pull/8726/head^2
Arek 8 years ago committed by Alexander Alekhin
parent 17eef4d8a9
commit 9edcd9b4ef
  1. 36
      modules/videoio/src/cap_aravis.cpp

@ -64,6 +64,7 @@
// read/write
// CAP_PROP_AUTO_EXPOSURE(0|1)
// CAP_PROP_EXPOSURE(t), t in seconds
// CAP_PROP_BRIGHTNESS (ev), exposure compensation in EV for auto exposure algorithm
// CAP_PROP_GAIN(g), g >=0 or -1 for automatic control if CAP_PROP_AUTO_EXPOSURE is true
// CAP_PROP_FPS(f)
// CAP_PROP_FOURCC(type)
@ -77,11 +78,13 @@
// video/x-raw, fourcc:'GREY' -> 8bit, 1 channel
// video/x-raw, fourcc:'Y800' -> 8bit, 1 channel
// video/x-raw, fourcc:'Y12 ' -> 12bit, 1 channel
// video/x-raw, fourcc:'Y16 ' -> 16bit, 1 channel
//
#define MODE_GREY CV_FOURCC_MACRO('G','R','E','Y')
#define MODE_Y800 CV_FOURCC_MACRO('Y','8','0','0')
#define MODE_Y12 CV_FOURCC_MACRO('Y','1','2',' ')
#define MODE_Y16 CV_FOURCC_MACRO('Y','1','6',' ')
#define CLIP(a,b,c) (cv::max(cv::min((a),(c)),(b)))
@ -139,6 +142,7 @@ protected:
double exposureMax; // Camera's maximum exposure time.
bool controlExposure; // Flag if automatic exposure shall be done by this SW
double exposureCompensation;
bool autoGain;
double targetGrey; // Target grey value (mid grey))
@ -179,10 +183,11 @@ CvCaptureCAM_Aravis::CvCaptureCAM_Aravis()
xoffset = yoffset = width = height = 0;
fpsMin = fpsMax = gainMin = gainMax = exposureMin = exposureMax = 0;
controlExposure = false;
exposureCompensation = 0;
targetGrey = 0;
frameID = prevFrameID = 0;
num_buffers = 50;
num_buffers = 10;
frame = NULL;
}
@ -314,6 +319,7 @@ IplImage* CvCaptureCAM_Aravis::retrieveFrame(int)
channels = 1;
break;
case ARV_PIXEL_FORMAT_MONO_12:
case ARV_PIXEL_FORMAT_MONO_16:
depth = IPL_DEPTH_16U;
channels = 1;
break;
@ -334,8 +340,8 @@ IplImage* CvCaptureCAM_Aravis::retrieveFrame(int)
}
cvCopy(&src, frame);
if(controlExposure && ((frameID - prevFrameID) > 1)) {
// control exposure every second frame
if(controlExposure && ((frameID - prevFrameID) >= 3)) {
// control exposure every third frame
// i.e. skip frame taken with previous exposure setup
autoExposureControl(frame);
}
@ -372,15 +378,15 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
midGrey = brightness;
double maxe = 1e6 / fps;
double ne = CLIP( ( exposure * d ) / dmid, exposureMin, maxe);
double ne = CLIP( ( exposure * d ) / ( dmid * pow(sqrt(2), -2 * exposureCompensation) ), exposureMin, maxe);
// if change of value requires intervention
if(fabs(d-dmid) > 5) {
if(std::fabs(d-dmid) > 5) {
double ev, ng = 0;
if(gainAvailable && autoGain) {
ev = log( d / dmid ) / log(2);
ng = CLIP( gain + ev, gainMin, gainMax);
ng = CLIP( gain + ev + exposureCompensation, gainMin, gainMax);
if( ng < gain ) {
// piority 1 - reduce gain
@ -390,8 +396,9 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
}
if(exposureAvailable) {
if(abs(exposure - ne) > 2) {
// priority 2 - control of exposure time
// priority 2 - control of exposure time
if(std::fabs(exposure - ne) > 2) {
// we have not yet reach the max-e level
arv_camera_set_exposure_time(camera, (exposure = ne) );
return;
}
@ -436,6 +443,9 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
case CV_CAP_PROP_AUTO_EXPOSURE:
return (controlExposure ? 1 : 0);
case CV_CAP_PROP_BRIGHTNESS:
return exposureCompensation;
case CV_CAP_PROP_EXPOSURE:
if(exposureAvailable) {
/* exposure time in seconds, like 1/100 s */
@ -463,6 +473,8 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
return MODE_Y800;
case ARV_PIXEL_FORMAT_MONO_12:
return MODE_Y12;
case ARV_PIXEL_FORMAT_MONO_16:
return MODE_Y16;
}
}
break;
@ -490,6 +502,9 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
}
}
break;
case CV_CAP_PROP_BRIGHTNESS:
exposureCompensation = CLIP(value, -3., 3.);
break;
case CV_CAP_PROP_EXPOSURE:
if(exposureAvailable) {
@ -528,6 +543,10 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
newFormat = ARV_PIXEL_FORMAT_MONO_12;
targetGrey = 2048;
break;
case MODE_Y16:
newFormat = ARV_PIXEL_FORMAT_MONO_16;
targetGrey = 32768;
break;
}
if(newFormat != pixelFormat) {
stopCapture();
@ -570,7 +589,6 @@ bool CvCaptureCAM_Aravis::startCapture()
{
if(init_buffers() ) {
arv_camera_set_acquisition_mode(camera, ARV_ACQUISITION_MODE_CONTINUOUS);
arv_device_set_string_feature_value(arv_camera_get_device (camera), "TriggerMode" , "Off");
arv_camera_start_acquisition(camera);
return true;

Loading…
Cancel
Save