lezilisy 2022-01-31 11:03 采纳率: 42.9%
浏览 947
已结题

Opencv 自带QRCode和ZBar库识别不出二维码的问题

我想用OPENCV 自带的qrcode识别和ZBar库进行二维码的识别,所用的原图如下(百度上随便找的):

经过二值化,确定角点和变换矩阵,对原图进行透视变换,再截取图片转换成灰度图得到校正后的二维码图片如下:

分别用自带的QRcode算法和ZBar库对直接二值化的图和经过校正之后的灰度图进行识别,下面用QRcode识别的代码,imageSource是灰度图,thresholdQRcode是直接二值化的图。

QRCodeDetector qrcodeDetector;
    String information1;
    String information2;
    vector<Point> points;
    bool isQRcode1 = qrcodeDetector.detect(imageSource, points);
    if (isQRcode1) {
        information1 = qrcodeDetector.detectAndDecode(imageSource, points);
        cout << "识别成功:"<< information1 << endl;
    }
    else {
        cout << "未识别成功!!" << endl;
    }
    bool isQRcode2 = qrcodeDetector.detect(thresholdQRcode, points);
    if (isQRcode2) {
        information2 = qrcodeDetector.detectAndDecode(thresholdQRcode, points);
        cout << "识别成功:" << information2 << endl;
    }
    else {
        cout << "未识别成功!!" << endl;
    }

接着再用ZBar进行识别,都是一样的代码,代码如下:

//zbar解码--必须在exe同目录下加入两个dll文件,注意灰度图像!!!
    ImageScanner scanner;
    scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
    int width1 = imageSource.cols;
    int height1 = imageSource.rows;
    uchar *raw1 = (uchar *)imageSource.data;

    Image imageZbar1(width1, height1, "Y800", raw1, width1*height1);
    scanner.scan(imageZbar1);
    Image::SymbolIterator symbol1 = imageZbar1.symbol_begin();
    if (imageZbar1.symbol_begin() == imageZbar1.symbol_end()) {
        cout << "未识别成功!!" << endl;
    }
    else {
        for (; symbol1 != imageZbar1.symbol_end(); ++symbol1) {
            cout << "类型: " << symbol1->get_type_name() << endl;
            cout << "条码:" << symbol1->get_data() << endl;
        }
    }

    int width2 = thresholdQRcode.cols;
    int height2 = thresholdQRcode.rows;
    uchar *raw2 = (uchar *)thresholdQRcode.data;

    Image imageZbar2(width2, height2, "Y800", raw2, width2*height2);
    scanner.scan(imageZbar2);
    Image::SymbolIterator symbol2 = imageZbar2.symbol_begin();
    if (imageZbar2.symbol_begin() == imageZbar2.symbol_end()) {
        cout << "未识别成功!!" << endl;
    }
    else {
        for (; symbol2 != imageZbar2.symbol_end(); ++symbol2) {
            cout << "类型: " << symbol2->get_type_name() << endl;
            cout << "条码:" << symbol2->get_data() << endl;
        }
    }

实验结果如下:

img

结果表明QRcode都识别出来了,但是ZBar根据校正后的二维码却没有识别出来。我非常奇怪为啥原来直接二值化的图能够识别,我进行处理校正后的图反而识别不出来了??希望有人能解释一下。

接下来我不用灰度图,而是直接用矫正后的原图,没有转变成灰度图直接进行识别,结果如下:

img

出现了新的错误,同样没有识别成功,有没有人说说这错误是什么意思?
然后我对直接二值化的图像进行透视变换截取,得到矫正后的二值化图象来直接进行识别,图像如下:

结果如下:

img

现在结果完全倒过来了,QRcode对矫正后的图片识别不了,反而ZBar识别成功了,这到底是为啥?或者说有什么更进一步的手段能够提高识别的成功率?

  • 写回答

3条回答 默认 最新

  • prince_zxill 2022-02-05 12:36
    关注
    获得0.55元问题酬金

    识别的连接:
    https://blog.csdn.net/fangyan90617/article/details/80504838
    提高准确度的话可以用zxing。

    //图片像素按比例缩放
    Image imagePic = Image.FromStream(stream);
    Bitmap bmp = imagePic as Bitmap;
    if (imagePic.Width > 512)
    {
    int zoomMultiple = imagePic.Width / 512;
    int toWidth = 512;
    int toHeight = imagePic.Height / zoomMultiple;
    bmp = new Bitmap(toWidth, toHeight);
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        g.Clear(Color.Transparent);
        g.DrawImage(imagePic,
                    new Rectangle(0, 0, toWidth, toHeight),
                    new Rectangle(0, 0, imagePic.Width, imagePic.Height),
                    GraphicsUnit.Pixel);
        imagePic.Dispose();
    }
    //第一种识别方式Zxing
    var codes = new BarcodeReader
    {
        AutoRotate = true,
        TryInverted = true,
        Options = new DecodingOptions
        {
            TryHarder = true
        }
    }.DecodeMultiple(bmp);
    if (codes != null)
    {
        result.DataView = codes[0].Text;
        result.Code = Enum.ResultCode.DealSuccess;
        result.Message = "识别成功";
        return ReturnResp(result);
    }
    //第二种识别方式ZBar
    using (ZBar.ImageScanner scanner = new ZBar.ImageScanner())
    {
        var symbols = scanner.Scan(bmp);
        if (symbols.Count > 0 && symbols[0].Data.Length > 8)
        {
            result.DataView = symbols[0].Data;
            result.Code = Enum.ResultCode.DealSuccess;
            result.Message = "识别成功";
            return ReturnResp(result);
        }
    }
    //第三种识别方式Zxing
    MultiFormatReader reader = new MultiFormatReader();
    Dictionary<DecodeHintType, object> dictionary = new Dictionary<DecodeHintType, object> { { DecodeHintType.CHARACTER_SET, "UTF-8" } };
    RGBLuminanceSource source = new RGBLuminanceSource(QrCode.Bitmap2Rgb(bmp), bmp.Width, bmp.Height);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    Result resultVerify = reader.decode(bitmap, dictionary);
    if (resultVerify != null)
    {
        result.DataView = resultVerify.Text;
        result.Code = Enum.ResultCode.DealSuccess;
        result.Message = "识别成功";
        return ReturnResp(result);
    }
    string thoughtWorksResult = "";
    //第四种识别方式thoughtWorks
    try
    {
        QRCodeDecoder decoder = new QRCodeDecoder();
        thoughtWorksResult = decoder.decode(new ThoughtWorks.QRCode.Codec.Data.QRCodeBitmapImage(bmp));
    }
    catch (Exception)
    {
    }
    if (!string.IsNullOrEmpty(thoughtWorksResult))
    {
        result.DataView = thoughtWorksResult;
        result.Code = Enum.ResultCode.DealSuccess;
        result.Message = "识别成功";
        return ReturnResp(result);
    }
    else
    {
        result.Code = Enum.ResultCode.DealFail;
        result.Message = "识别失败";
    }
    
    
    评论

报告相同问题?

问题事件

  • 系统已结题 2月8日
  • 创建了问题 1月31日

悬赏问题

  • ¥30 physon正则密码表示
  • ¥15 Flask应用部署到阿里云服务器失败,无法访问网页,问题出在哪里?
  • ¥15 计算个体的IBS遗传距离
  • ¥15 有什么好的直流步进减速电机42的厂家推荐,保持力矩达到0.3N.M
  • ¥15 一道蓝桥杯的题,请问我错在哪里
  • ¥15 关于#android问题,xposed模块找不到so
  • ¥15 UE5.4.2创建C++项目成功,但是编译失败
  • ¥15 华为手机备份nas,airdisk,遇到的空间不足问题。求个详细的解决方案。
  • ¥20 Cknife无法使用
  • ¥15 这个结构体为什么会出错呢?