Zbar源码分析

2016年3月2日15:26:36
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
{
  while(x < w) //x先从0递增到w,再递减回0
  {
     x += 1;
     zbar_scan_y();
  }
  x = w - 1;
  y = y+ ydensity //y从0以ydensity递增到h
  if(y >= h)
    break;
  while(x >=0)//  x开始递减
  {
     x -= 1;
     zbar_scan_y();
  } 
  x = 0 + 1;
  y = y + ydensity;
} 
//接着判断x方向扫描密度(xdensity),同理Z字形扫描

2016年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 */
gauss_20_sigma10
通过第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,加快执行速度
2nd differentials
但第234行的判断不知何意

if((abs(y1_1) < abs(y1_2)) &&
           ((y1_1 >= 0) == (y1_2 >= 0)))
            y1_1 = y1_2;
  //如果y11与y12同向且y11小于y12,则y11=y12

static inline unsigned calc_thresh (zbar_scanner_t *scn)
dx = x - lastedge;
t = thresh*dx;
t /= scn->width;
t /=8;
calc_thresh
这一段程序主要是为了使thresh逐渐回归到thresh_min,如果dx在8width范围内,则thresh=thresh(1-dx/8w);即如果dx=width,则thresh=7/8thresh。如果dx超出8w范围,则直接置为thresh_min。thresh在每次确定新的边界时更新为此处的y11的0.44倍。

你可能感兴趣的:(ZBar,图像处理,笔记)