身在物流行業,掃瞄條碼的場景很多。為了改造 zbar 使其返回條碼方向(條碼與水平線的夾角),閱讀了 zbar 的原始碼。總結一下。(沒有弄清楚所有細節,只說說我弄清楚的部分)
應該大家都知道 zbar 是 z 字型掃瞄的。(為什麼要 z 字型掃瞄?不清楚。)一次掃瞄一行或者一列,在掃瞄過程中做濾波,ewma,指數加權移動平均,可以消除部分雜訊影響,然後計算梯度變化,確定邊緣,計算當前邊緣與上一邊緣的距離作為乙個條碼元素( element,bar 或者 space)的寬度,這些元素寬度放在乙個滑動視窗陣列中,以 code 128 為例,這個陣列的長度是 6,因為 code 128 是 3 個 bar 加 3 個 space 表示乙個字元。每個字元寬度是最窄 element 的 11 倍,各個 element 根據型別(bar、space)以及所佔份數(寬度是最窄 element 的幾倍)被應設成二機制數,(舉例來說,x 代表乙份寬度的 bar,o 代表乙份寬度的 space,***oxxooo 被對映成 111011000),根據二進位制數查表,得到字元。在對這個寬度陣列進行解碼的時候使用了乙個叫like-edge measurement 也叫 similar-edge measurement 的機制進行計算,操作上是,計算第 0 和第 1 element 的寬度和 a、第 1 和第 2 element 的寬度和 b、… 第 4 和 第 5 element 的寬度和,可以解決一部分因為邊界模糊而導致的寬度誤差。識別到終止符的時候組裝字元返回結果,再次識別出某結果,該結果quality 加 1(quality 可以理解成 votes,可以考慮在 quality 大於某個閾值時提前結束識別,減少不必要的計算。)
zbar原始碼分析
img_scanner.c
int zbar_scan_image (zbar_image_scanner_t *iscn,
zbar_image_t *img)
經過上一步的分析後發現影象掃瞄的工作都是由zbar_scan_image完成的,zbar_scan_image主要根據設定的掃瞄密度(density)控制畫素點讀取(z字形),zbar_scan_y()來完成濾波,閾值,確定邊緣,轉化成寬度流。
//先判斷有沒有設定y密度
if(ydensity > 0)
while(y < h) //y從0以ydensity遞增到h
x = w - 1;
y = y+ ydensity //y從0以ydensity遞增到h
if(y >= h)
break;
while(x >=0)// x開始遞減
x = 0 + 1;
y = y + ydensity;
} //接著判斷x方向掃瞄密度(xdensity),同理z字形掃瞄
2023年3月2日21:00:27
zbar_symbol_type_t zbar_scan_y (zbar_scanner_t *scn,int y)
逐點掃瞄判斷邊界
實際的條形碼波形不是理論中的方波,而是高斯退化的波,其邊界處是凹凸交界的位置。
求邊界的原理是二階導數為0或者異號的位置可能為邊界即scanner.c中247行的注釋/* 2nd zero-crossing is 1st local min/max - could be edge */
通過第138行dprintf(1, 」 thr=%d t=%ld x=%d last=%d.%d (%d)」,
thresh, t, scn->x, scn->last_edge >> zbar_fixed,
可以看出關於zbar_fixed是小數字數,round換算下就是0.5。
函式一開頭使用ewma對原始資料濾波,抑制突變。再用y0陣列儲存鄰近點的資料,用來求一階導數和二階導數,
scn->y0[(x - 1) & 3]很巧妙的限制住了陣列索引不越界,迴圈使用。
緊接著開始求一階導,二階導
register int是設定變數常駐cpu,加快執行速度
但第234行的判斷不知何意
if((abs(y1_1) < abs(y1_2)) &&
((y1_1 >= 0) == (y1_2 >= 0)))
y1_1 = y1_2;
//如果y11與y12同向且y11小於y12,則y11=y12
這一段程式主要是為了使thresh逐漸回歸到thresh_min,如果dx在8width範圍內,則thresh=thresh(1-dx/8w);即如果dx=width,則thresh=7/8thresh。如果dx超出8w範圍,則直接置為thresh_min。thresh在每次確定新的邊界時更新為此處的y11的0.44倍。
Zbar 原始碼分析
部落格 自 img scanner.c 檔案內 int zbar scan image zbar image scanner t iscn,zbar image t img 經過zbar example的分析後發現影象掃瞄的工作都是由zbar scan image完成的,zbar scan imag...
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...
思科VPP原始碼分析(dpo機制原始碼分析)
vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...