From a08b1b656630c561327920b6034647aef370f6bc Mon Sep 17 00:00:00 2001 From: Adrian Kretz Date: Mon, 21 Apr 2025 16:40:33 +0200 Subject: [PATCH] Merge pull request #27244 from akretz:fix_issue_27183 Fix QR code encoder with autoversion #27244 The autodetected version is not honored in the `QRCodeEncoderImpl::encode*` methods. This fixes #27183 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/objdetect/src/qrcode_encoder.cpp | 2 ++ modules/objdetect/test/test_qrcode_encode.cpp | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/modules/objdetect/src/qrcode_encoder.cpp b/modules/objdetect/src/qrcode_encoder.cpp index d1c05d2525..14b51c254d 100644 --- a/modules/objdetect/src/qrcode_encoder.cpp +++ b/modules/objdetect/src/qrcode_encoder.cpp @@ -397,7 +397,9 @@ void QRCodeEncoderImpl::generateQR(const std::string &input) original = Mat(Size(version_size, version_size), CV_8UC1, Scalar(255)); masked_data = original.clone(); Mat qrcode = masked_data.clone(); + std::swap(version_level, tmp_version_level); generatingProcess(input_info, qrcode); + std::swap(version_level, tmp_version_level); final_qrcodes.push_back(qrcode); } } diff --git a/modules/objdetect/test/test_qrcode_encode.cpp b/modules/objdetect/test/test_qrcode_encode.cpp index 87142e4690..f6cf1c069f 100644 --- a/modules/objdetect/test/test_qrcode_encode.cpp +++ b/modules/objdetect/test/test_qrcode_encode.cpp @@ -590,4 +590,39 @@ INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_decoding, testing::ValuesIn(std:: {"err_correct_2L.png", "Version 2 QR Code Test Image"}, })); +TEST(Objdetect_QRCode_Encode_Decode_Long_Text, regression_issue27183) +{ + const int len = 135; + Ptr encoder = QRCodeEncoder::create(); + + std::string input; + input.resize(len); + cv::randu(Mat(1, len, CV_8U, &input[0]), 'a', 'z' + 1); + Mat qrcode; + encoder->encode(input, qrcode); + + std::vector corners(4); + corners[0] = Point2f(border_width, border_width); + corners[1] = Point2f(qrcode.cols * 1.0f - border_width, border_width); + corners[2] = Point2f(qrcode.cols * 1.0f - border_width, qrcode.rows * 1.0f - border_width); + corners[3] = Point2f(border_width, qrcode.rows * 1.0f - border_width); + + Mat resized_src; + resize(qrcode, resized_src, fixed_size, 0, 0, INTER_AREA); + float width_ratio = resized_src.cols * 1.0f / qrcode.cols; + float height_ratio = resized_src.rows * 1.0f / qrcode.rows; + for(size_t j = 0; j < corners.size(); j++) + { + corners[j].x = corners[j].x * width_ratio; + corners[j].y = corners[j].y * height_ratio; + } + + QRCodeDetector detector; + cv::String decoded_msg; + Mat straight_barcode; + EXPECT_NO_THROW(decoded_msg = detector.decode(resized_src, corners, straight_barcode)); + ASSERT_FALSE(straight_barcode.empty()); + EXPECT_EQ(input, decoded_msg); +} + }} // namespace