之前在网上找到个 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
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.