之前在网上找到个 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
![]() | 1 a33291 2023-11-26 13:41:02 +08:00 1.效率问题,可以采用独立后台线程解码和识别. .net 也有 opencv 的封装,比如 opencvsharp 或者 emgucv 2.识别率问题,这个就看 py 下和.net 是否是调用的同一个库,比如版本 api 等是否一致,如果一致则考虑送入解码的图是否一样 |
![]() | 2 ysc3839 2023-11-26 13:59:53 +08:00 via Android 建议试试 OpenCV 的 WeChatQRCode 不过 C#怎么调用我不知道 |
3 xd314697475 2023-11-26 14:06:19 +08:00 用 c#调用 python 岂不是迎刃而解 |