c# – ZXing.Net无法解码Camera捕获的QR码

最新信息:

在@Michael提醒之后,
我使用了成功捕获和解码QR码

zxingnet-88246\trunk\Clients\WindowsFormsDemo

EmguCVDemo (successful decode QR code in camera frame today)

我将尝试比较演示代码和我的代码之间的差异.谢谢迈克尔,很高兴成功解码它.

p / s:这些示例代码适用于net4.0 zxing.dll但不适用于net4.5 zxing.dll

老问题:

通过使用Zxing.Net,我可以解码ZXing.Net编码的QR码的原始图像.

但是当我从Emgu.CV捕获中获取图像时,它甚至不能被ZXing.Net解码
尝试裁剪,调整大小和添加画布大小.

但是,神奇的是Android QR码扫描器甚至可以直接从相机捕获中扫描那些QR码.我试图分析Android源代码,但我发现没什么特别的.
我想知道Android版本是否正在使用相机自动对焦功能?

以下是我的代码:

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());
}

我的代码可以解码这个

相机拍摄就像这样

裁剪后,调整大小并添加画布,它就像这样(testfunny678.bmp)

我在第一张QR码图片上添加了画布,因为我发现二维码被黑色包围,即使是Android二维码解码器也无法解码.

使用HybridBinarizer的旧版本代码无法解码第一个QR码.

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

我的最终目标是直接从相机(第二个二维码)解码二维码,但如果我能解码第三个二维码,我也会感到高兴.我的朋友告诉我锐化第三张图像,以便ZXing解码并解码第三张QR码.

顺便说一下,我可以检测到QR码存在(在点(23.5,76.5),(23.5,23.5),(75,24.5)处找到)
 第三个QR码通过这两个功能

    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;
    }

但即使我尝试使用Detect()函数中的DetectorResult.Points,通过更改Detect()函数来返回解码器的DetectorResult,它仍然在解码器部分失败,因为它具有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());
        }

    }

欢迎使用ZXing.NET二维码解码器成功解码第二个二维码和第三个二维码的任何建议或更正,谢谢.

最佳答案 首先,我可以使用当前版本的ZXing.Net和WinFormsDemo成功解码QR码的第一个和第三个版本.

我的主要问题是,为什么你会得到这样一个distorded第二版?

您应该尝试正确初始化网络摄像头和EmguCV.我在ZXing.Net的演示中使用了EmguCV,我从来没有得到过如此奇怪的结果.请查看ZXing.Net存储库中EmguCV演示的源代码.

点赞