吳兆林
摘要:本文是基于Zbar開源條形碼識別開發(fā)包,使用VC++開發(fā)工具和OpenCV,進(jìn)行條形碼圖像的識別,介紹了條碼碼識別常用的兩種方法和條形碼圖像識別要解決的兩個關(guān)鍵問題。詳細(xì)講述了基于Zbar條形碼圖像識別的具體實(shí)現(xiàn)步驟:開發(fā)工具環(huán)境的設(shè)置、條形碼圖像的獲取、條形碼圖像的預(yù)處理、條形碼圖像的識別四個步驟,重點(diǎn)是Zbar開發(fā)工具的實(shí)現(xiàn)方法。
關(guān)鍵詞:條形碼 識別 Zbar OpenCV 圖像
中圖分類號:TP391.41 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9416(2016)08-0128-02
自從上世紀(jì)末,互聯(lián)網(wǎng)得到了飛速發(fā)展,互聯(lián)網(wǎng)為信息化和現(xiàn)代化奠定了堅實(shí)的基礎(chǔ),在人們不斷探索人與人的現(xiàn)代通信技術(shù)的同時,視覺也在物與物的通信角度悄然翻開。從2005年開始,一種全新的“網(wǎng)絡(luò)”—物聯(lián)網(wǎng)開始悄然出現(xiàn)并影響日益巨大,物聯(lián)網(wǎng)被視為互聯(lián)網(wǎng)的應(yīng)用拓展,實(shí)現(xiàn)了任何物體與物體之間的信息交換和通信。目前物聯(lián)網(wǎng)中最常用的信息采集技術(shù)是條形碼技術(shù),所以條形碼圖像采集和識別將變得越來越重要。
1 條形碼技術(shù)簡介
條形碼是一種信息代碼,它用特殊的圖形來表示數(shù)字、字母信息和某些符號,用以表示一個完整數(shù)據(jù)的符號。條形碼分為一維條形碼和二維碼。
一維條形碼簡稱條形碼,它是由一組規(guī)則排列的條、空以及對應(yīng)的字符組成的標(biāo)記,這些條和空組成的數(shù)據(jù)表達(dá)一定的信息。常用的一維碼的碼制包括:EAN碼、39碼、UPC碼、128碼、93碼、庫德巴碼等。
二維條形碼簡稱二維碼,它是用某種特定的幾何圖形按一定規(guī)律在平面分布的黑白相間的圖形記錄數(shù)據(jù)符號信息的。常用二維碼的碼制有:DataMatrix、MaxiCode、Aztec、QRCode、Code49等。
2 條形碼圖像識別的常用方法
對條形碼的圖像進(jìn)行識別,就是對條碼圖像進(jìn)行譯碼,得到條碼所表示的文本信息,常用的方法有如下兩種:
2.1 按照條形碼編碼原理識別條碼
由于條形碼種類多,且每種條碼都有自己的編碼規(guī)則,所以利用條形碼的編碼原理來識別條形碼,一是對條形碼圖像處理的要求高,二是每一種條形碼編碼需要相應(yīng)的識別算法,程序編程量大,識別難度大。
2.2 使用開源條形碼識別工具包進(jìn)行識別
由于條形碼都是標(biāo)準(zhǔn)化的產(chǎn)品,目前市場上有專門的條形碼識別工具包,幫助程序開發(fā)者快速方便地識別出圖像中的條碼信息,這樣開發(fā)者就無需再對圖像中不同類型的條形碼編寫解碼程序,只需將圖像交給工具包就能快速得到條碼信息。目前條形碼識別工具包有很多,但開源的條形碼開發(fā)工具包不多,主要有兩個,一是Zbar工具包,另一是ZXing工具包,兩者都具有解碼多種格式的一維和二維條形碼功能,并且這兩種工具包支持多平臺和多語種版本供開發(fā)者使用。ZBar工具是基于C語言編寫,解碼效率高于ZXing,所以在windows平臺下,使用VC++開發(fā)工具進(jìn)行條形碼識別,首先Zbar工具包。
3 條形碼圖像識別要解決的兩個關(guān)鍵問題
條形碼圖像識別的流程是:采集圖像、圖像預(yù)處理、條形碼識別,得到圖像中的條形碼信息。需要解決好二個問題,即圖像處理和條形碼識別問題。
3.1 圖像處理問題
圖像處理部分是條碼識別的前期工作,需要使用強(qiáng)大的圖象處理工具來進(jìn)行,包括圖像的讀入、條形碼區(qū)域的裁剪、濾波、二值化處理等,得到高質(zhì)量圖像。條碼識別就是在這個圖像的基礎(chǔ)上實(shí)現(xiàn),所以圖像處理的質(zhì)量直接關(guān)系到條碼能否正確識別。
3.2 條形碼識別問題
條形碼識別問題,就是采用什么方法把圖像上的條形碼轉(zhuǎn)化成相應(yīng)的文本信息。如果采用根據(jù)條形碼編碼原理來識別條碼,因?yàn)闂l形碼種類多,每種條形碼編碼方式不同,開發(fā)人員不僅要熟悉各種條形碼的編碼規(guī)則,而且要針對每種條形碼編寫相應(yīng)的解碼程序,具有實(shí)現(xiàn)起來難度大、編程量大等缺點(diǎn)。而采用條形碼識別工具包來進(jìn)行條形碼識別,一可以大大簡化編程工作量;二不需要熟悉各種條形碼的編碼規(guī)則,識別工具包都能自行判斷;三來識別率高、速度快。
4 基于Zbar條形碼圖像識別的實(shí)現(xiàn)步驟
要對圖像中的條形碼進(jìn)行識別,有很多種實(shí)現(xiàn)途徑,本文是在windows操作系統(tǒng)下,使用VC++開發(fā)工具來實(shí)現(xiàn),需要如下幾個步驟:
4.1 開發(fā)工具環(huán)境的設(shè)置
使用Zbar進(jìn)行條形碼圖像識別的第一步是開發(fā)工具的環(huán)境設(shè)置,開發(fā)工具環(huán)境的設(shè)置包含兩個方面:一是圖像處理工具設(shè)置;二是Zbar工具包設(shè)置。
4.1.1 圖像處理工具OpenCV的設(shè)置
OpenCV是一個基于C/C++語言的開源圖像處理函數(shù)庫,其代碼都經(jīng)過優(yōu)化,用于實(shí)時處理圖像,圖像處理能力強(qiáng)大、速度快、使用方便。使用OpenCV函數(shù)庫時,需要正確的配置VC++的工程設(shè)置,主要是配置Windows環(huán)境變量和VC++的環(huán)境設(shè)置。VC++的環(huán)境設(shè)置包括設(shè)置預(yù)先編譯頭文件的路徑與動態(tài)鏈接庫的路徑,即將OpenCV需要的一些函數(shù)頭文件和庫文件加入到當(dāng)前編譯的工程中,使得程序在編譯時能夠正確地找到所需文件。
4.1.2 Zbar條形碼開發(fā)工具的設(shè)置
Zbar條形碼工具包的環(huán)境設(shè)置,只涉及到一個庫文件libzbar-0.lib和一個頭文件Zbar.h,把庫文件復(fù)制到OpenCV的庫文件目錄下,把頭文件Zbar.h加到當(dāng)前編譯的工程中就可以了,VC++在編譯時就可以就能找到這些文件進(jìn)行編譯。
4.2 條形碼圖像的獲取
識別的第二步是獲取要識別的圖像,獲取圖像的方法有兩種:一是通過電腦攝像頭或者其他圖像采集設(shè)備,實(shí)時獲取要識別的條形碼圖像,二是導(dǎo)入已經(jīng)用其他方法采集好的圖像。從攝像頭獲取圖像的方法是利用OpenCV的庫函數(shù),先創(chuàng)建設(shè)備和圖像兩個變量CvCapture* capture; IplImage* m_Frame;然后利用庫函數(shù)獲取攝像頭中的圖像capture=cvCreateCameraCapture(0); m_Frame=cvQueryFrame(capture);就可以從攝像頭中獲取圖像。
如果是圖像已經(jīng)采集好了,使用VC++的CFileFind類和CopyFile()函數(shù),把采集好的圖像文件導(dǎo)入到軟件的指定文件夾就可以了。
4.3 條形碼圖像的預(yù)處理
圖像預(yù)處理的目標(biāo)是提高別的速度和識別的正確率。簡單的圖像處理方法是對整幅圖像進(jìn)行去噪聲和二值化處理;復(fù)雜的處理方法是從整個圖像中裁剪取條形碼區(qū)域,去噪聲和二值化,必要時還要進(jìn)行旋轉(zhuǎn)、放大和縮小等處理,最終獲得高質(zhì)量的圖像。
4.4 條形碼圖像的識別
圖像預(yù)處理好了,就可以利用Zbar進(jìn)行條形碼的識別,需要如下步驟:(1)創(chuàng)建并設(shè)置Zbar圖像閱讀器;(2)獲取圖像信息;(3)從圖像中識別條形碼數(shù)據(jù);(4)把識別的數(shù)據(jù)從UTF8格式轉(zhuǎn)成ASCII格式。
4.4.1 創(chuàng)建并設(shè)置Zbar圖像閱讀器
要從圖像中識別條形碼,必須先創(chuàng)建Zbar圖像閱讀器,并且進(jìn)行相應(yīng)設(shè)置,代碼如下:
zbar_image_scanner_t *scanner = zbar_image_scanner_create();
zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
4.4.2 獲取圖像信息
Zbar閱讀器設(shè)置好了以后,接著讀入圖像,獲取圖像信息,為識別條形碼做準(zhǔn)備,代碼如下:
int width = 0, height = 0;const void *raw = NULL;
CvMat *cv_matrix = cvLoadImageM(“文件名”,CV_LOAD_IMAGE_GRAYSCALE);
width = cv_matrix->width;height= cv_matrix->height;
raw = (char*)cv_matrix->data.ptr;
zbar_image_t *image = zbar_image_create();
zbar_image_set_format(image, *(int*)”Y800”);
zbar_image_set_size(image, width, height);
zbar_image_set_data(image, raw, width * height, zbar_image_free_data);
4.4.3 圖像中識別條形碼數(shù)據(jù)
上述識別準(zhǔn)備工作做好以后,接下就是從圖像中讀取條形碼數(shù)據(jù),代碼如下:
int n = zbar_scan_image(scanner, image);
const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
const char *data = zbar_symbol_get_data(symbol);//數(shù)據(jù)存放到data
4.4.4 把識別的數(shù)據(jù)從UTF8格式轉(zhuǎn)成ASCII格式
Zbar從圖像得到的數(shù)據(jù)存放在data變量中,但數(shù)據(jù)的格式是UTF8格式,而一般使用的是數(shù)據(jù)格式是ASCII格式,所以要進(jìn)行數(shù)據(jù)格式轉(zhuǎn)換,代碼如下:
CString result_String; //用于存放轉(zhuǎn)成ASCII碼格式的數(shù)據(jù)
int nLen = MultiByteToWideChar(CP_UTF8, 0, data, -1, NULL, 0);WCHAR *pWstr = new WCHAR[nLen+1];
ZeroMemory(pWstr,sizeof(WCHAR) * (nLen+1)) ;
MultiByteToWideChar(CP_UTF8, 0, data, -1, pWstr, nLen) ;
std::string strAnsi(_bstr_t((wchar_t*)pWstr));
result_String.Format(_T(“%s”),pWstr);
delete[] pWstr ;
這樣識別出來的條形碼數(shù)據(jù)就存放再result_String變量中,用戶就可以對該數(shù)據(jù)根據(jù)需要進(jìn)行相應(yīng)的處理。
5 結(jié)語
利用Zbar開源的條形碼工具包來開發(fā)條形碼識別程序,可以大大簡化程序開發(fā)工作量,識別程序開發(fā)的重點(diǎn)可以放在圖像預(yù)處理上,即使圖像不進(jìn)行預(yù)處理,Zbar也能識別出圖像質(zhì)量較好的條形碼,條形碼識別這塊程序無需專門開發(fā),只要調(diào)用Zbar工具中相應(yīng)的語句就可以了。通過實(shí)驗(yàn),識別效果好、條形碼識別率高、速度快,可以識別出多種常用的一維和二維條形碼識碼數(shù)據(jù)。
參考文獻(xiàn)
[1]布拉德斯基,克勒.學(xué)習(xí)OpenCV(中文版).清華大學(xué)出版社,2009.
[2]徐永星.條形碼國家標(biāo)準(zhǔn)匯編[M].北京:中國標(biāo)準(zhǔn)出版社,2004.
[3]范永法,郭艷萍.條碼圖像處理及識別的軟件開發(fā)[J].計算機(jī)應(yīng)用研究,2008.