2021SC@SDUSC
目录
一、zbar.h头文件分析
在安装路径下,include中有个zbar.h文件,首先从这个头文件入手。
zbar.h文件最后给出了zbar.h所包含的头文件:
# include "zbar/Exception.h"
# include "zbar/Decoder.h"
# include "zbar/Scanner.h"
# include "zbar/Symbol.h"
# include "zbar/Image.h"
# include "zbar/ImageScanner.h"
# include "zbar/Video.h"
# include "zbar/Window.h"
# include "zbar/Processor.h"
可见ZBar源码的核心部分在zbar文件夹下。
1.Scanner.h和Decoder.h是两个重要的底层接口,分别负责扫码和解码:
* direct interaction with barcode scanning and decoding:
* - the Scanner (in @ref c-scanner "C" or @ref zbar::Scanner "C++")
* looks for barcodes in a linear intensity sample stream
* - the Decoder (in @ref c-decoder "C" or @ref zbar::Decoder "C++")
* extracts barcodes from a stream of bar and space widths
2.Window.h和Vedio.h为两种图像获取接口:
/** @name Window interface
* @anchor c-window
* mid-level output window abstraction.
* displays images to user-specified platform specific output window
*/
/*@{*/
/** @name Video interface
* @anchor c-video
* mid-level video source abstraction.
* captures images from a video device
*/
/*@{*/
windows接口将图像显示到用户指定的特定于平台的输出窗口,而video接口从视频设备捕获图像。
3.ImageScanner.h为解码结果迭代器,返回图像的第一个解码符号结果,如果没有可用的结果,则返回NULL:
/** image_scanner decode result iterator.
* @returns the first decoded symbol result for an image
* or NULL if no results are available
*/
4.Image.h为图像接口,存储图像数据样本以及相关的格式和大小:
/** @name Image interface
* stores image data samples along with associated format and size
* metadata
*/
/*@{*/
5.Symbol.h为符号集接口,用于与图像关联的解码结果符号的容器或者一个复合符号:
/** @name Symbol Set interface
* container for decoded result symbols associated with an image
* or a composite symbol.
* @since 0.10
*/
/*@{*/
6.Processor.h为图像处理器接口:
/** @name Processor interface
* @anchor c-processor
* high-level self-contained image processor.
* processes video and images for barcodes, optionally displaying
* images to a library owned output window
*/
/*@{*/
7.Exception.h为异常处理接口。
进一步的代码分析将围绕图像处理和部分解码工作展开,即Processor和Decoder。
二、图像处理器代码分析
ZBar的图像处理采用了二阶微分边缘检测:1、对运动均值后图像做二阶差分、一阶差分。边缘判定规则:二阶导数为零的位置是一阶时的最大值或最小值,因此认为是边缘点;对二阶导数符号发生变化的地方一定存在边缘点,由于进行的是差分运算,需要进行插值找到导数为零的近似位置。另外还需要满足阈值。一阶差分主要用来判定边界两侧像素大小变化2、计算边缘阈值 。对一阶差分计算阈值利于抗噪。取得当前阈值,如果当前阈值小于最小阈值,或者边缘宽度为0,返回最小阈值。求相对阈值,上一次的阈值乘以当前边缘和上一次边缘之间的距离与再上一个距离的比值。如果上一次的阈值大于相对阈值,则用上一次的阈值减去相对阈值,结果如果大于最小阈值,则返回这个结果,否则返回最小阈值。3、边缘处理。对满足边界判定规则的点进行边缘处理。4、更新新的边缘。通过线性插值算法更新新的边缘。更新阈值,对运动均值后的图像一阶差分,然后乘以一个常数。
参考:
struct zbar_processor_s {
errinfo_t err; /* error reporting */
const void *userdata; /* application data */
zbar_video_t *video; /* input video device abstraction */
zbar_window_t *window; /* output window abstraction */
zbar_image_scanner_t *scanner; /* barcode scanner */
zbar_image_data_handler_t *handler; /* application data handler */
unsigned req_width, req_height; /* application requested video size */
int req_intf, req_iomode; /* application requested interface */
uint32_t force_input; /* force input format (debug) */
uint32_t force_output; /* force format conversion (debug) */
int input; /* user input status */
/* state flags */
int threaded;
int visible; /* output window mapped to display */
int streaming; /* video enabled */
int dumping; /* debug image dump */
void *display; /* X display connection */
unsigned long xwin; /* toplevel window */
zbar_thread_t input_thread; /* video input handler */
zbar_thread_t video_thread; /* window event handler */
const zbar_symbol_set_t *syms; /* previous decode results */
zbar_mutex_t mutex; /* shared data mutex */
/* API serialization lock */
int lock_level;
zbar_thread_id_t lock_owner;
proc_waiter_t *wait_head, *wait_tail, *wait_next;
proc_waiter_t *free_waiter;
processor_state_t *state;
};