自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

AOE工程實(shí)踐 銀行卡OCR里的圖像處理

開發(fā) 項(xiàng)目管理
期我們開發(fā)了一個(gè)銀行卡 OCR 項(xiàng)目。需求是用手機(jī)對(duì)著銀行卡拍攝以后,通過推理,可以識(shí)別出卡片上的卡號(hào)。

[[284497]]

近期我們開發(fā)了一個(gè)銀行卡 OCR 項(xiàng)目。需求是用手機(jī)對(duì)著銀行卡拍攝以后,通過推理,可以識(shí)別出卡片上的卡號(hào)。

工程開發(fā)過程中,我們發(fā)現(xiàn)手機(jī)拍攝以后的圖像,并不能滿足模型的輸入要求。以 Android 為例,從攝像頭獲取到的預(yù)覽圖像是帶 90 度旋轉(zhuǎn)的 NV21 格式的圖片,而我們的模型要求的輸入,只需要卡片區(qū)域這一塊的圖像,并且需要轉(zhuǎn)成固定尺寸的 BGR 格式。所以在圖像輸入到模型之前,我們需要對(duì)采集到的圖像做圖像處理,如下圖所示:  

 

在開發(fā)的過程中,我們對(duì) YUV 圖像格式和 libyuv 進(jìn)行了研究,也積累了一些經(jīng)驗(yàn)。

下文我們結(jié)合銀行卡 OCR 項(xiàng)目,講一講里面涉及到的一些基礎(chǔ)知識(shí):

  • 什么是YUV格式
  • 如何對(duì)YUV圖像進(jìn)行裁剪
  • 如何對(duì)YUV圖像進(jìn)行旋轉(zhuǎn)
  • 圖像處理中的Stride
  • 如何進(jìn)行縮放和格式轉(zhuǎn)換
  • libyuv的使用

想要對(duì)采集到的YUV格式的圖像進(jìn)行處理,首先我們需要了解什么是 YUV 格式。 

什么是YUV格式 

YUV 是一種顏色編碼方法,YUV,分為三個(gè)分量:“Y” 表示明亮度(Luminance或Luma),也就是灰度值;“U”和“V” 表示的則是色度(Chrominance或Chroma)。主流的采樣方式有三種YUV4:4:4YUV4:2:2YUV4:2:0這部分專業(yè)的知識(shí),網(wǎng)絡(luò)上有詳細(xì)的解釋。我們簡(jiǎn)單理解一下,RGB 和 YUV 都使用三個(gè)值來描述一個(gè)像素點(diǎn),只是這三個(gè)值的意義不同。通過固定的公式,我們可以對(duì) RGB 和 YUV 進(jìn)行相互轉(zhuǎn)換。

工程里常見的I420,NV21,NV12,都是屬于YUV420,每四個(gè)Y共用一組UV分量。YUV420主要包含兩種格式,YUV420SP 和YUV420P?!颵UV420SP,先排列Y分量,UV分量交替排列,例如:NV12: YYYYYYYY UVUV 和★NV21: YYYYYYYY VUVU (上文中我們?cè)诎沧可喜杉降膱D像就是這種格式)。

YUV420P,先排列U(或者V)分量,再排列V(或者U)分量。例如:I420: YYYYYYYY UU VV 和 YV12: YYYYYYYY VV UU。 

 

了解了YUV的圖像格式以后,我們就可以嘗試對(duì)圖片進(jìn)行裁剪和旋轉(zhuǎn)了。

我們的想法是先在圖片上裁剪出銀行卡的區(qū)域,再進(jìn)行一次旋轉(zhuǎn)。 

 

如何對(duì)YUV圖像進(jìn)行裁剪 

YUV420SP 和 YUV420P 裁剪的過程類似,以 YUV420SP 為例,我們要裁剪圖中的這塊區(qū)域: 

 

在圖上看起來就非常明顯了,只要找到裁剪區(qū)域?qū)?yīng)的Y分量和UV分量,按行拷貝到目標(biāo)空間里就可以了。 

 

我們?cè)賮砜匆粡垐D,是否可以用上面的方法來裁剪圖中的這塊區(qū)域呢? 

 

答案是否定的,如果你按照上面說的方法來操作,最后你會(huì)發(fā)現(xiàn)你保存出來的圖,顏色基本是不對(duì)的,甚至?xí)袃?nèi)存錯(cuò)誤。原因很簡(jiǎn)單,仔細(xì)觀察一下,當(dāng) ClipLeft 或者 ClipTop 是奇數(shù)的時(shí)候,會(huì)導(dǎo)致拷貝的時(shí)候UV分量錯(cuò)亂。如果把錯(cuò)誤的圖像數(shù)據(jù)輸入到模型里面,肯定是得不到我們期望的結(jié)果的。所以我們?cè)谧霾眉舻臅r(shí)候,需要規(guī)避掉奇數(shù)的場(chǎng)景,否則你會(huì)遇到意想不到的結(jié)果。 

如何對(duì)YUV圖像進(jìn)行旋轉(zhuǎn) 

對(duì)上文裁剪后的圖像做順時(shí)針90度旋轉(zhuǎn),相比裁剪,轉(zhuǎn)換要稍微復(fù)雜一些。 


基本方法是一樣的,拷貝對(duì)應(yīng)的 Y 分量和 UV 分量到目標(biāo)空間里。 

 

在了解了裁剪和旋轉(zhuǎn)的方法以后,我們發(fā)現(xiàn)在學(xué)習(xí)的過程中不可避免地遇到了 Stride 這個(gè)詞。

那它在圖像中的作用是什么呢? 

圖像處理中的Stride 

Stride 是非常重要的一個(gè)概念,Stride 指在內(nèi)存中每行像素所占的空間,它是一個(gè)大于等于圖像寬度的內(nèi)存對(duì)齊的長(zhǎng)度。如下圖所示:

 

回過頭來看我們上面說到的裁剪和旋轉(zhuǎn),是否有什么問題?

以 Android 上的YV12為例,Google Doc 里是這樣描述的: 

  1. YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed by (W/2) x (H/2) Cr and Cb planes. 
  2.  
  3. This format assumes 
  4. • an even width 
  5. • an even height 
  6. • a horizontal stride multiple of 16 pixels 
  7. • a vertical stride equal to the height 
  8.  
  9. y_size = stride * height 
  10. c_stride = ALIGN(stride / 2, 16) 
  11. c_size = c_stride * height / 2 
  12. size = y_size + c_size * 2 
  13. cr_offset = y_size 
  14. cb_offize = y_size + c_size 

所以在不同的平臺(tái)和設(shè)備上,需要按照文檔和 stride 來進(jìn)行計(jì)算。例如計(jì)算 Buffer 的大小,很多文章都是簡(jiǎn)單的 “*3/2” ,仔細(xì)考慮一下,這其實(shí)是有問題的。

如果不考慮 stride ,會(huì)有帶來什么后果?如果 “運(yùn)氣” 足夠好,一切看起來很正常。“運(yùn)氣”不夠好,你會(huì)發(fā)現(xiàn)很多奇怪的問題,例如花屏,綠條紋,內(nèi)存錯(cuò)誤等等。這和我們平常工作中遇到的很多的奇怪問題一樣,實(shí)際上背后都是有深層次的原因的。

經(jīng)過裁剪和旋轉(zhuǎn),我們只需要把圖像縮放成模型需要的尺寸,轉(zhuǎn)成模型需要的BGR格式就可以了。 

如何進(jìn)行縮放和格式轉(zhuǎn)換 

以縮放為例,有臨近插值,線性插值,立方插值,蘭索斯插值等算法。YUV 和 RGB 之間的轉(zhuǎn)換,轉(zhuǎn)換的公式也有很多種,例如量化和非量化。這些涉及到專業(yè)的知識(shí),需要大量的時(shí)間去學(xué)習(xí)和理解。

這么多的轉(zhuǎn)換,我們是否都要自己去實(shí)現(xiàn)?

很多優(yōu)秀的開源項(xiàng)目已經(jīng)提供了完善的 API 給我們調(diào)用,例如 OpenCV,libyuv 等。我們需要做的是理解基本的原理,站在別人的肩膀上,做到心里有數(shù),這樣即使遇到問題,也能很快地定位解決。

經(jīng)過調(diào)查和比較,我們選擇了 libyuv 來做圖像處理的庫(kù)。libyuv 是 Google 開源的實(shí)現(xiàn)各種 YUV 與 RGB 之間相互轉(zhuǎn)換、旋轉(zhuǎn)、縮放的庫(kù)。它是跨平臺(tái)的,可在 Windows、Linux、Mac、Android 等操作系統(tǒng),x86、x64、arm 架構(gòu)上進(jìn)行編譯運(yùn)行,支持 SSE、AVX、NEON等SIMD 指令加速。 

libyuv的使用 

引入libyuv以后,我們只需要調(diào)用libyuv提供的相關(guān)API就可以了。

在銀行卡OCR工程使用的過程中,我們主要遇到了2個(gè)問題:

1.在Android開發(fā)的初期,我們發(fā)現(xiàn)識(shí)別率和我們的期望存在一定的差距。

我們懷疑是模型的輸入數(shù)據(jù)有問題,通過排查發(fā)現(xiàn)是使用libyuv的時(shí)候,沒注意到它是little endian。例如這個(gè)方法:int BGRAToARGB(...),BGRA little endian,在內(nèi)存里順序?qū)嶋H是ARGB。所以在使用的時(shí)候需要弄清楚你的數(shù)據(jù)在內(nèi)存里是什么順序的,修改這個(gè)問題后識(shí)別率達(dá)到了我們的預(yù)期。

2.在大部分機(jī)型上運(yùn)行正常,但在部分機(jī)型上出現(xiàn)了 Native 層的內(nèi)存異常。

通過多次定位,最后發(fā)現(xiàn)是 stride 和 buffersize 的計(jì)算錯(cuò)誤引起的。通過銀行卡 OCR 項(xiàng)目,我們積累了相關(guān)的經(jīng)驗(yàn)。另外,由于 libyuv 是 C/C++ 實(shí)現(xiàn)的,使用的時(shí)候不是那么的便捷。為了提高開發(fā)效率,我們提取了一個(gè) Vision 組件,對(duì)libyuv封裝了一層 JNI 接口,包括了一些基礎(chǔ)的轉(zhuǎn)換和一些 sample,這樣使用起來更加簡(jiǎn)單方便了。作為AOE SDK 里的圖像處理組件,還在不斷開發(fā)和完善中。 

 

責(zé)任編輯:龐桂玉 來源: 普惠出行產(chǎn)品技術(shù)
相關(guān)推薦

2022-06-22 12:48:26

加密貨幣比特幣加密卡

2014-12-05 13:19:59

2015-06-02 11:35:53

2011-11-28 12:25:52

2012-12-21 20:03:48

金融展

2015-03-11 10:30:52

Apple Pay

2020-04-02 16:00:12

區(qū)塊鏈數(shù)字錢包銀行卡

2009-06-17 10:26:19

銀行卡密碼安全

2015-02-03 09:51:33

2009-09-02 20:10:51

2010-01-25 09:54:53

金融行業(yè)ACI Worldwi

2015-08-04 11:08:31

2018-05-03 10:59:45

WiFi手機(jī)銀行卡

2012-06-27 13:33:09

JavaScript

2020-12-01 16:27:02

數(shù)字貨幣

2009-07-07 10:57:04

2017-05-26 18:34:23

2017-05-02 15:10:05

2015-07-21 16:49:18

2021-04-13 11:37:46

信用卡攻擊數(shù)據(jù)泄露
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)