Skip to content

Consider QRCode ECI encoding#24426

Merged
asmorkalov merged 13 commits intoopencv:4.xfrom
dkurt:qrcode_eci_encoding
Jun 19, 2025
Merged

Consider QRCode ECI encoding#24426
asmorkalov merged 13 commits intoopencv:4.xfrom
dkurt:qrcode_eci_encoding

Conversation

@dkurt
Copy link
Copy Markdown
Member

@dkurt dkurt commented Oct 18, 2023

Pull Request Readiness Checklist

related: #24350 (review)

  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:

    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:

    std::string input_infos[testing_versions] = {"\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8a\x45", // "Hello World" in Japanese

    test

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • 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
  • The PR is proposed to the proper branch
  • There is a reference to the original bug report and related work
  • 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

@dkurt dkurt changed the title Qrcode eci encoding Consider QRCode ECI encoding Oct 18, 2023
@opencv-alalek
Copy link
Copy Markdown
Contributor

opencv-alalek commented Oct 18, 2023

How did you get the sample QR in PR's description?

Why is it differ from test data https://github.com/opencv/opencv_extra/blob/4.x/testdata/cv/qrcode/kanji.jpg ?

Which variant is correct?


One more example from Internet: https://www.htmlelements.com/docs/images/qrcode-kanji.png

@opencv-alalek
Copy link
Copy Markdown
Contributor

print(text)

API should not return string for such cases.
New API should return some kind of bytes buffer. It is a caller responsibility to properly apply "Shift-JIS" encoding.

In case of Python it could be:

>>> type(b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8aE')
<class 'bytes'>

Final string should be received through .decode() call:

>>> b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8aE'.decode('shift-jis')
'こんにちは世界'

(like .decode('utf-8))


Kanji mode can only encode double-byte Shift JIS characters whose bytes are in the ranges 0x8140 to 0x9FFC and 0xE040 to 0xEBBF (hexadecimal).

Ref: https://www.thonky.com/qr-code-tutorial/kanji-mode-encoding

Kanji input and output must have "Shift-JIS" encoding (not a UTF-8 string / OpenCV string anymore).

@dkurt
Copy link
Copy Markdown
Member Author

dkurt commented Oct 19, 2023

@opencv-alalek, https://github.com/opencv/opencv_extra/blob/4.x/testdata/cv/qrcode/kanji.jpg is not a valid Kanji QRCode (encoded in Byte mode).

A sample from internet cannot be detected directly, but after removing a text under the code it worked:

img = cv.imread("qrcode-kanji.png")
detect = cv.QRCodeDetector()
text, points, straight_qrcode = detect.detectAndDecode(img)
print(text)
print(detect.getEncoding(), cv.QRCodeEncoder_ECI_SHIFT_JIS)
print(text.encode("shift-jis"))
こんにちは世界
20 20
b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8aE'

image

New API should return some kind of bytes buffer. It is a caller responsibility to properly apply "Shift-JIS" encoding.

Under new API do you mean a separate naming like detectAndDecodeBytes?

@asmorkalov
Copy link
Copy Markdown
Contributor

@dkurt Is there a chance to finish it in mean time?

@dkurt
Copy link
Copy Markdown
Member Author

dkurt commented May 12, 2025

@asmorkalov, yes, let me refresh it.

@dkurt dkurt force-pushed the qrcode_eci_encoding branch from f00145e to efccf18 Compare May 30, 2025 07:37
@dkurt dkurt marked this pull request as ready for review May 31, 2025 05:52
@asmorkalov asmorkalov self-requested a review June 1, 2025 12:02
@asmorkalov asmorkalov removed the RFC label Jun 1, 2025
@asmorkalov asmorkalov added this to the 4.12.0 milestone Jun 1, 2025
Copy link
Copy Markdown
Contributor

@asmorkalov asmorkalov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java bindings are not covered also.

@dkurt dkurt marked this pull request as draft June 2, 2025 10:40
@dkurt
Copy link
Copy Markdown
Member Author

dkurt commented Jun 2, 2025

@asmorkalov added detectAndDecodeBytes in Java manually, but I wanted to cover it by a generic binginds parser, need some time to update PR.

@dkurt dkurt force-pushed the qrcode_eci_encoding branch from 30d892e to e527110 Compare June 3, 2025 11:59
@dkurt dkurt force-pushed the qrcode_eci_encoding branch from e527110 to 30fc9ed Compare June 3, 2025 12:04
Comment on lines +77 to +81
#ifdef OPENCV_BINDINGS_PARSER
CV_WRAP_AS(detectAndDecodeBytes) NativeByteArray detectAndDecode(InputArray img, OutputArray points = noArray(),
OutputArray straight_code = noArray()) const;
CV_WRAP_AS(decodeBytes) NativeByteArray decode(InputArray img, InputArray points, OutputArray straight_code = noArray()) const;
#endif
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java bindings use just cv::Mat for it. There is MatOfBytes specialization. M.b. reuse it too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In such way user should call an extra method:

MatOfByte output = detector.detectAndDecodeBytes(qrcode);
new String(output.toArray(), "Shift_JIS"));

@dkurt dkurt force-pushed the qrcode_eci_encoding branch from 1bc05b2 to 901d5b6 Compare June 5, 2025 06:30
@dkurt dkurt marked this pull request as ready for review June 5, 2025 10:13
@asmorkalov asmorkalov self-assigned this Jun 19, 2025
@asmorkalov asmorkalov merged commit 1c53fd3 into opencv:4.x Jun 19, 2025
28 checks passed
@asmorkalov asmorkalov mentioned this pull request Jul 21, 2025
D00E pushed a commit to D00E/opencv that referenced this pull request Sep 19, 2025
Consider QRCode ECI encoding opencv#24426

### Pull Request Readiness Checklist

related: opencv#24350 (review)

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants