New issue 556 by Fitzpete: inverted codes
http://code.google.com/p/zxing/issues/detail?id=556
What steps will reproduce the problem?
1.Scanning an inverted Datamatrix code doesn't work, coding elements white
instead of black.
What is the expected output? What do you see instead?
not being recognized
What version of the product are you using? On what operating system?
3.5 on Froyo SGS
Please provide any additional information below.
Comment #1 on issue 556 by sro...@gmail.com: inverted codes
http://code.google.com/p/zxing/issues/detail?id=556
I read section 4.2 of the spec (ISO 16002) as saying that white-on-dark
decoding is optional. Nobody should be encoding it this way, in order to
maximize compatibility. It's trivial to support this, but, would waste
significant CPU cycles most of the time.
i understand this is not a bug but would it be possible to toogle this
maybe?
i am using inverted Datamatrix codes for marking glass by laser treatment.
The treated areas turn white subsequently.
How about a patch?
yep, that will do.
For the record, I've noted a few products in the wild that use
light-on-dark datamatrix codes. These are mostly in the realm of consumer
electronics, where the codes are printed directly onto black plastic.
Would it be possible to do a simple threshhold search (sample a small area
of "whitespace" around a potential code area) to determine if it should be
attempting an inverted scan? That'd possibly get rid of the wasted CPU time.
As QR codes are starting to appear in the wild more and more, designers are
going to try and incorporate the QR codes into their designs more to make
them visually appealing. Most people create codes, incorporate them into
their design (visually), and then try and scan the codes on the popular
phones to see if they actually work. Adding this feature would open up a
lot of design possibility.
(At the moment I've got my design hat on and I'm currently wishing right
now that inverted codes were supported, as my particular design is
light-on-dark.)
While I think this is a bad choice for the code creator, I like your
solution. Yes, it could try inverting the image and scanning if it sees
it's fairly dark on average. The concern is performance. Since codes are
almost never inverted, this will mean that 99.99% of the time this is just
wasting CPU cycles. If done cleverly I bet the sampling can be smart and
fast enough.
I myself am not looking to implement it but a clever patch could be just
fine.
That said, the Android 2.1+ version has an "invert" option that does the
inversion at the camera level so will at least let you scan these codes
with one small extra step, and at no overhead cost. That's a pretty decent
solution too.
What about using some kind of filter, to find contrast zones, and
processing the codes from there? That mean zxing will need a major rewrite,
but I guess it's a good approach.
The ISO specs say that inverted codes are optional. So the design choice
means some fraction of readers can read the code, versus 100%. Doesn't seem
like a good choice to me. The fact that the issue has come up here is why
it's a bad choice -- the reader for all Android phones doesn't support it.
I don't think supporting this automatically is a bad idea at all. The
problem is making 10,000 scans 1% worse in return for getting 1 scan right.
If the cost is small enough it's worth it. It is trivial to enable
otherwise.
I think detecting areas of high/low contrast is a pretty good idea. Better
still is to find a region of low chroma (U=V=0) -- that is,
black-and-white. The problem is again that these ideas cost more than
they're worth, or at least seem to in the past.
I understand the performance concerns and totally agree: as it stands at
the moment, making 10,000 scans 1% worse for 1 right scan is not good.
But the design choice (whether to publish a code inverted or not) is driven
by the available reader technology, not by the ISO specs. If it ends up
that 90% of all readers that a given designer and her friends tries can
handle inverted codes (iPhone and Android support would cover a lot of
cases) then they may decide to use an inverted code. This would therefore
increase the usefulness of it handling inverted codes by increasing the
number of published codes that are inverted.
So, I totally agree - with a low-cost way of checking to see if an inverted
scan is useful, this could be viable. To start, it could be slightly less
reliable, only engaging every 5th frame or something like that. If inverted
codes become popular, it could be made more reliable (and thereby slightly
more expensive).
True, but 90% of readers don't. I don't even think 10% do, but I have no
figures for that. I have never seen an inverted QR code in the wild either.
Still, it'd be nice to support.
How many clients use ZXING as their QRCode processing library?
I've used at least three different QR Code scanners for android (QR Droid,
Barcode Scanner, and Google Goggles) and all three fail QR codes where the
code data is lighter than its background.
This issue should be re-opened, or a new one opened in its stead. :( This
thread's activity again and again shows how relevant this feature is.
It remains a Bad Idea to encode inverted QR codes, and this thread is why.
Still, I can tell you that the "4.0" version of BS lets you scan inverted
codes with an option. You can try it.
Do you know which QR Code scanners use the ZXing library?
Literally all of them that didn't exist before 2008, in some form. The only
ones I can think of that (as far as I know) use their own scanner are
classics like the 3GVision-based ones.
In the summary by g1adrift, #4 and #6 are major kickers.
This problem'll need to get solved sooner or later.
RE: #7, I'm sure there's a way to easily detect QR codes that are normal or
inverted, as other ones are doing it already without any visual stagger or
lag to the user. (EG: i-nigma, testing using EVO 4G. ).
---------------
The following are my solution thoughts based on this thread. I haven't
seen the code, but I may be encouraged to do so.
THOUGHTS:
Right now, I take it that the system detects QR Codes in the following way:
It looks for the contrast between dark and light zones. If there's a dark
zone matching the shape of a QRCode's corner, it looks for others, and then
finally the positioning blocks. At that point, it locks in, and processes
the code it can see.
In an inverted case, each QRCode may yet have an identifying figure. They
might be unintentionally read as a "solid" square on with a hollow square
inside and equal-thickness margin outside, both proportional.
So, isn't it possible to look for that kind of 'hollow' proportionality
alongside searching for the solid figure, as either might indicate a QR
code? If ZXIng sees one, it can look for the others that figure's
brothers/sisters, then do an 'invert' scan if all of them exist and have
been found.
Sean, I doubt I'm the only person who's thought of this. What're the
troubles/landmines with the above approach?
The capability I am talking about will be a function of the Barcode Scanner
client (it already is -- download the beta). It is not something that will
automatically make any other reader scan inverted codes, though, they could
have implemented such a thing at any point. Flipping the image is trivial;
it's the runtime overhead.
Since I don't think you're going to find 100% support (or even majority
support) for optional spec features like structured append or inversion,
that's why I think it's a bad idea to encode an inverted QR code.
Scanning for inverted blocks does hurt performance. You can try it. You're
still doubling the number of leads it tracks down.
A better idea I think is farther up in the thread. Just sample the image to
see whether it's more dark than light and assume it's inverted if so. This
still has problems: a normal code in the middle of a large dark background
fails, when it didn't before. If someone works up a clever patch along
those lines that doesn't create more failures, that would be great
Issue 877 has been merged into this issue.