全站(zhàn)搜索
産品搜索
 
 
文章正文
工業相機編程流程及SDK接口使用彙總
作(zuò)者:管理(lǐ)員    發布于:2017-12-19 09:31:22    文字:【大(dà)】【】【小(xiǎo)
摘要:內(nèi)容綱要: 1.工業相機編程模型和(hé)流程 2.工業相機SDK接口使用總結 3.Basler Pylon工業相機SDK的使用 4.Pylon 以實時(shí)圖像采集講解PylonC SDK使用流程 5.工業相機SDK之opencv二次開(kāi)發

1.工業相機編程模型和(hé)流程


不同的工業相機提供不同的編程接口(SDK),盡管不同接口不同相機間(jiān)編程接口各不相同,他們實際的API結構和(hé)編程模型很(hěn)相似,了解了這些(xiē)再對工業相機編程就很(hěn)簡單了。


DMA技(jì)術(shù)

DMA是一種高(gāo)速的數(shù)據傳輸操作(zuò),允許在外部設備和(hé)存儲器(qì)之間(jiān)直接讀寫數(shù)據,既不通(tōng)過CPU,也不需要CPU幹預。整個(gè)數(shù)據傳輸操作(zuò)在一個(gè)稱為(wèi)"DMA控制(zhì)器(qì)"的控制(zhì)下進行(xíng)的。CPU除了在數(shù)據傳輸開(kāi)始和(hé)結束時(shí)做(zuò)一點處理(lǐ)外,在傳輸過程中CPU可(kě)以進行(xíng)其他的工作(zuò)。這樣,在大(dà)部分時(shí)間(jiān)裏,CPU和(hé)輸入輸出都處于并行(xíng)操作(zuò)。因此,使整個(gè)計(jì)算(suàn)機系統的效率大(dà)大(dà)提高(gāo)。

對于工業相機來(lái)說,當CMOS或CCD芯片曝光然後将數(shù)據轉到相機緩存後,這時(shí)候DMA會(huì)負責将緩存中數(shù)據保存到硬盤上(shàng)指定位置,正好滿足相機高(gāo)速大(dà)數(shù)據的傳輸。一般都會(huì)使用DMA來(lái)完成實時(shí)的數(shù)據采集和(hé)保存。


多(duō)數(shù)時(shí)候,DMA控制(zhì)器(qì)存在各種接口的圖像采集卡中,包括1394/GigE/USB/Camera Link等,這些(xiē)采集卡有(yǒu)自己的時(shí)間(jiān)控制(zhì)單元完成和(hé)相機曝光的同步,并控制(zhì)DMA的存取行(xíng)為(wèi)。


工作(zuò)流程

當相機工作(zuò)時(shí),就是連續的采集-處理(lǐ)-采集-處理(lǐ)...的過程,但(dàn)是這就存在一個(gè)問題,如果采集的速度比處理(lǐ)速度快,處理(lǐ)不過來(lái),怎麽辦?在實際中,我們使用隊列來(lái)解決這個(gè)問題,當前幀沒有(yǒu)處理(lǐ)完,下一幀到來(lái)時(shí)直接放入隊列等待當前處理(lǐ)完成後再處理(lǐ)它。

如下圖



這裏使用三個(gè)隊列完成采集和(hé)處理(lǐ)同步。

DMA隊列:當CMOS或CCD芯片曝光然後将數(shù)據轉到相機緩存後,這時(shí)候DMA會(huì)負責将緩存中數(shù)據寫入到“DMA隊列”頭Buffer中。

準備隊列:一旦“DMA隊列”頭Buffer被填充完成,會(huì)被加到“準備隊列”尾後,這時(shí)候會(huì)發送中斷通(tōng)知用戶程序:當前又有(yǒu)一幀數(shù)據采集完成,您看着處理(lǐ)吧(ba)。

處理(lǐ)隊列:當用戶接收到中斷會(huì)自動跳(tiào)轉到中斷函數(shù)中,使用GetFrame拿(ná)取“準備隊列”頭Buffer,然後加到當前用戶程序“處理(lǐ)隊列”尾,用戶程序從“處理(lǐ)隊列”頭拿(ná)取Buffer處理(lǐ)完成後使用PutFrame将Buffer再添加到原始的“DMA隊列”尾。

需要說明(míng)如下幾點:


1.這裏的初始隊列為(wèi)1-10,都是初始分配為(wèi)DMA隊列的,這個(gè)內(nèi)存分配和(hé)釋放過程有(yǒu)的SDK是自己負責的,有(yǒu)的則需要用戶自己分配和(hé)釋放,SDK隻負責托管使用。

2.一般最開(kāi)始注冊一個(gè)中斷處理(lǐ)函數(shù),當“準備隊列”填充完成會(huì)自動跳(tiào)轉到中斷函數(shù)中,借此完成同步操作(zuò)。也可(kě)以是用戶自己維護同步結構體(tǐ),使用查詢和(hé)等待的方式判斷“準備隊列”頭是否填充完成,是否該用戶程序獲取數(shù)據和(hé)處理(lǐ)了。

3.如果用戶處理(lǐ)任務非常簡單,可(kě)以去掉“處理(lǐ)隊列”,每次直接GetFrame->處理(lǐ)->PutFrame。如果用戶處理(lǐ)任務比較複雜而不希望出現丢幀的現象,則需要用戶使用“處理(lǐ)隊列”來(lái)保存所有(yǒu)可(kě)用的Buffer。

4.這裏隊列也隻是能夠解決處理(lǐ)速度比采集速度慢少(shǎo)許的情況,主要是對不同處理(lǐ)速度做(zuò)平均來(lái)保證采集和(hé)處理(lǐ)同步。如果每一幀的處理(lǐ)時(shí)間(jiān)太長,這時(shí)候“DMA隊列” Buffer全部轉移到“處理(lǐ)隊列” Buffer,就會(huì)出現異常情況,這時(shí)不同的相機會(huì)有(yǒu)不同的處理(lǐ)方法。


數(shù)據傳輸和(hé)顯示流程


如圖,每個(gè)相機可(kě)能有(yǒu)不同的流采集器(qì)(Grab Streamer)或同一接口上(shàng)安裝了多(duō)個(gè)相機(也對應多(duō)個(gè)流采集器(qì)),對應多(duō)個(gè)通(tōng)道(dào)(Channel)。對每個(gè)通(tōng)道(dào)來(lái)說,在實際采集時(shí)數(shù)據傳輸實際上(shàng)是拆分成如圖的數(shù)據包(Packet) RawData形式傳遞的,內(nèi)存中存儲形式為(wèi)一維數(shù)組,在每一幀圖像的起始存在不同的标識表明(míng)一幀的開(kāi)始和(hé)結束,每一個(gè)Packet都有(yǒu)标識表明(míng)當前所屬的通(tōng)道(dào)。為(wèi)了顯示圖像,用戶程序需要重新将一維數(shù)組數(shù)據拼裝成圖像形式,這一過程由用戶完成,通(tōng)常可(kě)借助OpenCV或MIL等圖像處理(lǐ)包完成該操作(zuò)。

編程模型和(hé)流程

對于相機來(lái)說,常見編程時(shí)我們關注三個(gè)對象——相機對象、采集對象、參數(shù)對象。

相機對象(Camera Object):負責相機的連接、斷開(kāi)等工作(zuò)。

采集對象(Grab Streamer):負責相機的采集隊列分配、相機單幀、連續采集。

參數(shù)對象(Parameter Object):負責相機參數(shù)的設置。


不同的SDK可(kě)能安排不一樣,一般來(lái)說要不是三種對象的功能合并到“相機對象”中,要不是分為(wèi)三種對象,其實采集對象和(hé)參數(shù)對象都是在“相機對象”上(shàng)封裝而來(lái)。

通(tōng)用編程流程如下圖:


可(kě)以看到相機編程需要做(zuò)三方面工作(zuò):


1.初始化操作(zuò)

首先初始化相機驅動Com環境,然後遍曆得(de)到當前的相機列表,根據相機ID或List 編号選擇對應相機。

之後連接指定相機,首先設置本次采集的相機參數(shù)(幀速、圖像大(dà)小(xiǎo)、縮放比等),然後是分配和(hé)注冊當前DMA隊列,這裏有(yǒu)的是用戶完成,有(yǒu)的是SDK完成

之後先開(kāi)啓DMA邏輯等待相機采圖,然後使相機開(kāi)始工作(zuò)采圖,整個(gè)系統就按照之前工作(zuò)流程運作(zuò)起來(lái)了,許多(duō)SDK将“開(kāi)啓DMA”和(hé)“相機開(kāi)始工作(zuò)”合并為(wèi)“開(kāi)始采集”


2.結束操作(zuò)

先停止相機工作(zuò)再關閉DMA邏輯,許多(duō)SDK将“開(kāi)啓DMA”和(hé)“相機開(kāi)始工作(zuò)”合并為(wèi)“結束采集”

然後清理(lǐ)DMA隊列,和(hé)分配時(shí)對應,這裏有(yǒu)的是用戶完成,有(yǒu)的是SDK完成

最後斷開(kāi)相機并清理(lǐ)工作(zuò)環境。


3.中斷響應操作(zuò)

當相機一幀采集完成後,自動跳(tiào)轉進入中斷回調函數(shù),這裏分了兩種中斷回調函數(shù)。

第一種為(wèi)簡單的取Buffer->處理(lǐ)->放回。


第二種結合Windows的消息隊列,在此處再給一個(gè)“處理(lǐ)隊列”,給處理(lǐ)一個(gè)緩沖時(shí)間(jiān)。

這裏的處理(lǐ)包括常見的圖像處理(lǐ)、計(jì)算(suàn)和(hé)顯示及RawData拼裝為(wèi)圖像等用到Buffer的地方。

前面也說過,常用的是中斷響應處理(lǐ),除此之外,自己去查詢Buffer填充狀态并作(zuò)相關同步操作(zuò)在某些(xiē)場(chǎng)合也會(huì)用到,這個(gè)請(qǐng)查詢不同相機SDK給出的同步方案。


差不多(duō)所有(yǒu)的工業相機SDK都是這樣的編程模型和(hé)流程,AVT 1394相機和(hé)Basler Camera Link相機和(hé)AVT GigE相機相關代碼在筆者網站(zhàn)可(kě)下載,還(hái)有(yǒu)之前講的Basler Pylon SDK相機編程,他們基本流程都是一樣,恕不詳述!


2. 工業相機SDK接口使用總結


相機調用  

        我們利用相機采集圖像,首先要對相機進行(xíng)相關參數(shù)設置及控制(zhì),這需要對相機的SDK包比較了解,一般相機廠家(jiā)都會(huì)提供相機SDK,其中包含用戶手冊和(hé)調用Demo,這些(xiē)都大(dà)大(dà)降低(dī)了調用門(mén)檻,提高(gāo)了二次開(kāi)發用戶的效率。目前用過Balser、海康、大(dà)華等相機,其實都是一個(gè)套路,都是按照下面幾個(gè)步驟進行(xíng)的。


             1)枚舉設備

             2)創建句柄

             3)打開(kāi)設備

             4)開(kāi)始抓圖

             5)獲取一幀并保存圖像

             6)停止抓圖

             7)關閉設備

             8)銷毀句柄


相機同步


       若是開(kāi)發過程中用到雙目或者多(duō)目的話(huà),則需要外接同步觸發器(qì)或者外部觸發信号,通(tōng)過相機同步觸發線來(lái)實現同步問題。以實際應用過的Basler acA1300-200uc為(wèi)例,其相機同步觸發線具體(tǐ)類型如下:


1 -——   +12 VDC  紅

2 —— I/O Input 1  黃  

3 —— VCC(加電(diàn)阻) 藍(lán)

4 ——  I/O Out 1    綠            

6 —— DCcam Power GND 黑(hēi)                   

0000—— I/O GND  白


3. Basler Pylon工業相機SDK的使用


Pylon庫有(yǒu)C++ .Net等各種封裝版本,一般用C++版本,功能全面效率高(gāo),但(dàn)對于不同接口(GigE USB3.0 CameraLink)的相機必須對應使用不同的類,之間(jiān)不能通(tōng)用。 
基于GenAPI通(tōng)用相機抽象接口使用的是Node結構,以字符串形式訪問相機參數(shù),可(kě)以統一管理(lǐ)不同接口類型的相機。但(dàn)效率低(dī),使用不方便。 
Pylon高(gāo)層用C++封裝,形成本地相機對象

如何管理(lǐ)多(duō)個(gè)相機,最靠譜的方法是按相機ID标定順序,需要讀一個(gè)配置文件,比如XML或JSON,然而一開(kāi)始不知道(dào)ID,需要先列舉出來(lái)。



4.Pylon 以實時(shí)圖像采集講解PylonC SDK使用流程


一般的對于提供硬件編程來(lái)說,硬件生(shēng)産廠家(jiā)都會(huì)提供好SDK使用的手冊和(hé)實例。手冊中一般包括安裝和(hé)配置流程,一些(xiē)基本概念的介紹,SDK每個(gè)函數(shù)使用,SDK使用流程和(hé)實例(有(yǒu)些(xiē)硬件實例直接寫在手冊中,有(yǒu)些(xiē)會(huì)以單獨文件存在,還(hái)有(yǒu)的兩者皆有(yǒu))。對于上(shàng)位機軟件開(kāi)發人(rén)員來(lái)說拿(ná)到一個(gè)硬件上(shàng)位機編程任務。


首先應該閱讀了解其SDK概念,再按照其介紹的SDK開(kāi)發流程閱讀其提供的實例,修改相應的實例為(wèi)自己所用,有(yǒu)不懂的函數(shù)查詢一下其用法即可(kě)。有(yǒu)些(xiē)開(kāi)發人(rén)員習慣性的去記其API,這是費時(shí)費力的做(zuò)法,并不推薦。下面主要以實時(shí)圖像采集講解Basler相機的PylonC SDK的使用流程。


PylonC SDK的使用的總體(tǐ)流程圖如下:



下面是其中對于不同的工作(zuò)要求,加載相機對象和(hé)卸載相機對象是通(tōng)用的。而要使用其他模塊,如事件對象時(shí),相應的改為(wèi)加載事件對象和(hé)卸載事件對象,以及使用事件對象完成相關任務即可(kě)。編程時(shí)一定要對整個(gè)流程做(zuò)好規劃,特别是硬件編程時(shí)一定留意內(nèi)存洩露,前面分配的資源一定要在後面釋放。

下面是五個(gè)大(dà)流程的詳細解析,需要的地方已經加以說明(míng),并注解了需要用到的函數(shù)


加載相機對象


卸載相機對象


加載數(shù)據流抓取對象


卸載數(shù)據流抓取對象


單幀或連續抓圖過程




按照以上(shàng)介紹的流程即可(kě)實現實時(shí)圖像采集



在工業控制(zhì)當中,用到basler工業相機sdk編程,主要是使用c或者c++,當項目龐大(dà)時(shí),又需要良好的用戶界面,用C++是不錯的選擇。 
以實例和(hé)看過的一些(xiē)參照講講PylonCppSDK使用流程。

從中我們知道(dào),總的開(kāi)發流程圖如下: 

 
那(nà)麽,用C++開(kāi)發也大(dà)抵如此。 
這裏我們看一個(gè)basler的cpp sample:




把這個(gè)和(hé)上(shàng)面的流程圖對比理(lǐ)解,再看看文檔和(hé)sdk的結構,理(lǐ)解起來(lái)就容易多(duō)了。



5.工業相機SDK之opencv二次開(kāi)發


做(zuò)視(shì)覺的第一步是選好相機鏡頭等硬件設備,接下來(lái)就是将自己開(kāi)發的算(suàn)法在硬件上(shàng)實現。我最近做(zuò)一個(gè)項目,實現了一下Opencv在相機SDK上(shàng)的運用,下面小(xiǎo)結一下具體(tǐ)實現步驟.


1. 安裝相機自帶的驅動和(hé)SDK開(kāi)發包;

2. 用VS2010新建一個(gè)工程,配置好SDK的動态鏈接庫(或者靜态),具體(tǐ)動态鏈接庫的使用可(kě)參見孫鑫的那(nà)本書(shū),這裏不多(duō)說;

3. 條用SDK開(kāi)發包中的函數(shù)建立相機和(hé)PC機件的鏈接;

4. 建立視(shì)頻流數(shù)據,設立一個(gè)回調函數(shù)(具體(tǐ)參見各SDK),并将數(shù)據拷貝到Mat中的data中;

5. 有(yǒu)了opencv中的Mat數(shù)據結構,接下來(lái)就可(kě)以實現我們的各種算(suàn)法了。

腳注信息
版權所有(yǒu) Copyright(C)2016  上海策馳自動化科技有限公司 備案号: 網安備滬公網安備31011702889576