micjahn / ZXing.Net

.Net port of the original java-based barcode reader and generator library zxing
Apache License 2.0
2.72k stars 667 forks source link

Decoding Code128 at various angles #365

Open idemetriades opened 3 years ago

idemetriades commented 3 years ago

Hi, We have been using XZing in .net to decode QR codes from image files flawlessly for more than 8 years. Now we have a new requirement to decode Code128 barcodes that are manually placed on physical documents which are scanned and converted to TIF. Because the barcodes are stickers that are manually placed on documents, they may appear at an angle. To simulate this scenario, I generated images with a Code128 barcode at an angle from 0 degrees to 359 and tried to decode the barcode on each image and I noticed that the decoding worked only at certain angles, namely from 0 to 6, 87 to 93, 176 to 184, 268 to 272, 356 to 359.

The images can be found here.

Here is part of the code:

private void btnScan360_Click(object sender, EventArgs e)
{
    int i;
    Image img;
    string filename;
    string filepath;
    BarcodeReader reader;

    reader = createNewReader();

    filepath = "E:\\Barcodes\\Tilted\\";

    for (i=0; i<360; i++)
    {
        filename = filepath + i.ToString() + ".tif";
        img = Image.FromFile(filename);
        decode((Bitmap)img, i, reader);

        img.Dispose();              
    }

}

private BarcodeReader createNewReader()
{
    BarcodeReader reader = new BarcodeReader();
    reader.AutoRotate = true;
    reader.TryInverted = true;

    reader.Options.PossibleFormats = new List<BarcodeFormat>();
    reader.Options.PossibleFormats.Add(BarcodeFormat.CODE_128);
    reader.Options.PureBarcode = true;
    reader.Options.TryHarder = true;

    return reader;
}

public void decode(Bitmap bitmap, int angle, BarcodeReader reader)
{
    int i;

    //LuminanceSource source;
    //source = new BitmapLuminanceSource(bitmap);

    Result[] result = reader.DecodeMultiple(bitmap);    //Without LuminanceSource

    if (result != null)
    {
        textBox1.Text = "";
        for (i = 0; i < result.Length; i++)
        {
                Console.WriteLine("Angle={0} {1}", angle, result[i].ToString().Trim());
        }
    }
    else
    {
        Console.WriteLine("{0} {1}", angle, "Nothing!");        
    }   
}

Is there anything I can do to improve the accuracy of the decoder so that we decode at a wider range of angles?

Your help is greatly appreciated Ioannis Demetriades

micjahn commented 3 years ago

I'm afraid there is no option to improve this behavior currently. The original java version of zxing was mainly developed for mobile devices. The use case for mobile devices is that the user holds the camera more or less accurately in front of the barcode. There was no need for decoding at any angle. The option AutoRotate, which I added to the .net port, only rotates by 90 degrees. Perhaps you have to rotate it manually before decoding. If you have enough cpu cycles for processing you can try a brute force method and make up to 18 images which are rotated by 10 degrees compared to the previous image.