损坏的二维码重建

pho*_*att 0 qr-code image-processing aforge

下面的图像编辑 是原始图像的预处理序列。1. 原始图像 -> 2. 模糊 xn 次以使 qrcode 位置显着 -> 3. 裁剪原始图像,使用 blob 从第二步中提取位置 -> 4. 锐化和阈值 -> 5. 检查 qrcode 的三个方块 -> 6 .进行额外的转换,例如旋转 ->(最终图像)(具有调整大小分辨率的裁剪图像。)

老问题 我正在尝试从原始图像重建二维码。正如你所看到的,照片的二维码已损坏,因此我使用 Aforge 库使用 blob 从图像中检测 3 个正方形。现在我不明白的是从这些信息生成二维码的逻辑。在技​​术上是否可以用给定的信息重建二维码?

分解

Zaw*_*Lin 7

这是一个有趣的问题。回答你的问题,这在技术上可行吗?是的,这当然是可能的。您问题中的二维码编码为“5176941.12”。

这是预先设定的图像,以便更容易手动设置像素。

在此输入图像描述

完成这一步后,我使用excel将每个像素一一设置。之后,只需将手机指向计算机屏幕即可。这就是它的样子。如果您想要 Excel 表格,可以在这里获取。

在此输入图像描述

既然可能性问题已经解决了,那么如何实现自动化呢?在不知道更多其他样本的情况下,很难确定。然而,仅基于此示例,最简单的方法就是在裁剪后的 QR 图像上对齐 21x21 网格,并使用阈值填充值。然后将此图像传递给您的 QR 解码器。QR 码具有一定程度的冗余,因此即使某些像素丢失,您也很可能能够恢复原始数据。


编辑

这里有一些 python 代码,可以作为如何自动化此操作的指南。有几点需要注意:

  • 我绕过了检测 3 个盒子的步骤,并手动将其剪得很紧。如果捕获期间存在旋转,则需要修复它。
  • 阈值0.6需要根据不同的图像进行调整。现在,即使存在多个错误,它仍然可以“幸运”地工作。如果错误太多,您可能永远不会获得有效的二维码。

代码:

import cv2
import numpy as np

def fill3box(qr):
    qr[0:7,0:7] = 1
    qr[14:21,14:21] = 1
    qr[14:21,0:7] = 1
    qr[0,0:6]=0
    qr[0:6,0]=0
    qr[0:6,6]=0
    qr[6,0:7]=0
    qr[2:5,2:5]=0
    qr[14:21,14:21] = qr[0:7,0:7]
    qr[14:21,0:7] = qr[0:7,0:7]
    return qr

im = cv2.imread('to_process.png')
im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
im = cv2.resize(im,(210,210))

im = 1-((im - im.min())/(im.max()-im.min())) #normalize and adjust contrast
avg=np.average(im)
qr = np.ones((21,21))
w,h = im.shape[:2]
im_orig = im.copy()

im[im<avg]=0#binarize
im[im>avg]=1
for y in range(21):
    for x in range(21):
        x1,y1 = (round(x*w/21),round(y*h/21))
        x2,y2 = (round(x1+10),round(y1+10))

        im_box = im[y1:y2,x1:x2]
        if np.average(im_box)<0.6 and qr[y,x]!=0:#0.6 need tweaking
            qr[y,x]=0

qr = fill3box(qr) #clean up 3 box areas as they need to be fixed
# debug visualization
for x in range(21):
    p1 = (round(x*w/21),0)
    p2 = (round(x*w/21),h)
    cv2.line(im_orig,p1,p2,(255),1)

for y in range(21):
    p1 = (0,round(y*h/21))
    p2 = (w,round(y*h/21))
    cv2.line(im_orig,p1,p2,(255),1)

qr = cv2.resize(qr,(210,210),interpolation=cv2.INTER_NEAREST)

im = (im*255).astype(np.uint8)
qr= (qr*255).astype(np.uint8)
im_orig= (im_orig*255).astype(np.uint8)

cv2.imwrite('im.png',im)
cv2.imwrite('qr.png',qr)
cv2.imwrite('im_orig.png',im_orig)
Run Code Online (Sandbox Code Playgroud)

在代码中裁剪图像to_process.png

在此输入图像描述

网格覆盖以显示此方法的工作原理

阈值图像。

在此输入图像描述

重新生成的 QR,请注意,即使存在多个错误,它仍然有效。

在此输入图像描述