损坏的QrCode重构

时间:2019-01-18 10:40:36

标签: image-processing qr-code aforge

EDIT 图像下方是原始图像上的预处理序列。 1.原始图像-> 2.模糊xn倍以使qrcode位置有意义-> 3.裁剪原始图像,使用blob从第二步提取位置-> 4.锐化和阈值-> 5.检查三个正方形的qrcode-> 6进行旋转->(最终图像)(具有调整大小分辨率的裁剪图像)之类的其他转换。

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

breakdown

2 个答案:

答案 0 :(得分:1)

这是一个有趣的问题。要回答您的问题,这在技术上是否可行。是的,肯定有可能。您问题中的QR码编码为“ 5176941.12”。

以下是假定的图像,以便于手动设置像素。

enter image description here

此步骤之后,我使用excel逐个设置每个像素。之后,只需将手机指向计算机屏幕即可。这就是它的样子。如果您需要Excel工作表,可以在这里获取它(https://docs.google.com/spreadsheets/d/18tEhboAULaSJlTjnhdZa0hOrqkUz6WmPOZSpzpSpcUE/edit?usp=sharing)。

enter image description here

现在可能性问题已经解决了,如何使其自动化?在不知道其他样本的情况下,很难确定。但是,仅基于此样本,最简单的方法就是在裁剪后的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)

在代码中裁剪了图像to_process.png

enter image description here

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

阈值图像。

enter image description here

重新生成的QR,请注意,即使有多个错误,它仍然可以正常工作。

enter image description here

答案 1 :(得分:0)

这很困难。

如果您可以使用读取器对QR进行解码(我尝试过但失败了),则可以使用写入器对其进行重新编码。但是不能保证编写者将重新创建相同的内容,因为可能使用不同的编码选项。

如果实际上您的目标是能够解码,那么您将陷于困境。 “手工”解码是可能的,但它既冗长又复杂。您还可以考虑在完美的网格上手工重绘代码,并将其传递给阅读器。