如何读取和解码印度Aadhaar卡图像上的安全二维码

2024-04-29 10:21:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图从一张Aadhar卡(印度)的图像中提取完整的Aadhar编号(12位)

enter image description here

我能够用二维码识别区域。为了提取信息,我一直在研究python库,这些库可以读取和解码印度Aadhaar卡上的安全QR码。 这两个库对于这个用例似乎特别有用:

  1. pyaadhaar
  2. aadhaar-py

我无法使用Aadhaar卡上的二维码解码安全二维码Information on Secure QR code is available here.请推荐可能的解决方案或一些其他方法来完成此任务

这是我使用这些库解码安全二维码的代码。 Python版本:3.8

from pyaadhaar.utils import Qr_img_to_text, isSecureQr
from pyaadhaar.deocde import AadhaarSecureQr
from pyaadhaar.deocde import AadhaarOldQr

qrData = Qr_img_to_text(sys.argv[1])
print(qrData)

if len(qrData) == 0:
    print(" No QR Code Detected !!")
else:
    isSecureQR = (isSecureQr(qrData[0]))
    if isSecureQR:
        print("Secure QR code")
        try:
            obj  = AadhaarSecureQr(qrData[0])
        except:
            print("Try aadhaar-py library")
            from aadhaar.qr import AadhaarSecureQR
            integer_scanned_from_qr = 123456
            # secure_qr = AadhaarSecureQR(integer_scanned_from_qr)
            secure_qr = AadhaarSecureQR(int(qrData[0]))
            decoded_secure_qr_data = secure_qr.extract_data()
            print(decoded_secure_qr_data)

以下是我在这些库中面临的问题:

  1. pyaadhaar:安全QR码解码代码,尝试将base10字符串转换为字节,但失败。 注意:对于Aadhaar卡的旧二维码格式,pyaadhaar库工作正常,此问题仅在安全二维码时出现。如下:

    File "/home/piyush/libs/py38/lib/python3.8/site-packages/pyaadhaar/deocde.py", line 23, in __init__
    bytes_array = base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00')
    

    AttributeError: 'str' object has no attribute 'to_bytes'

  2. aadhaar py:安全QR解码失败,原因是无法验证从QR码接收的整数。如下:

    Traceback (most recent call last): File "/home/piyush/libs/py38/lib/python3.8/site-packages/aadhaar/qr.py", line 55, in init self.decompressed_byte_array = zlib.decompress(self.byte_array, wbits=16+zlib.MAX_WBITS) zlib.error: Error -3 while decompressing data: incorrect header check During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "aadhaarQRCode.py", line 52, in secure_qr = AadhaarSecureQR(integer_scanned_from_qr) File "/home/piyush/libs/py38/lib/python3.8/site-packages/aadhaar/qr.py", line 57, in init raise MalformedIntegerReceived('Decompression failed, please send a valid integer received from QR code') aadhaar.exceptions.MalformedIntegerReceived: Decompression failed, please send a valid integer received from QR code


Tags: tofrompyimportcodeinteger解码qr
2条回答

对于任何需要在实际解码之前提取干净QR码ROI的人,这里有一个简单的方法,可以使用阈值、形态学操作和轮廓过滤来提取QR码

  1. 获取二值图像。Load imagegrayscaleGaussian blurOtsu's threshold

  2. 连接各个QR轮廓。使用^{}创建一个矩形结构内核,然后使用cv2.MORPH_CLOSE执行morphological operations

  3. 二维码过滤器。Find contours 并使用contour approximationcontour areaaspect ratio进行过滤


这是图像处理管道

加载图像,灰度,高斯模糊,然后大津的阈值得到一个二值图像

enter image description here

现在,我们创建一个矩形内核和变形接近组合成一个轮廓二维码

enter image description here

我们使用轮廓面积、轮廓近似和纵横比找到二维码的轮廓并进行滤波。检测到的二维码以绿色突出显示

enter image description here

提取的ROI

enter image description here

代码

import cv2
import numpy as np

# Load imgae, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Morph close
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)

# Find contours and filter for QR code using contour area, approximation, and aspect ratio
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    x,y,w,h = cv2.boundingRect(approx)
    area = cv2.contourArea(c)
    ar = w / float(h)
    if len(approx) == 4 and area > 1000 and (ar > .85 and ar < 1.3):
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
        ROI = original[y:y+h, x:x+w]
        # cv2.imwrite('ROI.png', ROI)

# Display
cv2.imshow('thresh', thresh)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.imshow('ROI', ROI)

# Save images
# cv2.imwrite('thresh.png', thresh)
# cv2.imwrite('close.png', close)
# cv2.imwrite('image.png', image)
# cv2.imwrite('ROI.png', ROI)
cv2.waitKey()     

我想我已经确定了两个问题:

  • 发布的示例图像的质量不够好
  • 发布的示例只是一个示例,不是真正的“安全QR码”,而是一个示例(isSecureQR返回false

将输入的大小调整为2可以读取二维码:

读取、调整大小并另存为新图像:

import cv2    

image_file_name = 'image.png';

img = cv2.imread(image_file_name, cv2.IMREAD_GRAYSCALE)  # Read image as grayscale.
img2 = cv2.resize(img, (img.shape[1]*2, img.shape[0]*2), interpolation=cv2.INTER_LANCZOS4)  # Resize by x2 using LANCZOS4 interpolation method.

cv2.imwrite('image2.png', img2)

完整的代码示例:

import cv2
from pyaadhaar.utils import Qr_img_to_text, isSecureQr
from pyaadhaar.deocde import AadhaarSecureQr
from pyaadhaar.deocde import AadhaarOldQr

image_file_name = 'image.png';

img = cv2.imread(image_file_name, cv2.IMREAD_GRAYSCALE)  # Read image as grayscale.
img2 = cv2.resize(img, (img.shape[1]*2, img.shape[0]*2), interpolation=cv2.INTER_LANCZOS4)  # Resize by x2 using LANCZOS4 interpolation method.

cv2.imwrite('image2.png', img2)

#qrData = Qr_img_to_text(image_file_name)
qrData = Qr_img_to_text('image2.png')

print(qrData[0])

if len(qrData) == 0:
    print(" No QR Code Detected !!")
else:
    isSecureQR = (isSecureQr(qrData[0]))

输出:

BEGIN:VCARD
VERSION:2.1
N:John Doe
TEL;HOME;VOICE:555-555-5555
TEL;WORK;VOICE:666-666-6666
EMAIL:email@example.com
ORG:TEC-IT
URL:http://www.example.com
END:VCARD

如您所见,这些信息是可读的


我不知道错误消息的原因。
我使用的是Python 3.6和Windows 10,没有错误


更新:

我想我找到了一个很好的QR样本here

enter image description here

您可以使用以下步骤读取和解码二维码:

  • 读取图像并转换为灰度:

     img = cv2.imread('QR-code.png')
     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
  • 使用pyzbar解码QR图像:

     from pyzbar.pyzbar import decode
    
     code = decode(gray)
     qrData = code[0].data
    

输出为:

qrData = b'2374971804270526477833002468783965837992554564899874087591661303561346432389832047870524302186901344489362368642972767716416349990805756094923115719687656090691368051627957878187788907419297818953295185555346288172578594637886352753543271000481717080003254556962148594350559820352806251787713278744047402230989238559317351232114240089849934148895256488140236015024800731753594740948640957680138566468247224859669467819596919398964809164399637893729212452791889199675715949918925838319591794702333094022248132120531152523331442741730158840977243402215102904932650832502847295644794421419704633765033761284508863534321317394686768650111457751139630853448637215423705157211510636160227953566227527799608082928846103264491539001327407775670834868948113753614112563650255058316849200536533335903554984254814901522086937767458409075617572843449110393213525925388131214952874629655799772119820372255291052673056372346072235458198199995637720424196884145247220163810790179386390283738429482893152518286247124911446073389185062482901364671389605727763080854673156754021728522287806275420847159574631844674460263574901590412679291518508010087116598357407343835408554094619585212373168435612645646129147973594416508676872819776522537778717985070402222824965034768103900739105784663244748432502180989441389718131079445941981681118258324511923246198334046020123727749408128519721102477302359413240175102907322619462289965085963377744024233678337951462006962521823224880199210318367946130004264196899778609815012001799773327514133268825910089483612283510244566484854597156100473055413090101948456959122378865704840756793122956663218517626099291311352417342899623681483097817511136427210593032393600010728324905512596767095096153856032112835755780472808814199620390836980020899858288860556611564167406292139646289142056168261133256777093245980048335918156712295254776487472431445495668303900536289283098315798552328294391152828182614909451410115516297083658174657554955228963550255866282688308751041517464999930825273776417639569977754844191402927594739069037851707477839207593911886893016618794870530622356073909077832279869798641545167528509966656120623184120128052588408742941658045827255866966100249857968956536613250770326334844204927432961924987891433020671754710428050564671868464658436926086493709176888821257183419013229795869757265111599482263223604228286513011751601176504567030118257385997460972803240338899836840030438830725520798480181575861397469056536579877274090338750406459700907704031830137890544492015701251066934352867527112361743047684237105216779177819594030160887368311805926405114938744235859610328064947158936962470654636736991567663705830950312548447653861922078087824048793236971354828540758657075837209006713701763902429652486225300535997260665898927924843608750347193892239342462507130025307878412116604096773706728162016134101751551184021079984480254041743057914746472840768175369369852937574401874295943063507273467384747124843744395375119899278823903202010381949145094804675442110869084589592876721655764753871572233276245590041302887094585204427900634246823674277680009401177473636685542700515621164233992970974893989913447733956146698563285998205950467321954304'

isSecureQR = (isSecureQr(qrData))返回True

  • 使用pyaadhaar解码qrData

     secure_qr = AadhaarSecureQr(int(qrData))
     decoded_secure_qr_data = secure_qr.decodeddata()
    

完整的代码示例:

import cv2
from pyzbar.pyzbar import decode
from pyaadhaar.utils import isSecureQr
from pyaadhaar.deocde import AadhaarSecureQr

img = cv2.imread('QR-code.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

code = decode(gray)
qrData = code[0].data

isSecureQR = (isSecureQr(qrData))

if isSecureQR:
    secure_qr = AadhaarSecureQr(int(qrData))
    decoded_secure_qr_data = secure_qr.decodeddata()
    print(decoded_secure_qr_data)

输出:

{'email_mobile_status': '3', 'referenceid': '269720190308114407437', 'name': 'Sumit Kumar', 'dob': '01-01-1984', 'gender': 'M', 'careof': 'C/O Ishwar Chand', 'district': 'East Delhi', 'landmark': '', 'house': 'B-31, 3rd Floor', 'location': '', 'pincode': '110051', 'postoffice': 'Krishna Nagar', 'state': 'Delhi', 'street': 'Radhey Shyam Park Extension', 'subdistrict': 'Gandhi Nagar', 'vtc': 'Krishna Nagar', 'adhaar_last_4_digit': '2697', 'adhaar_last_digit': '7', 'email': 'yes', 'mobile': 'yes'}


您的原始代码也适用于上图:

from pyaadhaar.utils import Qr_img_to_text, isSecureQr

qrData = Qr_img_to_text('QR-code.png')

isSecureQR = (isSecureQr(qrData[0]))

if isSecureQR:
    secure_qr = AadhaarSecureQr(int(qrData[0]))
    decoded_secure_qr_data = secure_qr.decodeddata()
    print(decoded_secure_qr_data)

相关问题 更多 >