diff --git a/modules/videoio/src/cap_aravis.cpp b/modules/videoio/src/cap_aravis.cpp index c272bee726..b5c71a86a3 100644 --- a/modules/videoio/src/cap_aravis.cpp +++ b/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;