二维码的目标定位
1 總體思路
第一步,尋找二維碼的三個(gè)角的定位角點(diǎn),需要對(duì)圖片進(jìn)行平滑濾波,二值化,尋找輪廓,篩選輪廓中有兩個(gè)子輪廓的特征,從篩選后的輪廓中找到面積最接近的3個(gè)即是二維碼的定位角點(diǎn)。
第二步:判斷3個(gè)角點(diǎn)處于什么位置,主要用來(lái)對(duì)圖片進(jìn)行透視校正(相機(jī)拍到的圖片)或者仿射校正(對(duì)網(wǎng)站上生成的圖片進(jìn)行縮放拉伸旋轉(zhuǎn)等操作后得到的圖片)。需要判斷三個(gè)角點(diǎn)圍成的三角形的最大的角就是二維碼右上角的點(diǎn)。然后根據(jù)這個(gè)角的兩個(gè)邊的角度差確定另外兩個(gè)角點(diǎn)的右下和左上位置。
第三步,根據(jù)這些特征識(shí)別二維碼的范圍。
2 zbar處理流程
2.1 z型掃描圖像
對(duì)傳入圖像先進(jìn)行逐行掃描,掃描路徑為 Z 字型(掃描兩遍,縱向也要掃),以一個(gè)像素點(diǎn)為增量在一行內(nèi)一點(diǎn)一點(diǎn)掃描過去,并且完成濾波,求取邊緣梯度,梯度閾值自適應(yīng)(注:一階差分計(jì)算閾值利于抗噪),確定邊緣(注:邊緣判定規(guī)則:二階導(dǎo)數(shù)為零的位置是一階時(shí)的最大值或最小值,因此認(rèn)為是邊緣點(diǎn);對(duì)二階導(dǎo)數(shù)符號(hào)發(fā)生變化的地方一定存在邊緣點(diǎn)),轉(zhuǎn)化成明暗寬度流
2.2 補(bǔ)充尋找邊緣
2.3 獲取寬度流
用當(dāng)前邊緣跟上一次保存下來(lái)的邊緣相減得到一個(gè)寬度,并將其保存到掃描器結(jié)構(gòu)變量scn中并將本次邊緣信息保存下
之后對(duì)掃描器結(jié)構(gòu)變量scn中保存下來(lái)的明暗寬度流進(jìn)行處理,處理對(duì)象為當(dāng)前保存下來(lái)的寬度流,通過計(jì)算各寬度之間的寬度信息提取掃碼特征,依次通過幾種一維碼二維碼的檢測(cè)標(biāo)準(zhǔn),尋找到符合標(biāo)準(zhǔn)的掃碼種類
2.4 尋找圖形中點(diǎn)
通過比例1:1:3:1:1對(duì)寬度流進(jìn)行篩選并且據(jù)類之后求出橫向縱向線段的交叉點(diǎn),求出圖形中點(diǎn)
2.5 仿射變換
仿射變換:https://www.cnblogs.com/happystudyeveryday/p/10547316.html
仿射變換(Affine Transformation) Affine Transformation是一種二維坐標(biāo)到二維坐標(biāo)之間的線性變換,保持二維圖形的“平直性”(譯注:straightness,即變換后直線還是直線不會(huì)打彎,圓弧還是圓弧)和“平行性”(譯注:parallelness,其實(shí)是指保二維圖形間的相對(duì)位置關(guān)系不變,平行線還是平行線,相交直線的交角不變。)
3 解碼階段
3.1 功能區(qū)解碼
通過仿射變換,求出了 QR 碼的版本碼字和模塊寬度(根據(jù)三個(gè)交叉點(diǎn)處于同邊的兩個(gè)點(diǎn)來(lái)計(jì)算,仿射變化有單應(yīng)性仿射 affine homography 和全矩陣仿射 full homography ),將所求得的所有結(jié)果進(jìn)行計(jì)算和比對(duì),最終的出 QR 碼的版本結(jié)果,還需要判斷求出結(jié)果數(shù)是否大于等于 7 。如果是,求得的版本信息是經(jīng)過編碼后的信息,版本號(hào)還需要解碼;如果小于 7 ,求出來(lái)的結(jié)果即是 QR 碼的版本號(hào)
之后求 QR 碼的格式信息,格式信息求出來(lái)之后就是 QR 碼的功能區(qū)到目前為止已全部識(shí)別并解碼出結(jié)果
3.2 數(shù)據(jù)區(qū)解碼
首先對(duì)對(duì)圖像進(jìn)行消除掩模處理,并且識(shí)別出圖像中的定位圖案
然后將 QR 碼除去功能區(qū)之外的區(qū)域轉(zhuǎn)換為 0 和 1 的比特流
使用 Reed-Solomon 糾錯(cuò)算法對(duì)提取出來(lái)的比特流進(jìn)行校驗(yàn)和糾錯(cuò),最后輸出最終的識(shí)別比特流。
對(duì)求出的比特流進(jìn)行分析判斷,判斷當(dāng)前 QR 碼屬于什么編碼模式,找到相應(yīng)的編碼模式后對(duì)比特流進(jìn)行解碼輸出,最終求得 QR 碼的解碼結(jié)果。
4 代碼實(shí)現(xiàn)
1.先通過opencv讀取視頻流中的幀,并將圖片轉(zhuǎn)換為灰度圖(大概率彩色圖片檢測(cè)不到二維碼)
? 2.再將灰度圖通過pyzbar庫(kù)中的decode函數(shù)進(jìn)行譯碼操作,得到二維碼的信息,類型,坐標(biāo),寬度,高度,以及四個(gè)頂點(diǎn)的坐標(biāo)獲取信息如下:
[Decoded(data=b’http://weixin.qq.com/r/vnW_pi3EcnANrWnF9yCs’, type=‘QRCODE’, rect=Rect(left=283, top=179, width=124, height=124), polygon=[Point(x=283, y=179), Point(x=283, y=303), Point(x=407, y=303), Point(x=407, y=179)])]
3.由于一個(gè)畫面中可能有多個(gè)二維碼,所以進(jìn)行遍歷。在每次遍歷中提取二維碼的邊界框的位置以及二維碼數(shù)據(jù) 注:數(shù)據(jù)為字節(jié)對(duì)象,所以如果我們想在輸出圖像上畫出來(lái),就需要先將它轉(zhuǎn)換成字符串,最后將邊框和信息在視頻流中顯示出來(lái)
5 參考資料
python3 + opencv +pyzbar實(shí)時(shí)檢測(cè)二維碼 / 定位二維碼,并繪制出二維碼的框和提取二維碼內(nèi)容
二維碼的特征定位和信息識(shí)別
邊緣梯度
二維碼(QR code)基本結(jié)構(gòu)及生成原理
zbar源碼分析–QR解碼過程分析
Zbar算法流程介紹
仿射變換(Affine Transformation)
pyzbar的github主頁(yè):https://github.com/NaturalHistoryMuseum/pyzbar
pyzbar的pypi主頁(yè):https://pypi.org/project/pyzbar/
總結(jié)