继续玩飞腾派。。。
Zbar和Zxing是目前条码识别开源算法软件,ZBar支持许多流行条形码类型,包括EAN-13/UPC-A、UPC-E、EAN-8、Code 128、Code 39、Interleaved 2/5、QR码等,Zbar基于C编写运行效率更高。
这里考虑更加贴近自助终端产品的开发环境和调优需求,采用了下载Zbar源码在本地编译的方式,Zbar源码文件:
条码种类介绍:
下面使用codeblocks IDE工具,安装最新版本openCV-4.8视觉库,使用UVC摄像头实时拍摄条码进行识别。
编写源代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "zbar.h"
#include "myclib.h"
using namespace std;
using namespace cv;
using namespace zbar;
using namespace myclib;
int libzcode_decode(unsigned char* pImg_Data, int nWidth, int nHeight, char *pSym_Data, int *pSym_Type, int Sym_BufLen)
{
zbar_image_scanner_t *scanner;
zbar_image_t *image;
const zbar_symbol_t *sym;
int sym_size = -1;
int num_syms = 0;
scanner = zbar_image_scanner_create( 2 );
zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
image = zbar_image_create();
zbar_image_set_format(image, zbar_fourcc('Y','8','0','0'));
zbar_image_set_size(image, nWidth, nHeight);
zbar_image_set_data(image, pImg_Data, nWidth * nHeight, zbar_image_free_data);
num_syms = zbar_scan_image(scanner, image);
if(num_syms > 0) {
sym = zbar_symbol_set_first_symbol( zbar_image_get_symbols(image) );
*pSym_Type = zbar_symbol_get_type(sym);
sym_size = zbar_symbol_get_data_length(sym);
if(sym_size > Sym_BufLen) sym_size = Sym_BufLen;
if(sym_size > 0) {
memcpy(pSym_Data, (char*)zbar_symbol_get_data(sym), sym_size);
}
}
zbar_image_destroy(image);
zbar_image_scanner_destroy(scanner);
return sym_size;
}
int zbar_main(int argc, char** argv)
{
bool result_cam = 0;
int result_cnt = 0;
int code_type = 0;
char sym_msg[256];
int sym_msg_len;
cv::VideoCapture capture;
result_cam = capture.open(“/dev/video0”, cv::CAP_V4L2);
if(result_cam < 1)
{
printf("open camera fail: %d\n", result_cam);
return -1;
}
capture.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
capture.set(cv::CAP_PROP_FRAME_WIDTH, 640);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
capture.set(cv::CAP_PROP_FPS, 30);
cv::Mat frame;
cv::Mat gray;
while(1)
{
capture >> frame;
if (!frame.empty())
{
cvtColor(frame, gray, COLOR_BGR2GRAY);
cv::imshow(“zbar”, gray);
memset(sym_msg, 0x00, sizeof(sym_msg));
sym_msg_len = 0;
code_type = 0;
sym_msg_len = libzcode_decode(gray.data, gray.cols, gray.rows, sym_msg, &code_type, sizeof(sym_msg)-1);
if (sym_msg_len > 0)
{
printf(“%d, type: %d, len: %d, msg: %s\n”, result_cnt++, code_type, sym_msg_len, sym_msg);
}
}
if (cv::waitKey(1) == 27)
break;
}
cv::destroyAllWindows();
return 0;
}
编译通过:
考虑对CMOS进行调优,可以关闭自动曝光&增加补光亮度,提高帧率,提高识别速度,关闭锐度增强,避免二值化引起误码,提高识别率等,这里根据UVC摄像头属性,使用v4l2-utils工具进行调节:
system("v4l2-ctl -d /dev/video0 -c exposure_auto=1"); //manual mode
system("v4l2-ctl -d /dev/video0 -c exposure_absolute=100");
//exposure
system("v4l2-ctl -d /dev/video0 -c gain=20"); //gain (0~100)
system("v4l2-ctl -d /dev/video0 -c sharpness=0");
//sharpness
system("v4l2-ctl -d /dev/video0 -c brightness=30");
//brightness (-64~64)
system("v4l2-ctl -d /dev/video0 -c contrast=16");
//contrast default 32
运行效果:
在未绑核和设置性能模式下,1D条码加大density后解码速率接近UVC帧率;2D QR码解码速度大约10次/秒,性能还可以。