From 08696d92eab96ba14a16fafa4c5be96de26c1305 Mon Sep 17 00:00:00 2001 From: Smirnov Egor Date: Mon, 4 Jul 2022 15:56:28 +0300 Subject: [PATCH] Add option to force reopen camera in interactive calibration tool --- apps/interactive-calibration/calibCommon.hpp | 1 + .../interactive-calibration/calibPipeline.cpp | 71 +++++++++++++------ apps/interactive-calibration/main.cpp | 1 + .../parametersController.cpp | 1 + 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/apps/interactive-calibration/calibCommon.hpp b/apps/interactive-calibration/calibCommon.hpp index f3fffa1729..d47d04eb56 100644 --- a/apps/interactive-calibration/calibCommon.hpp +++ b/apps/interactive-calibration/calibCommon.hpp @@ -95,6 +95,7 @@ namespace calib int minFramesNum; bool saveFrames; float zoom; + bool forceReopen; captureParameters() { diff --git a/apps/interactive-calibration/calibPipeline.cpp b/apps/interactive-calibration/calibPipeline.cpp index 3b0eedffec..ac54764e41 100644 --- a/apps/interactive-calibration/calibPipeline.cpp +++ b/apps/interactive-calibration/calibPipeline.cpp @@ -6,6 +6,7 @@ #include #include +#include #include @@ -30,37 +31,61 @@ CalibPipeline::CalibPipeline(captureParameters params) : PipelineExitStatus CalibPipeline::start(std::vector > processors) { - if(mCaptureParams.source == Camera && !mCapture.isOpened()) - { - mCapture.open(mCaptureParams.camID); - cv::Size maxRes = getCameraResolution(); - cv::Size neededRes = mCaptureParams.cameraResolution; - - if(maxRes.width < neededRes.width) { - double aR = (double)maxRes.width / maxRes.height; - mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width); - mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.width/aR); - } - else if(maxRes.height < neededRes.height) { - double aR = (double)maxRes.width / maxRes.height; - mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height); - mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.height*aR); - } - else { - mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height); - mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width); + auto open_camera = [this] () { + if(mCaptureParams.source == Camera) + { + mCapture.open(mCaptureParams.camID); + cv::Size maxRes = getCameraResolution(); + cv::Size neededRes = mCaptureParams.cameraResolution; + + if(maxRes.width < neededRes.width) { + double aR = (double)maxRes.width / maxRes.height; + mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width); + mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.width/aR); + } + else if(maxRes.height < neededRes.height) { + double aR = (double)maxRes.width / maxRes.height; + mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height); + mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.height*aR); + } + else { + mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height); + mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width); + } + mCapture.set(cv::CAP_PROP_AUTOFOCUS, 0); } - mCapture.set(cv::CAP_PROP_AUTOFOCUS, 0); + else if (mCaptureParams.source == File) + mCapture.open(mCaptureParams.videoFileName); + }; + + if(!mCapture.isOpened()) { + open_camera(); } - else if (mCaptureParams.source == File && !mCapture.isOpened()) - mCapture.open(mCaptureParams.videoFileName); mImageSize = cv::Size((int)mCapture.get(cv::CAP_PROP_FRAME_WIDTH), (int)mCapture.get(cv::CAP_PROP_FRAME_HEIGHT)); if(!mCapture.isOpened()) throw std::runtime_error("Unable to open video source"); cv::Mat frame, processedFrame, resizedFrame; - while(mCapture.grab()) { + while (true) { + if (!mCapture.grab()) + { + if (!mCaptureParams.forceReopen) + { + CV_LOG_ERROR(NULL, "VideoCapture error: could not grab the frame."); + break; + } + + CV_LOG_INFO(NULL, "VideoCapture error: trying to reopen..."); + do + { + open_camera(); + } while (!mCapture.isOpened() || !mCapture.grab()); + + CV_LOG_INFO(NULL, "VideoCapture error: reopened successfully."); + auto newSize = cv::Size((int)mCapture.get(cv::CAP_PROP_FRAME_WIDTH), (int)mCapture.get(cv::CAP_PROP_FRAME_HEIGHT)); + CV_CheckEQ(mImageSize, newSize, "Camera image size changed after reopening."); + } mCapture.retrieve(frame); if(mCaptureParams.flipVertical) cv::flip(frame, frame, -1); diff --git a/apps/interactive-calibration/main.cpp b/apps/interactive-calibration/main.cpp index c2a6aa7298..d8b31db18a 100644 --- a/apps/interactive-calibration/main.cpp +++ b/apps/interactive-calibration/main.cpp @@ -42,6 +42,7 @@ const std::string keys = "{pf | defaultConfig.xml| Advanced application parameters}" "{save_frames | false | Save frames that contribute to final calibration}" "{zoom | 1 | Zoom factor applied to the image}" + "{force_reopen | false | Forcefully reopen camera in case of errors}" "{help | | Print help}"; bool calib::showOverlayMessage(const std::string& message) diff --git a/apps/interactive-calibration/parametersController.cpp b/apps/interactive-calibration/parametersController.cpp index b5a01b1ea8..232a16c748 100644 --- a/apps/interactive-calibration/parametersController.cpp +++ b/apps/interactive-calibration/parametersController.cpp @@ -91,6 +91,7 @@ bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser) mCapParams.templDst = parser.get("dst"); mCapParams.saveFrames = parser.has("save_frames"); mCapParams.zoom = parser.get("zoom"); + mCapParams.forceReopen = parser.get("force_reopen"); if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive")) return false;