Redth / ZXing.Net.Mobile

Barcode Scanner for Xamarin.iOS, Xamarin.Android, UWP and Tizen
MIT License
1.07k stars 701 forks source link

Small barcode detection issue #83

Closed AlexMerle closed 10 years ago

AlexMerle commented 10 years ago

Hello,

First of all, thank you very much for porting the library.

We are trying to build a Xamarin application that will detect the I2of5 barcodes. We have a bunch of different labels depending on the item size and length of barcodes vary from 1.5 to 6 cm. Barcodes longer than 3 cm are detected very good. But if they become smaller than 2 cm it's pretty difficult to detect them (even at TryHarder mode) because they are probably too small for 6 inches distance (from camera to the target) to be detected and when you put the camera closer it can't (auto)focus at the target.

I've tested the original Barcode Scanner app by ZXing Team (https://play.google.com/store/apps/details?id=com.google.zxing.client.android) and it looks like it can focus the camera at closer distance, 3 inches or something, at the same device.

Is there a way to configure the library so it can detect smaller barcodes at the same recommended 6 inches distance or maybe focus at smaller distance (3-4 inches)? Maybe some kind of Macro mode?

Thank you.

Redth commented 10 years ago

Can you provide some sample barcode images?

Focusing is really somewhat dependant on hardware, so this isn't going to be a 'simple' fix I don't think :s

AlexMerle commented 10 years ago

Redth, thank you for the answer. Please take a look at them here: http://sdrv.ms/1e7d62p These 2 barcodes are the smallest ones. I added a pen so you can compare their sizes.

I tested the application with Galaxy SII if you need to know the hardware. But I'm not sure it's completely dependent on hardware because I tested Barcode Scanner by ZXing team on the same device and it turned out that it can focus much closer (3 inches maybe) and that's why scans these small barcodes very well.

Basically, I would like to ask if there is a way to configure the library so it can detect smaller barcodes at the same recommended 6 inches distance or maybe focus at smaller distance (3-4 inches)? Some workaround maybe? I tried to research the source code but didn't find the way how to do it easily.

Redth commented 10 years ago

Can you scan those and send them to me? I'd like to try and make them approximately 'real' size and try working with them on my end... This is a good indication of how small they are though for testing...

AlexMerle commented 10 years ago

I generated few barcodes for you and shared them here: http://sdrv.ms/1eaksCd The smallest one ~corresponds to the smallest barcode at our system.

I used http://www.barcodesinc.com/generator/index.php for their generation. It's I2of5 barcode with bar width = 1 pixel and then made smaller as an image.

Please let me know if I can help you somehow with testing. Thank you for your help!

AlexMerle commented 10 years ago

Hello Redth, sorry for bothering you. Any luck with this issue?

Redth commented 10 years ago

Not yet, sorry. Pretty swamped with my day job right now :(

AlexMerle commented 10 years ago

I understand, thank you. Maybe you can point me to the right direction so I can move forward with research myself?

Redth commented 10 years ago

@AlexMerle I think the main issue actually is that l2of5 format is not supported in ZXing.Net which is what ZXing.Net.Mobile uses to actually decode the barcodes from the image data: http://zxingnet.codeplex.com/

@micjahn may be able to chime in and see if there's a possibility in supporting it in the near future or not?

AlexMerle commented 10 years ago

@Redth I think it's not an issue because as I mentioned previously larger I2of5 barcodes are recognized very well. The problem occurs when barcode becomes smaller than some particular size. Recognition doesn't happen at the 6 inches distance (too small?) and when you move the device closer - it can't focus because of blurring.

So if I understand the problem correctly I should either try increasing the size of the image before it gets to the recognition engine OR make sure camera can focus at the closer distance. Maybe there is a way to control the autofocusing process? This option seems possible because as I mentioned earlier native ZXing demo application focuses on much closer distance at the same device. So it's probably a controllable process.

What do you think about these options?

Redth commented 10 years ago

Well first of all, let's get a barcode that is detectable by ZXing.Net, and take the .Mobile variable out of the equation...

I've added a test with the larger of the sample barcodes you provided: https://github.com/Redth/ZXing.Net.Mobile/blob/master/src/ZXing.Net.Mobile.NUnit/Test.cs#L102-L107

The image I'm trying does not pass the test, so that's where we should start looking I think!

micjahn commented 10 years ago

@Redth I2of5 is supported by ZXing.Net.

And now some results of my tests with the barcode from the word document. I generally test every image with the WinFormsDemo from ZXing.Net. It is something like my reference implementation.

I can successfully decode the barcode BUT not without modification of the source code. The main problem is the proportion between the wide and the narrow bars. Referencing to the spec of I2of5 from http://en.wikipedia.org/wiki/Interleaved_2_of_5 the wide bars should be 2.0 to 3.0 times the width of the narrow bars. But zxing does only accept 3 times the width, not 2 times.

The sample image uses a proportion between wide and narrow of 2 -> it fails.

If you want to try it yourself than you have to change one line in the file ITFReader.cs: private const int W = 3; // Pixel width of a wide line to private const int W = 2; // Pixel width of a wide line

After fixing this issue you should continue with the tests of smaller barcodes and different ranges.

Redth commented 10 years ago

@micjahn is this something you're going to account for in the ITFReader in your project then?

micjahn commented 10 years ago

Hopefully. There is an open issue for the java version with the same topic: New URL: https://github.com/zxing/zxing/issues/34 Old URL: https://code.google.com/p/zxing/issues/detail?id=1831

Perhaps I can help to solve it, then I will port the changes to ZXing.Net.

AlexMerle commented 10 years ago

@Redth @micjahn Thank you for your answers and ideas.

I downloaded the latest code from GitHub and conducted several experiments with it on a real device. 1) Changing "W = 3" to "W = 2" at the ITFReader.cs doesn't improve the recognition unfortunately. 2) Setting camera focusing mode to Macro (via camera parameters at ZXingSurfaceView.AutoFocus method) helps to decrease the minimum possible distance to the barcode from 6 inches to about 3-4 inches but it doesn't help with small barcodes either :(

Is there any other options I can test?

I have one more idea: if the problem is really caused by narrow bars at the small barcodes then it might be reasonable to "zoom in" the image before sending it to the recognition. I tried this option as well but failed to complete the process. It's easy to crop the captured image using PlanarYUVLuminanceSource class (BarcodeReaderGeneric.Decode method) in order to get the central part of it but there is a question how to stretch it. Maybe you have some ideas how to stretch the central part of the image?

Redth commented 10 years ago

Sorry, at this point I'm unable to add anything. This seems to be an upstream issue which got closed in the .java world :(

Please continue on that issue in the zxing project.

ankiitbansal commented 6 years ago

We @Redth we are also facing this issue, any help you can do please let us know. We are not able to scan smaller barcodes.

grayter1 commented 4 years ago

What about version 3? Is this problem solved? I really need a reliable scanner in my app, but app will scan only very tiny barcodes (stickers on front hdd drives)

elvijs-scopetechnology commented 3 years ago

It might be that not the highest camera resolution gets picked up. Can try this solution to pick highest available

ScanView.Options = new MobileBarcodeScanningOptions()
{
    CameraResolutionSelector = (List<CameraResolution> availableResolutions) =>
    {
        var entry = availableResolutions.Select(r => new
        {
            PixelCount = r.Width * r.Height,
            Resolution = r
        })
            .OrderByDescending(entry => entry.PixelCount)
            .First();

        return entry.Resolution;
    },
};