Question

Latest Info :

After reminded by @Michael, I successfully capture and decode the QR code by using the

zxingnet-88246\trunk\Clients\WindowsFormsDemo

EmguCVDemo (successful decode QR code in camera frame today)

I will try to compare the difference between the Demo code and my code. Thanks Michael, so happy to successfully decode it.

p/s: those sample codes work with net4.0 zxing.dll but not the net4.5 zxing.dll


Old questions:

By using Zxing.Net, I can decode original image of the QR code encoded by ZXing.Net.

But when I obtain the image from Emgu.CV capture, it cannot be decoded by ZXing.Net even I
try to crop, resize and add canvas size.

But, the magic is the Android QR code scanner CAN scan those QR code even directly from camera capture. I tried to analyzed the Android source code but I found nothing special. I wonder if the Android version one is using camera auto-focus function?

Below is my code:

DecoderResult decoderResult;
Bitmap bitmap = new Bitmap(@"C:\testfunny678.bmp");
LuminanceSource source = new BitmapLuminanceSource(bitmap);
//
BinaryBitmap binBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));

try
{
    //null Hashable Hints
    DetectorResult detectorResult = new Detector(binBitmap.BlackMatrix).detect(null);

    Result result = decoder.decode(binBitmap);

    //decoderResult = decoder.decode(detectorResult.Bits,null);
    //points = detectorResult.Points;
    //Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);

    if (result.Text != null)
    {
        //QR_CODE
        //MessageBox.Show("format is: " + result.BarcodeFormat);
        MessageBox.Show("result is: " + result.Text);
    }
    else
    {
        MessageBox.Show("bitmap is null");
    }
}
//com.google.zxing.ReaderException: Exception of type 'com.google.zxing.ReaderException' was thrown.
//   at com.google.zxing.qrcode.detector.FinderPatternFinder.selectBestPatterns() in d:\Temp\zxing-2.1\csharp\qrcode\detector\FinderPatternFinder.cs:line 602
//   at com.google.zxing.qrcode.detector.FinderPatternFinder.find(Hashtable hints) in d:\Temp\zxing-2.1\csharp\qrcode\detector\FinderPatternFinder.cs:line 238
//   at com.google.zxing.qrcode.detector.Detector.detect(Hashtable hints) in d:\Temp\zxing-2.1\csharp\qrcode\detector\Detector.cs:line 90
//   at qrcode.Form1.Decode3() in c:\Users\User\Documents\Visual Studio 2013\Projects\qrcode\qrcode\Form1.cs:line 139
catch (Exception e)
{
    //MessageBox.Show(e.ToString());
}

My code can decode this

My code can decode this

Camera capture like this

Camera capture like this

After crop,resize and add canvas, it becomes like this (testfunny678.bmp)

After crop,resize and add canvas

I added canvas at the first QR code picture because I found of the QR code surrounded by black colour, it cannot be decoded even by Android QR code decoder.

Old version of my code using HybridBinarizer cannot decode the first QR code.

        LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
        BinaryBitmap binBitmap = new BinaryBitmap(new HybridBinarizer(source));

My ultimate target is decode the QR code directly from camera (2nd QR code), but if I can decode the third QR code, I also feel happy. My friend tell me to sharpen the third image so that ZXing decoder and decode the third QR code.

By the way, I can detect the QR code existence (Found at points (23.5, 76.5), (23.5, 23.5), (75, 24.5)) of THIRD QR code via this two function

    public string Detect(Bitmap bitmap)
    {
        try
        {
            ZXing.LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
            var binarizer = new HybridBinarizer(source);
            var binBitmap = new BinaryBitmap(binarizer);
            BitMatrix bm = binBitmap.BlackMatrix;
            Detector detector = new Detector(bm);
            DetectorResult result = detector.detect();

            string retStr = "Found at points ";
            foreach (ResultPoint point in result.Points)
            {
                retStr += point.ToString() + ", ";
            }

            return retStr;
        }
        catch
        {
            return "Failed to detect QR code.";
        }
    }

    private byte[] GetRGBValues(Bitmap bmp)
    {
        // Lock the bitmap's bits. 
        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap.
        int bytes = bmpData.Stride * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
        bmp.UnlockBits(bmpData);

        return rgbValues;
    }

But even I tried to use the DetectorResult.Points from Detect() function by changing Detect() function to return the DetectorResult for Decoder, it is still fail at the decoder part by having null decoderResult.

    public DetectorResult Detect(Bitmap bitmap)
    //public string Detect(Bitmap bitmap)
    {
        try
        {
            ZXing.LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
            var binarizer = new HybridBinarizer(source);
            var binBitmap = new BinaryBitmap(binarizer);
            BitMatrix bm = binBitmap.BlackMatrix;
            Detector detector = new Detector(bm);
            DetectorResult result = detector.detect();
            return result;
            //string retStr = "Found at points ";
            //foreach (ResultPoint point in result.Points)
            //{
            //    retStr += point.ToString() + ", ";
            //}

            //return retStr;
        }
        catch
        {
            //return "Failed to detect QR code.";
            return null;
        }
    }

    void Decode3()
    {
        //System.Collections.Hashtable hints = null;
        DecoderResult decoderResult;
        Bitmap bitmap = new Bitmap(@"C:\testfunny678.bmp");
        LuminanceSource source = new BitmapLuminanceSource(bitmap);
        BinaryBitmap binBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
        ResultPoint[] points;

        ZXing.QrCode.Internal.Decoder decoder = new ZXing.QrCode.Internal.Decoder();
        //ZXing.MultiFormatReader decoder = new ZXing.MultiFormatReader();

        try
        {
            DetectorResult detectorResult = new Detector(binBitmap.BlackMatrix).detect(null);
            //DetectorResult detectorResult = Detect(bitmap);
            //Result result = decoder.decode(binBitmap);
            //null decoderResult here
            decoderResult = decoder.decode(detectorResult.Bits,null);
            points = detectorResult.Points;
            Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);

            if (result.Text != null)
            {
                MessageBox.Show("result is: " + result.Text);
            }
            else
            {
                MessageBox.Show("bitmap is null");
            }
        }
        catch (Exception e)
        {
            //MessageBox.Show(e.ToString());
        }

    }

Any suggestion or correction to successfully decode the 2nd QR code and 3rd QR code with ZXing.NET QR code decoder is welcome, thank you.

Was it helpful?

Solution

First, I could successfully decode the first and the third version of the QR code with the current version of ZXing.Net and the WinFormsDemo. My main question is, why did you get such a distorded second version?

You should try to initialize your webcam and EmguCV correctly. I used EmguCV in a demo for ZXing.Net and I never got such weird results. Please take a look at the source code of the EmguCV demo in the ZXing.Net repository.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top