1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge pull request #24426 from dkurt:qrcode_eci_encoding

Consider QRCode ECI encoding #24426

### Pull Request Readiness Checklist

related: https://github.com/opencv/opencv/pull/24350#pullrequestreview-1661658421

1. Add `getEncoding` method to obtain ECI number
2. Add `detectAndDecodeBytes`, `decodeBytes`, `decodeBytesMulti`, `detectAndDecodeBytesMulti` methods in Python (return `bytes`) and Java (return `byte[]`)
3. Allow Python bytes to std::string conversion in general and add `encode(byte[] encoded_info, Mat qrcode)` in Java


    Python example with Kanji encoding:
    ```python
    img = cv.imread("test.png")
    detect = cv.QRCodeDetector()
    data, points, straight_qrcode = detect.detectAndDecodeBytes(img)
    print(data)
    print(detect.getEncoding(), cv.QRCodeEncoder_ECI_SHIFT_JIS)
    print(data.decode("shift-jis"))
    ```
    ```
    b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8aE'
    20 20
    こんにちは世界
    ```

    source: https://github.com/opencv/opencv/blob/ba4d6c859d21536f84e0328c16f4cc3e96bf3065/modules/objdetect/test/test_qrcode_encode.cpp#L332

    ![test](https://github.com/opencv/opencv/assets/25801568/0b5eefa8-918a-4c42-9acb-830f23c0ea9f)


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.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Dmitry Kurtaev
2025-06-19 10:12:15 +03:00
committed by GitHub
parent 210203090e
commit 1c53fd3777
14 changed files with 250 additions and 9 deletions
+21 -6
View File
@@ -963,6 +963,7 @@ public:
double epsX, epsY;
mutable vector<vector<Point2f>> alignmentMarkers;
mutable vector<Point2f> updateQrCorners;
mutable vector<QRCodeEncoder::ECIEncodings> encodings;
bool useAlignmentMarkers = true;
bool detect(InputArray in, OutputArray points) const override;
@@ -978,6 +979,8 @@ public:
String decodeCurved(InputArray in, InputArray points, OutputArray straight_qrcode);
std::string detectAndDecodeCurved(InputArray in, OutputArray points, OutputArray straight_qrcode);
QRCodeEncoder::ECIEncodings getEncoding(int codeIdx);
};
QRCodeDetector::QRCodeDetector() {
@@ -994,6 +997,13 @@ QRCodeDetector& QRCodeDetector::setEpsY(double epsY) {
return *this;
}
QRCodeEncoder::ECIEncodings QRCodeDetector::getEncoding(int codeIdx) {
auto& encodings = std::dynamic_pointer_cast<ImplContour>(p)->encodings;
CV_Assert(codeIdx >= 0);
CV_Assert(codeIdx < static_cast<int>(encodings.size()));
return encodings[codeIdx];
}
bool ImplContour::detect(InputArray in, OutputArray points) const
{
Mat inarr;
@@ -1035,6 +1045,8 @@ public:
uint8_t total_num = 1;
} structure_info;
QRCodeEncoder::ECIEncodings eci;
protected:
double getNumModules();
Mat getHomography() {
@@ -2802,7 +2814,6 @@ static std::string encodeUTF8_bytesarray(const uint8_t* str, const size_t size)
bool QRDecode::decodingProcess()
{
QRCodeEncoder::ECIEncodings eci;
const uint8_t* payload;
size_t payload_len;
#ifdef HAVE_QUIRC
@@ -2895,7 +2906,7 @@ bool QRDecode::decodingProcess()
return true;
case QRCodeEncoder::EncodeMode::MODE_KANJI:
// FIXIT BUG: we must return UTF-8 compatible string
CV_LOG_WARNING(NULL, "QR: Kanji is not supported properly");
eci = QRCodeEncoder::ECIEncodings::ECI_SHIFT_JIS;
result_info.assign((const char*)payload, payload_len);
return true;
case QRCodeEncoder::EncodeMode::MODE_ECI:
@@ -2966,6 +2977,7 @@ std::string ImplContour::decode(InputArray in, InputArray points, OutputArray st
alignmentMarkers = {qrdec.alignment_coords};
updateQrCorners = qrdec.getOriginalPoints();
}
encodings.resize(1, qrdec.eci);
return ok ? decoded_info : std::string();
}
@@ -2999,6 +3011,7 @@ String ImplContour::decodeCurved(InputArray in, InputArray points, OutputArray s
{
qrdec.getStraightBarcode().convertTo(straight_qrcode, CV_8UC1);
}
encodings.resize(1, qrdec.eci);
return ok ? decoded_info : std::string();
}
@@ -4111,20 +4124,22 @@ bool ImplContour::decodeMulti(
straight_qrcode.assign(tmp_straight_qrcodes);
}
decoded_info.clear();
decoded_info.resize(info.size());
encodings.resize(info.size());
for (size_t i = 0; i < info.size(); i++)
{
auto& decoder = qrdec[i];
encodings[i] = decoder.eci;
if (!decoder.isStructured())
{
decoded_info.push_back(info[i]);
decoded_info[i] = info[i];
continue;
}
// Store final message corresponding to 0-th code in a sequence.
if (decoder.structure_info.sequence_num != 0)
{
decoded_info.push_back("");
decoded_info[i] = "";
continue;
}
@@ -4145,7 +4160,7 @@ bool ImplContour::decodeMulti(
break;
}
}
decoded_info.push_back(decoded);
decoded_info[i] = decoded;
}
alignmentMarkers.resize(src_points.size());