From 14b5933e8c51abd50a11b545a8808b07ee51f0eb Mon Sep 17 00:00:00 2001 From: sitong lian <563052165@qq.com> Date: Tue, 6 Sep 2022 23:58:19 +0800 Subject: [PATCH 1/7] fix the bug that cannot detect multi qrcode when use_nn_detector is false --- .vscode/settings.json | 6 ++ .../samples/qrcode_example_without_nn.cpp | 67 +++++++++++++++++++ .../samples/qrcode_without_nn.py | 50 ++++++++++++++ modules/wechat_qrcode/src/decodermgr.cpp | 36 +++++----- modules/wechat_qrcode/src/decodermgr.hpp | 6 +- modules/wechat_qrcode/src/wechat_qrcode.cpp | 26 +++---- .../src/zxing/qrcode/qrcode_reader.cpp | 37 +++++----- .../src/zxing/qrcode/qrcode_reader.hpp | 6 +- modules/wechat_qrcode/src/zxing/reader.cpp | 2 +- modules/wechat_qrcode/src/zxing/reader.hpp | 4 +- 10 files changed, 186 insertions(+), 54 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 modules/wechat_qrcode/samples/qrcode_example_without_nn.cpp create mode 100644 modules/wechat_qrcode/samples/qrcode_without_nn.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..553817fbf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "cquery.cacheDirectory": "${workspaceFolder}/.vscode/cquery_cached_index/", + "files.associations": { + "vector": "cpp" + } +} \ No newline at end of file diff --git a/modules/wechat_qrcode/samples/qrcode_example_without_nn.cpp b/modules/wechat_qrcode/samples/qrcode_example_without_nn.cpp new file mode 100644 index 000000000..7428d0dd6 --- /dev/null +++ b/modules/wechat_qrcode/samples/qrcode_example_without_nn.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#include + +int main(int argc, char* argv[]) { + cout << endl << argv[0] << endl << endl; + cout << "A demo program of WeChat QRCode Detector: " << endl; + + Mat img; + int camIdx = -1; + if (argc > 1) { + bool live = strcmp(argv[1], "-camera") == 0; + if (live) { + camIdx = argc > 2 ? atoi(argv[2]) : 0; + } else { + img = imread(argv[1]); + } + } else { + cout << " Usage: " << argv[0] << " " << endl; + return 0; + } + // The model is downloaded to ${CMAKE_BINARY_DIR}/downloads/wechat_qrcode if cmake runs without warnings, + // otherwise you can download them from https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode. + Ptr detector; + + try { + detector = makePtr("", "", "", ""); + } catch (const std::exception& e) { + cout << + "\n---------------------------------------------------------------\n" + "Failed to initialize WeChatQRCode.\n" + "---------------------------------------------------------------\n"; + cout << e.what() << endl; + return 0; + } + string prevstr = ""; + vector points; + + if (camIdx < 0) { + auto res = detector->detectAndDecode(img, points); + for (const auto& t : res) cout << t << endl; + } else { + VideoCapture cap(camIdx); + for(;;) { + cap >> img; + if (img.empty()) + break; + auto res = detector->detectAndDecode(img, points); + for (const auto& t : res) { + if (t != prevstr) + cout << t << endl; + } + if (!res.empty()) + prevstr = res.back(); + imshow("image", img); + if (waitKey(30) >= 0) + break; + } + } + return 0; +} \ No newline at end of file diff --git a/modules/wechat_qrcode/samples/qrcode_without_nn.py b/modules/wechat_qrcode/samples/qrcode_without_nn.py new file mode 100644 index 000000000..9b8feb520 --- /dev/null +++ b/modules/wechat_qrcode/samples/qrcode_without_nn.py @@ -0,0 +1,50 @@ +import cv2 +import sys + +print(sys.argv[0]) +print('A demo program of WeChat QRCode Detector:') +camIdx = -1 +if len(sys.argv) > 1: + if sys.argv[1] == "-camera": + camIdx = int(sys.argv[2]) if len(sys.argv)>2 else 0 + img = cv2.imread(sys.argv[1]) +else: + print(" Usage: " + sys.argv[0] + " ") + exit(0) + +# For python API generator, it follows the template: {module_name}_{class_name}, +# so it is a little weird. +# The model is downloaded to ${CMAKE_BINARY_DIR}/downloads/wechat_qrcode if cmake runs without warnings, +# otherwise you can download them from https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode. +try: + detector = cv2.wechat_qrcode_WeChatQRCode( + "", "", "", "") +except: + print("---------------------------------------------------------------") + print("Failed to initialize WeChatQRCode.") + print("---------------------------------------------------------------") + exit(0) + +prevstr = "" + +if camIdx < 0: + res, points = detector.detectAndDecode(img) + print(res,points) +else: + cap = cv2.VideoCapture(camIdx) + while True: + res, img = cap.read() + if img is None: + break + res, points = detector.detectAndDecode(img) + for t in res: + if t != prevstr: + print(t) + if res: + prevstr = res[-1] + cv2.imshow("image", img) + if cv2.waitKey(30) >= 0: + break + # When everything done, release the capture + cap.release() + cv2.destroyAllWindows() diff --git a/modules/wechat_qrcode/src/decodermgr.cpp b/modules/wechat_qrcode/src/decodermgr.cpp index d4b8edf6f..47a9ec775 100644 --- a/modules/wechat_qrcode/src/decodermgr.cpp +++ b/modules/wechat_qrcode/src/decodermgr.cpp @@ -18,7 +18,7 @@ using zxing::Result; using zxing::UnicomBlock; namespace cv { namespace wechat_qrcode { -int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector& points) { +int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, vector& results, vector>& zxing_points) { int width = src.cols; int height = src.rows; if (width <= 20 || height <= 20) @@ -28,7 +28,7 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, v zxing::ArrayRef scaled_img_zx = zxing::ArrayRef(new zxing::Array(scaled_img_data)); - zxing::Ref zx_result; + vector> zx_results; decode_hints_.setUseNNDetector(use_nn_detector); @@ -43,16 +43,20 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, v } else { source->reset(scaled_img_zx.data(), width, height); } - int ret = TryDecode(source, zx_result); + int ret = TryDecode(source, zx_results); if (!ret) { - result = zx_result->getText()->getText(); - auto result_points = zx_result->getResultPoints(); - for(int i = 0; i < result_points->size() / 4; i++) { - const int ind = i * 4; - for (int j = 1; j < 4; j++) - points.emplace_back(result_points[ind+j]->getX(), result_points[ind+j]->getY()); - - points.emplace_back(result_points[ind]->getX(), result_points[ind]->getY()); + for(unsigned int i=0; igetText()->getText()); + vector tmp_qr_points; + auto tmp_zx_points = zx_results[i]->getResultPoints(); + for(int i = 0; i < tmp_zx_points->size() / 4; i++) { + const int ind = i * 4; + for (int j = 1; j < 4; j++){ + tmp_qr_points.emplace_back(tmp_zx_points[ind+j]->getX(), tmp_zx_points[ind+j]->getY()); + } + tmp_qr_points.emplace_back(tmp_zx_points[ind]->getX(), tmp_zx_points[ind]->getY()); + } + zxing_points.push_back(tmp_qr_points); } return ret; } @@ -62,7 +66,7 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, v return -1; } -int DecoderMgr::TryDecode(Ref source, Ref& result) { +int DecoderMgr::TryDecode(Ref source, vector>& results) { int res = -1; string cell_result; @@ -71,17 +75,17 @@ int DecoderMgr::TryDecode(Ref source, Ref& result) { zxing::Ref binary_bitmap(new BinaryBitmap(binarizer)); binary_bitmap->m_poUnicomBlock = qbarUicomBlock_; - result = Decode(binary_bitmap, decode_hints_); - res = (result == NULL) ? 1 : 0; + results = Decode(binary_bitmap, decode_hints_); + res = (results.size() == 0) ? 1 : 0; if (res == 0) { - result->setBinaryMethod(int(binarizer_mgr_.GetCurBinarizer())); + results[0]->setBinaryMethod(int(binarizer_mgr_.GetCurBinarizer())); } return res; } -Ref DecoderMgr::Decode(Ref image, DecodeHints hints) { +vector> DecoderMgr::Decode(Ref image, DecodeHints hints) { return reader_->decode(image, hints); } } // namespace wechat_qrcode diff --git a/modules/wechat_qrcode/src/decodermgr.hpp b/modules/wechat_qrcode/src/decodermgr.hpp index c2f29dbe2..1e04203b2 100644 --- a/modules/wechat_qrcode/src/decodermgr.hpp +++ b/modules/wechat_qrcode/src/decodermgr.hpp @@ -26,7 +26,7 @@ public: DecoderMgr() { reader_ = new zxing::qrcode::QRCodeReader(); }; ~DecoderMgr(){}; - int decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector& points); + int decodeImage(cv::Mat src, bool use_nn_detector, vector& result, vector>& zxing_points); private: zxing::Ref qbarUicomBlock_; @@ -35,10 +35,10 @@ private: zxing::Ref reader_; BinarizerMgr binarizer_mgr_; - zxing::Ref Decode(zxing::Ref image, + vector> Decode(zxing::Ref image, zxing::DecodeHints hints); - int TryDecode(zxing::Ref source, zxing::Ref& result); + int TryDecode(zxing::Ref source, vector>& result); }; } // namespace wechat_qrcode diff --git a/modules/wechat_qrcode/src/wechat_qrcode.cpp b/modules/wechat_qrcode/src/wechat_qrcode.cpp index 3836ea467..596a72269 100644 --- a/modules/wechat_qrcode/src/wechat_qrcode.cpp +++ b/modules/wechat_qrcode/src/wechat_qrcode.cpp @@ -144,21 +144,23 @@ vector WeChatQRCode::Impl::decode(const Mat& img, vector& candidate super_resolution_model_->processImageScale(cropped_img, cur_scale, use_nn_sr_); string result; DecoderMgr decodemgr; - vector points_qr; - auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, result, points_qr); + vector> zxing_points; + auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, decode_results, zxing_points); if (ret == 0) { - for (auto&& pt: points_qr) { - pt /= cur_scale; - } + for(unsigned int i=0; i points_qr = zxing_points[i]; + for (auto&& pt: points_qr) { + pt /= cur_scale; + } - if (use_nn_detector_) - points_qr = aligner.warpBack(points_qr); - for (int i = 0; i < 4; ++i) { - point.at(i, 0) = points_qr[i].x; - point.at(i, 1) = points_qr[i].y; + if (use_nn_detector_) + points_qr = aligner.warpBack(points_qr); + for (int j = 0; j < 4; ++j) { + point.at(j, 0) = points_qr[j].x; + point.at(j, 1) = points_qr[j].y; + } + points.push_back(point); } - decode_results.push_back(result); - points.push_back(point); break; } } diff --git a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp index 64a6c08c9..c5b526263 100644 --- a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp +++ b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp @@ -34,33 +34,33 @@ QRCodeReader::QRCodeReader() : decoder_() { smoothMaxMultiple_ = 40; } -Ref QRCodeReader::decode(Ref image) { return decode(image, DecodeHints()); } +vector> QRCodeReader::decode(Ref image) { return decode(image, DecodeHints()); } -Ref QRCodeReader::decode(Ref image, DecodeHints hints) { +vector> QRCodeReader::decode(Ref image, DecodeHints hints) { // Binarize image using the Histogram Binarized method and be binarized ErrorHandler err_handler; + vector> result_list; Ref imageBitMatrix = image->getBlackMatrix(err_handler); - if (err_handler.ErrCode() || imageBitMatrix == NULL) return Ref(); + if (err_handler.ErrCode() || imageBitMatrix == NULL) return result_list; - Ref rst = decodeMore(image, imageBitMatrix, hints, err_handler); - if (err_handler.ErrCode() || rst == NULL) { + vector> rst = decodeMore(image, imageBitMatrix, hints, err_handler); + if (err_handler.ErrCode() || rst.empty()) { // black white mirro!!! Ref invertedMatrix = image->getInvertedMatrix(err_handler); - if (err_handler.ErrCode() || invertedMatrix == NULL) return Ref(); - Ref tmp_rst = decodeMore(image, invertedMatrix, hints, err_handler); - if (err_handler.ErrCode() || tmp_rst == NULL) return Ref(); - return tmp_rst; + if (err_handler.ErrCode() || invertedMatrix == NULL) return result_list; + vector> tmp_rst = decodeMore(image, invertedMatrix, hints, err_handler); + if (err_handler.ErrCode() || tmp_rst.empty()) return tmp_rst; } return rst; } -Ref QRCodeReader::decodeMore(Ref image, Ref imageBitMatrix, +vector> QRCodeReader::decodeMore(Ref image, Ref imageBitMatrix, DecodeHints hints, ErrorHandler &err_handler) { nowHints_ = hints; std::string ept; - - if (imageBitMatrix == NULL) return Ref(); + vector> result_list; + if (imageBitMatrix == NULL) return result_list; image->m_poUnicomBlock->Init(); image->m_poUnicomBlock->Reset(imageBitMatrix); @@ -88,7 +88,7 @@ Ref QRCodeReader::decodeMore(Ref image, Ref ima Ref patternInfo = detector->getFinderPatternInfo(i); setPatternFix(patternInfo->getPossibleFix()); if (patternInfo->getAnglePossibleFix() < 0.6 && i) continue; - + bool patternFoundFlag = false; int possibleAlignmentCount = 0; possibleAlignmentCount = detector->getPossibleAlignmentCount(i); if (possibleAlignmentCount < 0) continue; @@ -99,6 +99,7 @@ Ref QRCodeReader::decodeMore(Ref image, Ref ima vector needTryVariousDeimensions(possibleAlignmentCount, false); for (int j = 0; j < possibleAlignmentCount; j++) { + if (patternFoundFlag){break;} ArrayRef > points; err_handler.Reset(); Ref detectorResult = @@ -142,11 +143,12 @@ Ref QRCodeReader::decodeMore(Ref image, Ref ima decoderResult->getCharset(), decoderResult->getQRCodeVersion(), decoderResult->getEcLevel(), decoderResult->getCharsetMode())); setSuccFix(points); - - return result; + result_list.push_back(result); + patternFoundFlag = true; } // try different dimentions for (int j = 0; j < possibleAlignmentCount; j++) { + if (patternFoundFlag){break;} err_handler.Reset(); ArrayRef > points; if (needTryVariousDeimensions[j]) { @@ -188,13 +190,14 @@ Ref QRCodeReader::decodeMore(Ref image, Ref ima decoderResult->getEcLevel(), decoderResult->getCharsetMode())); setSuccFix(points); - return result; + result_list.push_back(result); + patternFoundFlag = true; } } } } } - return Ref(); + return result_list; } vector QRCodeReader::getPossibleDimentions(int detectDimension) { diff --git a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.hpp b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.hpp index bb0ccf61e..613286c2c 100644 --- a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.hpp +++ b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.hpp @@ -75,10 +75,10 @@ public: virtual ~QRCodeReader(); string name() override { return "qrcode"; } - Ref decode(Ref image) override; - Ref decode(Ref image, DecodeHints hints) override; + vector> decode(Ref image) override; + vector> decode(Ref image, DecodeHints hints) override; - Ref decodeMore(Ref image, Ref imageBitMatrix, + vector> decodeMore(Ref image, Ref imageBitMatrix, DecodeHints hints, ErrorHandler& err_handler); private: diff --git a/modules/wechat_qrcode/src/zxing/reader.cpp b/modules/wechat_qrcode/src/zxing/reader.cpp index da54ccb6b..7fa6b65f9 100644 --- a/modules/wechat_qrcode/src/zxing/reader.cpp +++ b/modules/wechat_qrcode/src/zxing/reader.cpp @@ -14,7 +14,7 @@ namespace zxing { Reader::~Reader() {} -Ref Reader::decode(Ref image) { return decode(image, DecodeHints()); } +vector> Reader::decode(Ref image) { return decode(image, DecodeHints()); } unsigned int Reader::getDecodeID() { return 0; } diff --git a/modules/wechat_qrcode/src/zxing/reader.hpp b/modules/wechat_qrcode/src/zxing/reader.hpp index cb3e7eaf3..e958013ca 100644 --- a/modules/wechat_qrcode/src/zxing/reader.hpp +++ b/modules/wechat_qrcode/src/zxing/reader.hpp @@ -23,8 +23,8 @@ protected: Reader() {} public: - virtual Ref decode(Ref image); - virtual Ref decode(Ref image, DecodeHints hints) = 0; + virtual vector> decode(Ref image); + virtual vector> decode(Ref image, DecodeHints hints) = 0; virtual ~Reader(); virtual string name(); From f30e80e026074fcbf190acd47270bf3fcf7fcb00 Mon Sep 17 00:00:00 2001 From: sitong lian <563052165@qq.com> Date: Wed, 7 Sep 2022 00:03:50 +0800 Subject: [PATCH 2/7] fix the bug that cannot detect multi qrcode when use_nn_detector is false --- .vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 553817fbf..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cquery.cacheDirectory": "${workspaceFolder}/.vscode/cquery_cached_index/", - "files.associations": { - "vector": "cpp" - } -} \ No newline at end of file From 4c2283fa9952c241584936d64103cb059910408a Mon Sep 17 00:00:00 2001 From: sitong lian <563052165@qq.com> Date: Wed, 7 Sep 2022 00:19:14 +0800 Subject: [PATCH 3/7] fix the bug that cannot detect multi qrcode when use_nn_detector is false --- .vscode/settings.json | 3 +++ modules/wechat_qrcode/src/decodermgr.cpp | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..f5d622ff1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cquery.cacheDirectory": "${workspaceFolder}/.vscode/cquery_cached_index/" +} \ No newline at end of file diff --git a/modules/wechat_qrcode/src/decodermgr.cpp b/modules/wechat_qrcode/src/decodermgr.cpp index 47a9ec775..9f8ad419a 100644 --- a/modules/wechat_qrcode/src/decodermgr.cpp +++ b/modules/wechat_qrcode/src/decodermgr.cpp @@ -45,10 +45,10 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, vector& r } int ret = TryDecode(source, zx_results); if (!ret) { - for(unsigned int i=0; igetText()->getText()); + for(unsigned int k=0; kgetText()->getText()); vector tmp_qr_points; - auto tmp_zx_points = zx_results[i]->getResultPoints(); + auto tmp_zx_points = zx_results[k]->getResultPoints(); for(int i = 0; i < tmp_zx_points->size() / 4; i++) { const int ind = i * 4; for (int j = 1; j < 4; j++){ From 5d9067933e59436f48066bcb9326b8972a68ae74 Mon Sep 17 00:00:00 2001 From: sitong lian <563052165@qq.com> Date: Wed, 7 Sep 2022 00:22:33 +0800 Subject: [PATCH 4/7] fix the bug that cannot detect multi qrcode when use_nn_detector is false --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f5d622ff1..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cquery.cacheDirectory": "${workspaceFolder}/.vscode/cquery_cached_index/" -} \ No newline at end of file From 14157b140ea83777dede37cd7dbeb75c64fc7a7a Mon Sep 17 00:00:00 2001 From: AleksandrPanov Date: Mon, 19 Sep 2022 23:13:05 +0300 Subject: [PATCH 5/7] fixed duplicate corners and style --- modules/wechat_qrcode/src/decodermgr.cpp | 6 ++--- modules/wechat_qrcode/src/wechat_qrcode.cpp | 27 ++++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/modules/wechat_qrcode/src/decodermgr.cpp b/modules/wechat_qrcode/src/decodermgr.cpp index 9f8ad419a..1e93aa15c 100644 --- a/modules/wechat_qrcode/src/decodermgr.cpp +++ b/modules/wechat_qrcode/src/decodermgr.cpp @@ -45,14 +45,14 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, vector& r } int ret = TryDecode(source, zx_results); if (!ret) { - for(unsigned int k=0; kgetText()->getText()); vector tmp_qr_points; auto tmp_zx_points = zx_results[k]->getResultPoints(); - for(int i = 0; i < tmp_zx_points->size() / 4; i++) { + for (int i = 0; i < tmp_zx_points->size() / 4; i++) { const int ind = i * 4; for (int j = 1; j < 4; j++){ - tmp_qr_points.emplace_back(tmp_zx_points[ind+j]->getX(), tmp_zx_points[ind+j]->getY()); + tmp_qr_points.emplace_back(tmp_zx_points[ind + j]->getX(), tmp_zx_points[ind + j]->getY()); } tmp_qr_points.emplace_back(tmp_zx_points[ind]->getX(), tmp_zx_points[ind]->getY()); } diff --git a/modules/wechat_qrcode/src/wechat_qrcode.cpp b/modules/wechat_qrcode/src/wechat_qrcode.cpp index 596a72269..f4bec7c2b 100644 --- a/modules/wechat_qrcode/src/wechat_qrcode.cpp +++ b/modules/wechat_qrcode/src/wechat_qrcode.cpp @@ -144,10 +144,10 @@ vector WeChatQRCode::Impl::decode(const Mat& img, vector& candidate super_resolution_model_->processImageScale(cropped_img, cur_scale, use_nn_sr_); string result; DecoderMgr decodemgr; - vector> zxing_points; + vector> zxing_points, check_points; auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, decode_results, zxing_points); if (ret == 0) { - for(unsigned int i=0; i points_qr = zxing_points[i]; for (auto&& pt: points_qr) { pt /= cur_scale; @@ -159,7 +159,28 @@ vector WeChatQRCode::Impl::decode(const Mat& img, vector& candidate point.at(j, 0) = points_qr[j].x; point.at(j, 1) = points_qr[j].y; } - points.push_back(point); + // try to find duplicate qr corners + bool isDuplicate = false; + for (const auto &tmp_points: check_points) { + const float eps = 10.f; + for (size_t j = 0; j < tmp_points.size(); j++) { + if (abs(tmp_points[j].x - points_qr[j].x) < eps && + abs(tmp_points[j].y - points_qr[j].y) < eps) { + isDuplicate = true; + } + else { + isDuplicate = false; + break; + } + } + } + if (isDuplicate == false) { + points.push_back(point); + check_points.push_back(points_qr); + } + else { + decode_results.erase(decode_results.begin() + i, decode_results.begin() + i + 1); + } } break; } From cfcfd5f4114a6014d93345a82ea397c2cc1aeb40 Mon Sep 17 00:00:00 2001 From: AleksandrPanov Date: Mon, 19 Sep 2022 23:13:42 +0300 Subject: [PATCH 6/7] add multi detect test --- modules/wechat_qrcode/test/test_qrcode.cpp | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/modules/wechat_qrcode/test/test_qrcode.cpp b/modules/wechat_qrcode/test/test_qrcode.cpp index 49a34978a..d59932b81 100644 --- a/modules/wechat_qrcode/test/test_qrcode.cpp +++ b/modules/wechat_qrcode/test/test_qrcode.cpp @@ -408,5 +408,52 @@ TEST(Objdetect_QRCode_Tiny, regression) { ASSERT_EQ(expect_msg, decoded_info[0]); } + +typedef testing::TestWithParam Objdetect_QRCode_Easy_Multi; +TEST_P(Objdetect_QRCode_Easy_Multi, regression) { + string path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt, path_sr_caffemodel; + string model_path = GetParam(); + + if (!model_path.empty()) { + path_detect_prototxt = findDataFile(model_path + "/detect.prototxt", false); + path_detect_caffemodel = findDataFile(model_path + "/detect.caffemodel", false); + path_sr_prototxt = findDataFile(model_path + "/sr.prototxt", false); + path_sr_caffemodel = findDataFile(model_path + "/sr.caffemodel", false); + } + + auto detector = wechat_qrcode::WeChatQRCode(path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt, + path_sr_caffemodel); + + const cv::String expect_msg1 = "OpenCV1", expect_msg2 = "OpenCV2"; + QRCodeEncoder::Params params; + params.version = 4; // 33x33 + Ptr qrcode_enc = cv::QRCodeEncoder::create(params); + Mat qrImage1, qrImage2; + qrcode_enc->encode(expect_msg1, qrImage1); + qrcode_enc->encode(expect_msg2, qrImage2); + const int pixInBlob = 2; + const int offset = 14; + const int qr_size = (params.version - 1) * 4 + 21; + Mat tinyImage = Mat::zeros(qr_size*pixInBlob+offset, (qr_size*pixInBlob+offset)*2, CV_8UC1); + Size qrSize = Size(qrImage1.cols, qrImage1.rows); + + Mat roiImage = tinyImage(Rect((tinyImage.cols/2 - qrSize.width)/2, (tinyImage.rows - qrSize.height)/2, + qrSize.width, qrSize.height)); + cv::resize(qrImage1, roiImage, qrSize, 1., 1., INTER_NEAREST); + + roiImage = tinyImage(Rect((tinyImage.cols/2 - qrSize.width)/2+tinyImage.cols/2, (tinyImage.rows - qrSize.height)/2, + qrSize.width, qrSize.height)); + cv::resize(qrImage2, roiImage, qrSize, 1., 1., INTER_NEAREST); + + vector points; + auto decoded_info = detector.detectAndDecode(tinyImage, points); + ASSERT_EQ(2ull, decoded_info.size()); + ASSERT_TRUE((expect_msg1 == decoded_info[0] && expect_msg2 == decoded_info[1]) || + (expect_msg1 == decoded_info[1] && expect_msg2 == decoded_info[0])); +} + +std::string qrcode_model_path[] = {"", "dnn/wechat_2021-01"}; +INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Easy_Multi, testing::ValuesIn(qrcode_model_path)); + } // namespace } // namespace opencv_test From a3afb879cab6898a6be787ff6fd2f1cc04beb63f Mon Sep 17 00:00:00 2001 From: AleksandrPanov Date: Tue, 20 Sep 2022 11:37:53 +0300 Subject: [PATCH 7/7] add return for nn_detector --- modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp index c5b526263..b6c4c4f71 100644 --- a/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp +++ b/modules/wechat_qrcode/src/zxing/qrcode/qrcode_reader.cpp @@ -145,6 +145,9 @@ vector> QRCodeReader::decodeMore(Ref image, Ref> QRCodeReader::decodeMore(Ref image, Ref