question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BUG: Rect object returned by `decode` can be trivially wrong

See original GitHub issue

The rectangle object returned by the decode function is (completely) wrong whenever the found DataMatrix code is rotated. The problem is that the returned rectangle is always supposed to be upright when, in fact, libdtmx supports also rotated codes.

Examples with one upright and one rotated DataMatrix code:

  • direct call of dmtxread on the command line
(base) ➜  ~ dmtxread -n -v -N 1 12345_garbage.png        
--------------------------------------------------
       Matrix Size: 10 x 10
    Data Codewords: 3 (capacity 3)
   Error Codewords: 5
      Data Regions: 1 x 1
Interleaved Blocks: 1
    Rotation Angle: 0
          Corner 0: (1152.0, 1287.0)
          Corner 1: (1201.0, 1287.0)
          Corner 2: (1200.1, 1238.0)
          Corner 3: (1152.0, 1238.0)
--------------------------------------------------
12345

(base) ➜  ~ dmtxread -n -v -N 1 12345_garbage_rotated.png
--------------------------------------------------
       Matrix Size: 10 x 10
    Data Codewords: 3 (capacity 3)
   Error Codewords: 5
      Data Regions: 1 x 1
Interleaved Blocks: 1
    Rotation Angle: 319
          Corner 0: (1191.0, 1292.9)
          Corner 1: (1228.1, 1325.2)
          Corner 2: (1260.5, 1287.9)
          Corner 3: (1223.4, 1255.6)
--------------------------------------------------
12345
  • using pylibdtmx
(libdmtx) ➜  ~ ipython
Python 3.7.5 (default, Oct 25 2019, 15:51:11) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.9.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pylibdmtx.pylibdmtx import decode                                                                           

In [2]: from PIL import Image                                                                                            

In [3]: decode(Image.open("/home/gri/12345_garbage.png"), max_count=1)                                                   
Out[3]: [Decoded(data=b'12345', rect=Rect(left=1152, top=2220, width=48, height=49))]

In [4]: decode(Image.open("/home/gri/12345_garbage_rotated.png"), max_count=1)                                           
Out[4]: [Decoded(data=b'12345', rect=Rect(left=1191, top=2214, width=70, height=5))]

(Note how also width and height changed to totally incorrect values.)

The obvious solution would be to not return a tuple of left, top, width, and height coordinates, since they apply only to upright rectangles, but to return the coordinates of the four corners—as is done by the command line program.

So in these lines of the code all four points should be captured instead of only two ones.

Of course, such a change would break the interface as it is now. If you insist on returning an upright rectangle, it should at least be the upright bounding box of the DataMatrix code crop. But I would much prefer if the python version would just return the four corner points as the command line version does.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:3
  • Comments:14

github_iconTop GitHub Comments

2reactions
gauti1311commented, Feb 5, 2020

yes you can do by easily adding two more vectors e.g p00 = DmtxVector2() p11 = DmtxVector2(1.0, 1.0) p10 = DmtxVector2(1.0, 0.0) p01 = DmtxVector2(0.0, 1.0) dmtxMatrix3VMultiplyBy(p00, region.contents.fit2raw) dmtxMatrix3VMultiplyBy(p11, region.contents.fit2raw) dmtxMatrix3VMultiplyBy(p01, region.contents.fit2raw) dmtxMatrix3VMultiplyBy(p10, region.contents.fit2raw) x00 = int((shrink * p00.X) + 0.5) y00 = int((shrink * p00.Y) + 0.5) x11 = int((shrink * p11.X) + 0.5) y11 = int((shrink * p11.Y) + 0.5) x10 = int((shrink * p10.X) + 0.5) y10 = int((shrink * p10.Y) + 0.5) x01 = int((shrink * p01.X) + 0.5) y01 = int((shrink * p01.Y) + 0.5) return Decoded( string_at(msg.contents.output), #Rect2 = namedtuple(‘Rect’, ‘x00 y00 x01 y01 x10 y10 x11 y11’) Rect2(x00,y00,x01,y01,x10,y10,x11,y11)

I did its in my lib and it works well

1reaction
amackpcommented, Sep 29, 2022

Solved!

How did you solve it?

@GenericArt Not sure what @Gennadynemchin 's actual issue was, but I found that the when using @gauti1311 's solution to return 4 corners from the _decode_region, the y coordinate frame is flipped relative to the coordinate frame used by openCV images. You can simply subtract the input image’s height from the rectangle’s Y coordinates to get the proper pixel location.

cv_image = cv2.imread('/path/to/image.png')

results = pylibdmtx.decode(cv_image)

height, width, channels = cv_image.shape

for code in results:
    tl = (code.rect2.x01, height - code.rect2.y01)
    tr = (code.rect2.x11, height - code.rect2.y11)
    br = (code.rect2.x10, height - code.rect2.y10)
    bl = (code.rect2.x00, height - code.rect2.y00)
   
    # do something with rectangle... 

Read more comments on GitHub >

github_iconTop Results From Across the Web

tilepix package - github.com/bcvery1/tilepix - Go Packages
GetRect will return a pixel.Circle representation of this object relative to the map (the co-ordinates will match those as drawn in Tiled). If...
Read more >
Single versus double quotes in json loads in Python
Confusing one with the other can either lead to parse errors or subtle problems when decoding happened to succeed but the data has...
Read more >
Understanding and resolving MetaMask error codes
This guide outlines the most common and confusing MetaMask error codes to help you resolve errors for a smoother Web3 development ...
Read more >
Main objects — pikepdf 6.0.2.dev9+g25f0537 documentation
Returns a mapping that provides access to all files attached to this PDF. PDF supports attaching (or embedding, if you prefer) any other...
Read more >
Constructors, C++ FAQ
How can I handle a constructor that fails? What is the “Named Parameter Idiom”? Why am I getting an error after declaring a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found