Skip to content

Commit 9edcd9b

Browse files
ArkadiuszRajalalek
authored andcommitted
Merge pull request opencv#8711 from ArkadiuszRaj:aravis_autoexposure_correction
Aravis: Use of std::fabs, added support for 16-bit mono files and exposure compensation (opencv#8711) * Use of std::fabs, added support for 16-bit mono files * Correction in priority2 stage & adding exposure compensation
1 parent 17eef4d commit 9edcd9b

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

modules/videoio/src/cap_aravis.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
// read/write
6565
// CAP_PROP_AUTO_EXPOSURE(0|1)
6666
// CAP_PROP_EXPOSURE(t), t in seconds
67+
// CAP_PROP_BRIGHTNESS (ev), exposure compensation in EV for auto exposure algorithm
6768
// CAP_PROP_GAIN(g), g >=0 or -1 for automatic control if CAP_PROP_AUTO_EXPOSURE is true
6869
// CAP_PROP_FPS(f)
6970
// CAP_PROP_FOURCC(type)
@@ -77,11 +78,13 @@
7778
// video/x-raw, fourcc:'GREY' -> 8bit, 1 channel
7879
// video/x-raw, fourcc:'Y800' -> 8bit, 1 channel
7980
// video/x-raw, fourcc:'Y12 ' -> 12bit, 1 channel
81+
// video/x-raw, fourcc:'Y16 ' -> 16bit, 1 channel
8082
//
8183

8284
#define MODE_GREY CV_FOURCC_MACRO('G','R','E','Y')
8385
#define MODE_Y800 CV_FOURCC_MACRO('Y','8','0','0')
8486
#define MODE_Y12 CV_FOURCC_MACRO('Y','1','2',' ')
87+
#define MODE_Y16 CV_FOURCC_MACRO('Y','1','6',' ')
8588

8689
#define CLIP(a,b,c) (cv::max(cv::min((a),(c)),(b)))
8790

@@ -139,6 +142,7 @@ class CvCaptureCAM_Aravis : public CvCapture
139142
double exposureMax; // Camera's maximum exposure time.
140143

141144
bool controlExposure; // Flag if automatic exposure shall be done by this SW
145+
double exposureCompensation;
142146
bool autoGain;
143147
double targetGrey; // Target grey value (mid grey))
144148

@@ -179,10 +183,11 @@ CvCaptureCAM_Aravis::CvCaptureCAM_Aravis()
179183
xoffset = yoffset = width = height = 0;
180184
fpsMin = fpsMax = gainMin = gainMax = exposureMin = exposureMax = 0;
181185
controlExposure = false;
186+
exposureCompensation = 0;
182187
targetGrey = 0;
183188
frameID = prevFrameID = 0;
184189

185-
num_buffers = 50;
190+
num_buffers = 10;
186191
frame = NULL;
187192
}
188193

@@ -314,6 +319,7 @@ IplImage* CvCaptureCAM_Aravis::retrieveFrame(int)
314319
channels = 1;
315320
break;
316321
case ARV_PIXEL_FORMAT_MONO_12:
322+
case ARV_PIXEL_FORMAT_MONO_16:
317323
depth = IPL_DEPTH_16U;
318324
channels = 1;
319325
break;
@@ -334,8 +340,8 @@ IplImage* CvCaptureCAM_Aravis::retrieveFrame(int)
334340
}
335341
cvCopy(&src, frame);
336342

337-
if(controlExposure && ((frameID - prevFrameID) > 1)) {
338-
// control exposure every second frame
343+
if(controlExposure && ((frameID - prevFrameID) >= 3)) {
344+
// control exposure every third frame
339345
// i.e. skip frame taken with previous exposure setup
340346
autoExposureControl(frame);
341347
}
@@ -372,15 +378,15 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
372378
midGrey = brightness;
373379

374380
double maxe = 1e6 / fps;
375-
double ne = CLIP( ( exposure * d ) / dmid, exposureMin, maxe);
381+
double ne = CLIP( ( exposure * d ) / ( dmid * pow(sqrt(2), -2 * exposureCompensation) ), exposureMin, maxe);
376382

377383
// if change of value requires intervention
378-
if(fabs(d-dmid) > 5) {
384+
if(std::fabs(d-dmid) > 5) {
379385
double ev, ng = 0;
380386

381387
if(gainAvailable && autoGain) {
382388
ev = log( d / dmid ) / log(2);
383-
ng = CLIP( gain + ev, gainMin, gainMax);
389+
ng = CLIP( gain + ev + exposureCompensation, gainMin, gainMax);
384390

385391
if( ng < gain ) {
386392
// piority 1 - reduce gain
@@ -390,8 +396,9 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
390396
}
391397

392398
if(exposureAvailable) {
393-
if(abs(exposure - ne) > 2) {
394-
// priority 2 - control of exposure time
399+
// priority 2 - control of exposure time
400+
if(std::fabs(exposure - ne) > 2) {
401+
// we have not yet reach the max-e level
395402
arv_camera_set_exposure_time(camera, (exposure = ne) );
396403
return;
397404
}
@@ -436,6 +443,9 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
436443
case CV_CAP_PROP_AUTO_EXPOSURE:
437444
return (controlExposure ? 1 : 0);
438445

446+
case CV_CAP_PROP_BRIGHTNESS:
447+
return exposureCompensation;
448+
439449
case CV_CAP_PROP_EXPOSURE:
440450
if(exposureAvailable) {
441451
/* exposure time in seconds, like 1/100 s */
@@ -463,6 +473,8 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
463473
return MODE_Y800;
464474
case ARV_PIXEL_FORMAT_MONO_12:
465475
return MODE_Y12;
476+
case ARV_PIXEL_FORMAT_MONO_16:
477+
return MODE_Y16;
466478
}
467479
}
468480
break;
@@ -490,6 +502,9 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
490502
}
491503
}
492504
break;
505+
case CV_CAP_PROP_BRIGHTNESS:
506+
exposureCompensation = CLIP(value, -3., 3.);
507+
break;
493508

494509
case CV_CAP_PROP_EXPOSURE:
495510
if(exposureAvailable) {
@@ -528,6 +543,10 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
528543
newFormat = ARV_PIXEL_FORMAT_MONO_12;
529544
targetGrey = 2048;
530545
break;
546+
case MODE_Y16:
547+
newFormat = ARV_PIXEL_FORMAT_MONO_16;
548+
targetGrey = 32768;
549+
break;
531550
}
532551
if(newFormat != pixelFormat) {
533552
stopCapture();
@@ -570,7 +589,6 @@ bool CvCaptureCAM_Aravis::startCapture()
570589
{
571590
if(init_buffers() ) {
572591
arv_camera_set_acquisition_mode(camera, ARV_ACQUISITION_MODE_CONTINUOUS);
573-
arv_device_set_string_feature_value(arv_camera_get_device (camera), "TriggerMode" , "Off");
574592
arv_camera_start_acquisition(camera);
575593

576594
return true;

0 commit comments

Comments
 (0)