mchehab / zbar

ZBar is an open source software suite for reading bar codes from various sources, including webcams. As its development stopped in 2012, I took the task of keeping it updated with the V4L2 API. This is the main repository for it. There's a clone at at LinuxTV.org, and another one at gitlab.
https://linuxtv.org/downloads/zbar/
GNU Lesser General Public License v2.1
1k stars 205 forks source link

Fail to see QR code other readers handle #65

Open petterreinholdtsen opened 5 years ago

petterreinholdtsen commented 5 years ago

Attached is a image with a QR code where zbar failed to see it, while smart phone readers are able to read it. Is there some way to get zbar to recognize it too?

DSC00028

matheusmoreira commented 5 years ago

I was able to reproduce this issue with zbarimg 0.23 as well as the master branch.

$ zbarimg --version
0.23
$ zbarimg -Sdisable -Sqr.enable 65.jpeg 2>&1 | grep WARNING
WARNING: barcode data was not detected in some image(s)
$ zbar/zbarimg/zbarimg -Sdisable -Sqr.enable 65.jpeg 2>&1 | grep WARNING
WARNING: barcode data was not detected in some image(s)

The QR decoding code has lots of TODO comments. Perhaps one of these improvements could fix this issue. I'm not knowledgeable enough to implement these improvements.

jose1711 commented 4 years ago

here's another such code written by qrencode. it can by read by neoreader on android just fine.

qr_code

jose1711 commented 4 years ago

here's a way to find problematic qr codes. so far i was able to read them all using neoreader on android.

#!/bin/bash
# level = L M Q H
level=Q

while :
do
  string_orig=$(base64 -w0 /dev/urandom | head -c 140)
  echo "== start of text before encoding =="
  echo "${string_orig}"
  echo "== end of text before encoding =="
  echo "${string_orig}" | qrencode -c -l "${level}" -o qr_code.png
  # degrading quality on purpose
  convert qr_code.png -resize 120 qr_code.jpg
  string_decoded=$(zbarimg --raw qr_code.jpg 2>/dev/null)
  if [ "${string_orig}" != "${string_decoded}" ]
  then
    echo "text after encoding: ${string_decoded}"
    echo "mismatch!"
    break
  else
    echo "OK"
  fi
done

geeqie qr_code.jpg

strangely zbarimg looks to work much better with the lowest error correction level (L), all other levels produced mismatches within a few seconds.

jose1711 commented 4 years ago

here's a modification that encodes to all 4 levels at once:

#!/bin/bash

while :
do
  string_orig=$(base64 -w0 /dev/urandom | head -c 140)
  echo "== start of text before encoding =="
  echo "${string_orig}"
  echo "== end of text before encoding =="
  for level in L M Q H
  do
    echo "${string_orig}" | qrencode -c -l "${level}" -o qr_code_${level}.png
    convert qr_code_${level}.png -resize 120 qr_code_${level}.jpg
  done
  for level in L M Q H
  do
    string_decoded=$(zbarimg --raw qr_code_${level}.jpg 2>/dev/null)
    if [ "${string_orig}" != "${string_decoded}" ]
    then
      echo "text after encoding: ${string_decoded}"
      echo "level ${level} - mismatch!"
      break 2
    else
      echo "level ${level} - OK"
    fi
  done
done

geeqie qr_code_${level}.jpg

again it may be easily observed how higher levels are usually the ones having more issues.

jose1711 commented 4 years ago

fwiw after editing in gimp - playing with contrast, levels, some rotation and color threshold i was able to modify the original image so that zbarimg was able to read the code. obrázok

bitcoinhodler commented 4 years ago

again it may be easily observed how higher levels are usually the ones having more issues.

At first I found this disturbing: higher levels of error correction lead to more decoding errors?

But when I tried this, I observed that the mismatches detected by this script fell into only two categories:

  1. Extra barcodes erroneously detected, in addition to the QR code. (Easy solution: restrict zbarimg to search only for QR codes.)
  2. No barcodes at all detected.

I did not observe any case where the QR was detected but decoded data did not match the original.

I also realized: higher error correction also leads to larger QR codes. And your test script is resizing all PNGs down to the same 120 pixels. Which means the QR codes with higher error correction end up with smaller dots, so it makes sense that zbar would have more trouble detecting the code.

Conclusion: while the original image in this issue is still a problem, I don't believe @jose1711 has discovered anything unexpected or concerning.

maslick commented 2 years ago

I was able to decode all of the images you provided with my OSS project named Koder. It is based on zbar 0.23.90 (compiled into WebAssembly). You can check out the demo here: https://qr.maslick.tech

petterreinholdtsen commented 2 years ago

[Pavel Maslov]

I was able to decode all of the images you provided with my OSS project named Koder. It is based on zbar 0.23.90 (compiled into WebAssembly). You can check out the demo here: https://qr.maslick.tech

Perhaps you can provide patches for libzbar to get it to recognize these too? What was wrong?

-- Happy hacking Petter Reinholdtsen

maslick commented 2 years ago

@petterreinholdtsen I haven't changed anything - zbar lib was used as is. My guess is that with Koder you scan and decode images in real time (e.g. 4 times a sec) at different angles, zoom and light conditions. Which gives you higher chances in decoding the QR code.

petterreinholdtsen commented 2 years ago

[Pavel Maslov]

@petterreinholdtsen I haven't changed anything - zbar lib was used as is. My guess is that with Koder you scan and decode images in real time (e.g. 4 times a sec) at different angles, zoom and light conditions. Which gives you higher chances in decoding the QR code.

Aha. I assumed it was able to handle the specific images mentioned in this request, based on your messages.

-- Happy hacking Petter Reinholdtsen