V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhoufan47
V2EX  ›  C#

C#的二维码摆渡解码遇到点问题

  •  
  •   zhoufan47 · 141 天前 · 955 次点击
    这是一个创建于 141 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前在网上找到个 python 写的二维码摆渡程序,识别率颇高,但是 python 的 UI 界面实在难画,自己对 python 也不是很熟悉。 最近用 C#重写了一份,可以实现一些特定功能,但是发现无论是 ZXing.net 还是 Zbar ,识别效率和成功率对比之前 python 用的 CV2 打开摄像头+pyzbar 识别二维码的组合差很多很多。 python 下我是采用固定 10ms 读取摄像头识别一次,单次 6 图,效率大约是 60/s 。 c#下我是采用绑定 timer 的形式,20ms 触发一次从摄像头获取 bitmap ,送进 decoder 解码,效率只有 1/S ,甚至经常识别不出。 各位大佬帮忙看看。 C#核心代码

     private void decodeCurrentFrame()
    
        {
            if (graphics == null)
            {
                return;
            }
            //复制图像
            this.graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);
            this.pictureBox1.Image = this.bitmapSrc;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Bitmap bitmap = (Bitmap)this.bitmapSrc.Clone();
            //解码图片
            Result[] results = reader.DecodeMultiple(bitmap);
            //读取识别出来的二维码
            if (results != null)
            {
                foreach (Result result in results)
                {
                    {
                        Console.WriteLine("成功识别");
                        string content = result.ToString();
                        if (content.Length <= 20)
                        {
                            return;
                        }
                        string prefix = content.Substring(0, 16); //获取文件前缀
                        string currentIndex = prefix.Substring(0, 8); //获取当前切片索引编号
                        string total = prefix.Substring(8); //获取总索引数
                        if (content.Contains("|"))
                        {
                            int prefixIndex = content.LastIndexOf("|");
                            int qrCurrentIndex = content.IndexOf("|");
                            currentIndex = content.Substring(0, qrCurrentIndex);
                            string raw = content.Substring(prefixIndex + 1);
                            content = "0000000000000000" + raw;
                            Console.WriteLine("旧版数据" + raw + "索引编号:" + currentIndex);
                        }
                        initResultMap(total);
                        dealData(currentIndex, content.Substring(16));
                        checkResultMap();
                    }
                }
            }
            //统计数据
            sw.Stop();
            TimeSpan ts = sw.Elapsed;
            string costed = ts.TotalMilliseconds + "ms";
            labelTickCost.Text = costed;
        }
        
    

    pyhon 核心代码

       def decodeDisplay(img):
    
            global number
            barcodes = pyzbar.decode(img)
            for barcode in barcodes:
                barcodeData = barcode.data.decode()
                try:
                    i = int(barcodeData[:8])
                except ValueError:
                    return img
                try:
                    max = int(barcodeData[8:16])
                except ValueError:
                    return img
                ll = ''
    
                if not os.path.exists("temp/result" + str(i) + ".txt"):
                    barcodeData = barcodeData[16:]
                    with open("temp/result" + str(i) + ".txt", "w+") as f:
                        f.write(barcodeData)
                        number = number + 1
                        global sat
                    if number == max:
                        filecount = len(os.listdir('temp/result'))
                        if number != filecount:
                            number = filecount
                            continue
                        j = 1
                        while j <= number:
                            with open("temp/result" + str(j) + ".txt", "r+") as f:
                                txt = f.read()
                            ll = ll + txt
                            j = j + 1
                        global starttime
                        ent = time.time()
                        theLB.insert(END, "识别结束")
                        theLB.see(END)
                        with open("result/b64.txt", "w") as f:
                            f.write(ll)
                        temp = base64.b64decode(ll)
                        with open("result/result.txt", "wb") as f:
                            f.write(temp)
                        if tkinter.messagebox.askyesno(title='识别成功', message='另存为'):
                            old_path = tk.filedialog.askdirectory()
                            shutil.copy("result/result.txt", old_path)
                        theLB.insert(END, "识别成功")
                        del_file()
            return img
    
    3 条回复    2023-11-26 14:06:19 +08:00
    a33291
        1
    a33291  
       141 天前
    1.效率问题,可以采用独立后台线程解码和识别. .net 也有 opencv 的封装,比如 opencvsharp 或者 emgucv
    2.识别率问题,这个就看 py 下和.net 是否是调用的同一个库,比如版本 api 等是否一致,如果一致则考虑送入解码的图是否一样
    ysc3839
        2
    ysc3839  
       141 天前 via Android
    建议试试 OpenCV 的 WeChatQRCode
    不过 C#怎么调用我不知道
    xd314697475
        3
    xd314697475  
       141 天前
    用 c#调用 python 岂不是迎刃而解
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3291 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:01 · PVG 21:01 · LAX 06:01 · JFK 09:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.