zxing-cpp / zxing-cpp

C++ port of ZXing
Apache License 2.0
1.26k stars 400 forks source link

Solving errors when reading DataMatrix Codes #782

Open fabulous-fabio opened 5 months ago

fabulous-fabio commented 5 months ago

Hello, I'm currently working on a Project where I have to decode many small DataMatrixCodes. I'm using the python wrapper with a self built wheel using c++20. The Images have a relatively low resolution, but I can still read about half the codes. Unfortunately I encountered some problems: When scanning the rest of the codes, I eather encounter a ChecksumError or an FormatError.

I already tried to rescale the images but I still encounter the errors. When I read the codes with an App that is also using this library it reads the codes well. Does anybody know how I can achieve this? This Codes raises the following Error: ChecksumError @ DMDecoder.cpp:425

img_17 img_19

And this Codes raises the following Error: FormatError (Invalid matrix dimension) @ DMDecoder.cpp:399 img_13 img_12

Maybe someone can help me figure out how I have to manipulate the image to be able to read the codes.

Thank you a lot! Kind Regards

axxel commented 5 months ago

Your 4 images don't work because of a combination of 3 problems: 1) low resolution 2) background noise 3) over saturation (black dots are too thick)

They are very similar in nature. Do all your problematic images look like this?

I had some success in detecting them by doing: a) scale them up to 200%, then b) apply an optional dilate operation and c) perform a thresholding such that you get roughly the same amount of black and white pixels within the symbol. If your input is really so similar, you could do the latter by hand once and then use the same thresholding value for all your input.

Here are my results that work: #782-1 #782-3 #782-4

axxel commented 5 months ago

I forgot to ask: which app based on this library were you talking about?

fabulous-fabio commented 5 months ago

Thanks for your answer! What Kernel did you use for dilation?

I'll try it out and will let you know how it works.

The images are fairly similar because they are all from a bigger image and thus all have the same quality issues.

The app I use is calles Code Scan

Kind Regards

axxel commented 5 months ago

What Kernel did you use for dilation?

I simply used GIMP. I believe they use a 3x3 box kernel.

The app I use is calles Code Scan

I can't find it, can you provide a URL?

fabulous-fabio commented 4 months ago

Hey, glad to inform you that the provided Images work fairly well now.

The app mentioned is the following: https://apps.apple.com/de/app/code-scan-liest-jeden-qrcode/id1554812545

I still face some issues I hope you can help me with. The following codes fail to decode and I hope you can assist me with your valuable expertise:

img_12 img_9 img_8 img_7 img_6 img_5 img_4 img_2 img_0

Thanks for your help and the development of this very helpful library!

Kind regards

axxel commented 4 months ago

So you implemented the 3 steps I mentioned above in your application and it helps but the provided images still have issues?

With regards to why the mentioned iOS app works better: Let's ask the authors, maybe they can share their secret source? ;) @parallaxe @markusfisch

alexmanzer commented 4 months ago

We use a lot of "magic" here and, like any good magician, we are of course not allowed to reveal our tricks. 😅

Seriously: iOS itself offers barcode detection (via Vision and also in AVFoundation as MetaData of a camera image), which we use in combination with Zxing to enable the fastest possible recognition. iOS's own detectors also all run very efficiently on the GPU, which is why we get them very efficiently "for free". In addition, due to the high performance that iOS devices offer, we can also do some other tricks with the input images (e.g. scaling, inverting, enhance images, etc.) and have them recognized in parallel/alternating.

Therefore, a number of mechanisms are fired and ensure that the result is found in one of the countless images from your camera stream.

fabulous-fabio commented 4 months ago

So you implemented the 3 steps I mentioned above in your application and it helps but the provided images still have issues?

Exactly. A lot more Images work now, but somehow these images still don't.

fabulous-fabio commented 4 months ago

Does anybody have an Idea how to solve them? Kind regards

Eitol commented 1 month ago

The problem is occurring because neither of the 2 functions that search for the L pattern support this pattern being discontinuous. That's why it throws the error "FormatError (Invalid matrix dimension)".

The function must be modified to detect the L pattern with discontinuous lines.

static DetectorResult Scan(EdgeTracer& startTracer, std::array<DMRegressionLine, 4>& lines)

I'm going to try to do it (But I'm not an expert on this topic)

image