Commit 9edcd9b4 authored by Arek's avatar Arek Committed by Alexander Alekhin

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