zoukankan      html  css  js  c++  java
  • Zbar -- 源码分析

    博客转载自:https://blog.csdn.net/sunflower_boy/article/details/50783179

    //Img_scanner.c 文件内
    int zbar_scan_image (zbar_image_scanner_t *iscn, zbar_image_t *img)

    经过Zbar example的分析后发现图像扫描的工作都是由zbar_scan_image完成的,zbar_scan_image主要根据设定的扫描密度(density)控制像素点读取(Z字形),scanner.c文件内的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字形扫描
    }

    逐点扫描判断边界,实际的条形码波形不是理论中的方波,而是高斯退化的波,其边界处是凹凸交界的位置。求边界的原理是二阶导数为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

    函数

    static inline unsigned calc_thresh (zbar_scanner_t *scn) 
    dx = x - lastedge; 
    t = thresh*dx; 
    t /= scn->width; 
    t /=8; 
    

      

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

  • 相关阅读:
    fork子进程
    多输入使用多线程
    多输入select
    多输入之轮询
    开启telnet
    slickedit编译调试linux应用程序
    电子书框架
    通用Makefile
    STDIN_FILENO和stdin
    libiconv交叉编译提示arm-none-linux-gnueabi-gcc
  • 原文地址:https://www.cnblogs.com/flyinggod/p/8717916.html
Copyright © 2011-2022 走看看