From b729d8e821c296ea07ecb3af38ef309819cf5cb0 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 8 Jun 2023 14:50:58 +0300 Subject: [PATCH] added graphicalCodeDetector, remove QRCodeDetectorBase --- .../objdetect/include/opencv2/objdetect.hpp | 78 +----------------- .../objdetect/graphical_code_detector.hpp | 81 +++++++++++++++++++ .../objdetect/perf/perf_qrcode_pipeline.cpp | 4 +- .../objdetect/src/graphical_code_detector.cpp | 45 +++++++++++ .../src/graphical_code_detector_impl.hpp | 25 ++++++ modules/objdetect/src/qrcode.cpp | 49 +---------- modules/objdetect/test/test_qrcode.cpp | 8 +- samples/cpp/qrcode.cpp | 8 +- 8 files changed, 166 insertions(+), 132 deletions(-) create mode 100644 modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp create mode 100644 modules/objdetect/src/graphical_code_detector.cpp create mode 100644 modules/objdetect/src/graphical_code_detector_impl.hpp diff --git a/modules/objdetect/include/opencv2/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect.hpp index 70c787a389..68b8d86e69 100644 --- a/modules/objdetect/include/opencv2/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect.hpp @@ -46,6 +46,7 @@ #include "opencv2/core.hpp" #include "opencv2/objdetect/aruco_detector.hpp" +#include "opencv2/objdetect/graphical_code_detector.hpp" /** @defgroup objdetect Object Detection @@ -763,80 +764,7 @@ public: CV_WRAP virtual void encodeStructuredAppend(const String& encoded_info, OutputArrayOfArrays qrcodes) = 0; }; - -class CV_EXPORTS_W_SIMPLE QRCodeDetectorBase { -public: - CV_DEPRECATED_EXTERNAL // avoid using in C++ code, will be moved to "protected" (need to fix bindings first) - QRCodeDetectorBase(); - - QRCodeDetectorBase(const QRCodeDetectorBase&) = default; - QRCodeDetectorBase(QRCodeDetectorBase&&) = default; - QRCodeDetectorBase& operator=(const QRCodeDetectorBase&) = default; - QRCodeDetectorBase& operator=(QRCodeDetectorBase&&) = default; - - /** @brief Detects QR code in image and returns the quadrangle containing the code. - @param img grayscale or color (BGR) image containing (or not) QR code. - @param points Output vector of vertices of the minimum-area quadrangle containing the code. - */ - CV_WRAP bool detect(InputArray img, OutputArray points) const; - - /** @brief Decodes QR code in image once it's found by the detect() method. - - Returns UTF8-encoded output string or empty string if the code cannot be decoded. - @param img grayscale or color (BGR) image containing QR code. - @param points Quadrangle vertices found by detect() method (or some other algorithm). - @param straight_qrcode The optional output image containing rectified and binarized QR code - */ - CV_WRAP std::string decode(InputArray img, InputArray points, OutputArray straight_qrcode = noArray()) const; - - /** @brief Both detects and decodes QR code - - @param img grayscale or color (BGR) image containing QR code. - @param points optional output array of vertices of the found QR code quadrangle. Will be empty if not found. - @param straight_qrcode The optional output image containing rectified and binarized QR code - */ - CV_WRAP std::string detectAndDecode(InputArray img, OutputArray points=noArray(), - OutputArray straight_qrcode = noArray()) const; - - - /** @brief Detects QR codes in image and returns the vector of the quadrangles containing the codes. - @param img grayscale or color (BGR) image containing (or not) QR codes. - @param points Output vector of vector of vertices of the minimum-area quadrangle containing the codes. - */ - CV_WRAP - bool detectMulti(InputArray img, OutputArray points) const; - - /** @brief Decodes QR codes in image once it's found by the detect() method. - @param img grayscale or color (BGR) image containing QR codes. - @param decoded_info UTF8-encoded output vector of string or empty vector of string if the codes cannot be decoded. - @param points vector of Quadrangle vertices found by detect() method (or some other algorithm). - @param straight_qrcode The optional output vector of images containing rectified and binarized QR codes - */ - CV_WRAP - bool decodeMulti( - InputArray img, InputArray points, - CV_OUT std::vector& decoded_info, - OutputArrayOfArrays straight_qrcode = noArray() - ) const; - - /** @brief Both detects and decodes QR codes - @param img grayscale or color (BGR) image containing QR codes. - @param decoded_info UTF8-encoded output vector of string or empty vector of string if the codes cannot be decoded. - @param points optional output vector of vertices of the found QR code quadrangles. Will be empty if not found. - @param straight_qrcode The optional output vector of images containing rectified and binarized QR codes - */ - CV_WRAP - bool detectAndDecodeMulti( - InputArray img, CV_OUT std::vector& decoded_info, - OutputArray points = noArray(), - OutputArrayOfArrays straight_qrcode = noArray() - ) const; - struct Impl; -protected: - Ptr p; -}; - -class CV_EXPORTS_W_SIMPLE QRCodeDetector : public QRCodeDetectorBase +class CV_EXPORTS_W_SIMPLE QRCodeDetector : public GraphicalCodeDetector { public: CV_WRAP QRCodeDetector(); @@ -877,7 +805,7 @@ public: OutputArray straight_qrcode = noArray()); }; -class CV_EXPORTS_W_SIMPLE QRCodeDetectorAruco : public QRCodeDetectorBase { +class CV_EXPORTS_W_SIMPLE QRCodeDetectorAruco : public GraphicalCodeDetector { public: CV_WRAP QRCodeDetectorAruco(); diff --git a/modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp b/modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp new file mode 100644 index 0000000000..3535a8da1c --- /dev/null +++ b/modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp @@ -0,0 +1,81 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html +#ifndef OPENCV_OBJDETECT_GRAPHICAL_CODE_DETECTOR_HPP +#define OPENCV_OBJDETECT_GRAPHICAL_CODE_DETECTOR_HPP + +#include + +namespace cv { + +//! @addtogroup objdetect_common +//! @{ + +class CV_EXPORTS_W_SIMPLE GraphicalCodeDetector { +public: + CV_DEPRECATED_EXTERNAL // avoid using in C++ code, will be moved to "protected" (need to fix bindings first) + GraphicalCodeDetector(); + + GraphicalCodeDetector(const GraphicalCodeDetector&) = default; + GraphicalCodeDetector(GraphicalCodeDetector&&) = default; + GraphicalCodeDetector& operator=(const GraphicalCodeDetector&) = default; + GraphicalCodeDetector& operator=(GraphicalCodeDetector&&) = default; + + /** @brief Detects graphical code in image and returns the quadrangle containing the code. + @param img grayscale or color (BGR) image containing (or not) graphical code. + @param points Output vector of vertices of the minimum-area quadrangle containing the code. + */ + CV_WRAP bool detect(InputArray img, OutputArray points) const; + + /** @brief Decodes graphical code in image once it's found by the detect() method. + + Returns UTF8-encoded output string or empty string if the code cannot be decoded. + @param img grayscale or color (BGR) image containing graphical code. + @param points Quadrangle vertices found by detect() method (or some other algorithm). + @param straight_code The optional output image containing binarized code, will be empty if not found. + */ + CV_WRAP std::string decode(InputArray img, InputArray points, OutputArray straight_code = noArray()) const; + + /** @brief Both detects and decodes graphical code + + @param img grayscale or color (BGR) image containing graphical code. + @param points optional output array of vertices of the found graphical code quadrangle, will be empty if not found. + @param straight_code The optional output image containing binarized code + */ + CV_WRAP std::string detectAndDecode(InputArray img, OutputArray points = noArray(), + OutputArray straight_code = noArray()) const; + + + /** @brief Detects graphical codes in image and returns the vector of the quadrangles containing the codes. + @param img grayscale or color (BGR) image containing (or not) graphical codes. + @param points Output vector of vector of vertices of the minimum-area quadrangle containing the codes. + */ + CV_WRAP bool detectMulti(InputArray img, OutputArray points) const; + + /** @brief Decodes graphical codes in image once it's found by the detect() method. + @param img grayscale or color (BGR) image containing graphical codes. + @param decoded_info UTF8-encoded output vector of string or empty vector of string if the codes cannot be decoded. + @param points vector of Quadrangle vertices found by detect() method (or some other algorithm). + @param straight_code The optional output vector of images containing binarized codes + */ + CV_WRAP bool decodeMulti(InputArray img, InputArray points, CV_OUT std::vector& decoded_info, + OutputArrayOfArrays straight_code = noArray()) const; + + /** @brief Both detects and decodes graphical codes + @param img grayscale or color (BGR) image containing graphical codes. + @param decoded_info UTF8-encoded output vector of string or empty vector of string if the codes cannot be decoded. + @param points optional output vector of vertices of the found graphical code quadrangles. Will be empty if not found. + @param straight_code The optional vector of images containing binarized codes + */ + CV_WRAP bool detectAndDecodeMulti(InputArray img, CV_OUT std::vector& decoded_info, OutputArray points = noArray(), + OutputArrayOfArrays straight_code = noArray()) const; + struct Impl; +protected: + Ptr p; +}; + +//! @} + +} + +#endif \ No newline at end of file diff --git a/modules/objdetect/perf/perf_qrcode_pipeline.cpp b/modules/objdetect/perf/perf_qrcode_pipeline.cpp index 9eac2352e3..150ed8cbbe 100644 --- a/modules/objdetect/perf/perf_qrcode_pipeline.cpp +++ b/modules/objdetect/perf/perf_qrcode_pipeline.cpp @@ -68,7 +68,7 @@ PERF_TEST_P_(Perf_Objdetect_QRCode_Multi, detectMulti) Mat src = imread(image_path); ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; std::vector corners; - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } @@ -90,7 +90,7 @@ PERF_TEST_P_(Perf_Objdetect_QRCode_Multi, decodeMulti) if (disabled_samples.find({name_current_image, method}) != disabled_samples.end()) { throw SkipTestException(name_current_image + " is disabled sample for method " + method); } - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } diff --git a/modules/objdetect/src/graphical_code_detector.cpp b/modules/objdetect/src/graphical_code_detector.cpp new file mode 100644 index 0000000000..971fd597ab --- /dev/null +++ b/modules/objdetect/src/graphical_code_detector.cpp @@ -0,0 +1,45 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#include "precomp.hpp" +#include "opencv2/objdetect/graphical_code_detector.hpp" +#include "graphical_code_detector_impl.hpp" + +namespace cv { + +GraphicalCodeDetector::GraphicalCodeDetector() {} + +bool GraphicalCodeDetector::detect(InputArray img, OutputArray points) const { + CV_Assert(p); + return p->detect(img, points); +} + +std::string GraphicalCodeDetector::decode(InputArray img, InputArray points, OutputArray straight_code) const { + CV_Assert(p); + return p->decode(img, points, straight_code); +} + +std::string GraphicalCodeDetector::detectAndDecode(InputArray img, OutputArray points, OutputArray straight_code) const { + CV_Assert(p); + return p->detectAndDecode(img, points, straight_code); +} + +bool GraphicalCodeDetector::detectMulti(InputArray img, OutputArray points) const { + CV_Assert(p); + return p->detectMulti(img, points); +} + +bool GraphicalCodeDetector::decodeMulti(InputArray img, InputArray points, std::vector& decoded_info, + OutputArrayOfArrays straight_code) const { + CV_Assert(p); + return p->decodeMulti(img, points, decoded_info, straight_code); +} + +bool GraphicalCodeDetector::detectAndDecodeMulti(InputArray img, std::vector& decoded_info, OutputArray points, + OutputArrayOfArrays straight_code) const { + CV_Assert(p); + return p->detectAndDecodeMulti(img, decoded_info, points, straight_code); +} + +} diff --git a/modules/objdetect/src/graphical_code_detector_impl.hpp b/modules/objdetect/src/graphical_code_detector_impl.hpp new file mode 100644 index 0000000000..76429222ff --- /dev/null +++ b/modules/objdetect/src/graphical_code_detector_impl.hpp @@ -0,0 +1,25 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html +#ifndef OPENCV_OBJDETECT_GRAPHICAL_CODE_DETECTOR_IMPL_HPP +#define OPENCV_OBJDETECT_GRAPHICAL_CODE_DETECTOR_IMPL_HPP + +#include + +namespace cv { + +struct GraphicalCodeDetector::Impl { + virtual ~Impl() {} + virtual bool detect(InputArray img, OutputArray points) const = 0; + virtual std::string decode(InputArray img, InputArray points, OutputArray straight_code) const = 0; + virtual std::string detectAndDecode(InputArray img, OutputArray points, OutputArray straight_code) const = 0; + virtual bool detectMulti(InputArray img, OutputArray points) const = 0; + virtual bool decodeMulti(InputArray img, InputArray points, std::vector& decoded_info, + OutputArrayOfArrays straight_code) const = 0; + virtual bool detectAndDecodeMulti(InputArray img, std::vector& decoded_info, + OutputArray points, OutputArrayOfArrays straight_code) const = 0; +}; + +} + +#endif \ No newline at end of file diff --git a/modules/objdetect/src/qrcode.cpp b/modules/objdetect/src/qrcode.cpp index 18b2650d99..9f64c64462 100644 --- a/modules/objdetect/src/qrcode.cpp +++ b/modules/objdetect/src/qrcode.cpp @@ -9,6 +9,7 @@ #include "opencv2/objdetect.hpp" #include "opencv2/calib3d.hpp" #include +#include "graphical_code_detector_impl.hpp" #ifdef HAVE_QUIRC #include "quirc.h" @@ -950,53 +951,7 @@ vector QRDetect::getQuadrilateral(vector angle_list) return result_angle_list; } -struct QRCodeDetectorBase::Impl { - virtual ~Impl() {} - virtual bool detect(InputArray img, OutputArray points) const = 0; - virtual std::string decode(InputArray img, InputArray points, OutputArray straight_qrcode) const = 0; - virtual std::string detectAndDecode(InputArray img, OutputArray points, OutputArray straight_qrcode) const = 0; - virtual bool detectMulti(InputArray img, OutputArray points) const = 0; - virtual bool decodeMulti(InputArray img, InputArray points, std::vector& decoded_info, - OutputArrayOfArrays straight_qrcode) const = 0; - virtual bool detectAndDecodeMulti(InputArray img, std::vector& decoded_info, OutputArray points, - OutputArrayOfArrays straight_qrcode) const = 0; -}; - -QRCodeDetectorBase::QRCodeDetectorBase() {} - -bool QRCodeDetectorBase::detect(InputArray img, OutputArray points) const { - CV_Assert(p); - return p->detect(img, points); -} - -std::string QRCodeDetectorBase::decode(InputArray img, InputArray points, OutputArray straight_qrcode) const { - CV_Assert(p); - return p->decode(img, points, straight_qrcode); -} - -std::string QRCodeDetectorBase::detectAndDecode(InputArray img, OutputArray points, OutputArray straight_qrcode) const { - CV_Assert(p); - return p->detectAndDecode(img, points, straight_qrcode); -} - -bool QRCodeDetectorBase::detectMulti(InputArray img, OutputArray points) const { - CV_Assert(p); - return p->detectMulti(img, points); -} - -bool QRCodeDetectorBase::decodeMulti(InputArray img, InputArray points, std::vector& decoded_info, - OutputArrayOfArrays straight_qrcode) const { - CV_Assert(p); - return p->decodeMulti(img, points, decoded_info, straight_qrcode); -} - -bool QRCodeDetectorBase::detectAndDecodeMulti(InputArray img, std::vector& decoded_info, - OutputArray points, OutputArrayOfArrays straight_qrcode) const { - CV_Assert(p); - return p->detectAndDecodeMulti(img, decoded_info, points, straight_qrcode); -} - -struct ImplContour : public QRCodeDetectorBase::Impl +struct ImplContour : public GraphicalCodeDetector::Impl { public: ImplContour(): epsX(0.2), epsY(0.1) {} diff --git a/modules/objdetect/test/test_qrcode.cpp b/modules/objdetect/test/test_qrcode.cpp index 609cc6dd2e..5e6ec6faf5 100644 --- a/modules/objdetect/test/test_qrcode.cpp +++ b/modules/objdetect/test/test_qrcode.cpp @@ -369,7 +369,7 @@ TEST_P(Objdetect_QRCode_Multi, regression) ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; if (disabled_samples.find({name_current_image, method}) != disabled_samples.end()) throw SkipTestException(name_current_image + " is disabled sample for method " + method); - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } @@ -427,7 +427,7 @@ TEST_P(Objdetect_QRCode_detectMulti, detect_regression_16961) Mat src = imread(image_path); ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } @@ -450,7 +450,7 @@ TEST_P(Objdetect_QRCode_detectAndDecodeMulti, check_output_parameters_type_19363 Mat src = imread(image_path); ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; #ifdef HAVE_QUIRC - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } @@ -619,7 +619,7 @@ TEST_P(Objdetect_QRCode_detectAndDecodeMulti, decode_9_qrcodes_version7) std::string image_path = findDataFile(root + name_current_image); Mat src = imread(image_path); const std::string method = GetParam(); - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (method == "aruco_based") { qrcode = QRCodeDetectorAruco(); } diff --git a/samples/cpp/qrcode.cpp b/samples/cpp/qrcode.cpp index 84ef621543..6b914f78ef 100644 --- a/samples/cpp/qrcode.cpp +++ b/samples/cpp/qrcode.cpp @@ -160,7 +160,7 @@ void drawQRCodeResults(Mat& frame, const vector& corners, const vector& corners, vector& decode_info // +global: bool g_modeMultiQR, bool g_detectOnly ) @@ -194,7 +194,7 @@ void runQR( } static -double processQRCodeDetection(const QRCodeDetectorBase& qrcode, const Mat& input, Mat& result, vector& corners) +double processQRCodeDetection(const GraphicalCodeDetector& qrcode, const Mat& input, Mat& result, vector& corners) { if (input.channels() == 1) cvtColor(input, result, COLOR_GRAY2BGR); @@ -232,7 +232,7 @@ int liveQRCodeDetect() cout << "Press 'd' to switch between decoder and detector" << endl; cout << "Press ' ' (space) to save result into images" << endl; cout << "Press 'ESC' to exit" << endl; - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (g_useArucoBased) qrcode = QRCodeDetectorAruco(); @@ -315,7 +315,7 @@ int imageQRCodeDetect(const string& in_file) << " on image: " << input.size() << " (" << typeToString(input.type()) << ")" << endl; - QRCodeDetectorBase qrcode = QRCodeDetector(); + GraphicalCodeDetector qrcode = QRCodeDetector(); if (g_useArucoBased) qrcode = QRCodeDetectorAruco();