??不同的工業(yè)相機(jī)提供不同的編程接口(SDK)奠宜,盡管不同接口不同相機(jī)間編程接口各不相同拐辽,他們實際的API結(jié)構(gòu)和編程模型很相似,了解了這些再對工業(yè)相機(jī)編程就很簡單了
DMA技術(shù)
??DMA是一種高速的數(shù)據(jù)傳輸操作,允許在外部設(shè)備和存儲器之間直接讀寫數(shù)據(jù)翁脆,既不通過CPU训挡,也不需要CPU干預(yù)澳骤。整個數(shù)據(jù)傳輸操作在一個稱為"DMA控制器"的控制下進(jìn)行的。CPU除了在數(shù)據(jù)傳輸開始和結(jié)束時做一點處理外澜薄,在傳輸過程中CPU可以進(jìn)行其他的工作为肮。這樣,在大部分時間里肤京,CPU和輸入輸出都處于并行操作颊艳。因此,使整個計算機(jī)系統(tǒng)的效率大大提高忘分。
??對于工業(yè)相機(jī)來說棋枕,當(dāng)CMOS或CCD芯片曝光然后將數(shù)據(jù)轉(zhuǎn)到相機(jī)緩存后,這時候DMA會負(fù)責(zé)將緩存中數(shù)據(jù)保存到硬盤上指定位置饭庞,正好滿足相機(jī)高速大數(shù)據(jù)的傳輸戒悠。一般都會使用DMA來完成實時的數(shù)據(jù)采集和保存。
??多數(shù)時候舟山,DMA控制器存在各種接口的圖像采集卡中绸狐,包括1394/GigE/USB/Camera Link等卤恳,這些采集卡有自己的時間控制單元完成和相機(jī)曝光的同步,并控制DMA的存取行為寒矿。
工作流程
??當(dāng)相機(jī)工作時突琳,就是連續(xù)的采集-處理-采集-處理...的過程,但是這就存在一個問題符相,如果采集的速度比處理速度快拆融,處理不過來,怎么辦啊终?在實際中镜豹,我們使用隊列來解決這個問題,當(dāng)前幀沒有處理完蓝牲,下一幀到來時直接放入隊列等待當(dāng)前處理完成后再處理它趟脂。如下圖
這里使用三個隊列完成采集和處理同步。
DMA隊列:當(dāng)CMOS或CCD芯片曝光然后將數(shù)據(jù)轉(zhuǎn)到相機(jī)緩存后例衍,這時候DMA會負(fù)責(zé)將緩存中數(shù)據(jù)寫入到“DMA隊列”頭Buffer中昔期。
準(zhǔn)備隊列:一旦“DMA隊列”頭Buffer被填充完成,會被加到“準(zhǔn)備隊列”尾后佛玄,這時候會發(fā)送中斷通知用戶程序:當(dāng)前又有一幀數(shù)據(jù)采集完成硼一,您看著處理吧。
處理隊列:當(dāng)用戶接收到中斷會自動跳轉(zhuǎn)到中斷函數(shù)中梦抢,使用GetFrame拿取“準(zhǔn)備隊列”頭Buffer般贼,然后加到當(dāng)前用戶程序“處理隊列”尾,用戶程序從“處理隊列”頭拿取Buffer處理完成后使用PutFrame將Buffer再添加到原始的“DMA隊列”尾惑申。
需要說明如下幾點:
1.這里的初始隊列為1-10,都是初始分配為DMA隊列的具伍,這個內(nèi)存分配和釋放過程有的SDK是自己負(fù)責(zé)的,有的則需要用戶自己分配和釋放圈驼,SDK只負(fù)責(zé)托管使用。
2.一般最開始注冊一個中斷處理函數(shù)望几,當(dāng)“準(zhǔn)備隊列”填充完成會自動跳轉(zhuǎn)到中斷函數(shù)中绩脆,借此完成同步操作。也可以是用戶自己維護(hù)同步結(jié)構(gòu)體橄抹,使用查詢和等待的方式判斷“準(zhǔn)備隊列”頭是否填充完成靴迫,是否該用戶程序獲取數(shù)據(jù)和處理了。
3.如果用戶處理任務(wù)非常簡單楼誓,可以去掉“處理隊列”玉锌,每次直接GetFrame->處理->PutFrame。如果用戶處理任務(wù)比較復(fù)雜而不希望出現(xiàn)丟幀的現(xiàn)象疟羹,則需要用戶使用“處理隊列”來保存所有可用的Buffer主守。
4.這里隊列也只是能夠解決處理速度比采集速度慢少許的情況禀倔,主要是對不同處理速度做平均來保證采集和處理同步。如果每一幀的處理時間太長参淫,這時候“DMA隊列” Buffer全部轉(zhuǎn)移到“處理隊列” Buffer救湖,就會出現(xiàn)異常情況,這時不同的相機(jī)會有不同的處理方法涎才。
數(shù)據(jù)傳輸和顯示流程
??如圖鞋既,每個相機(jī)可能有不同的流采集器(Grab Streamer)或同一接口上安裝了多個相機(jī)(也對應(yīng)多個流采集器),對應(yīng)多個通道(Channel)耍铜。對每個通道來說邑闺,在實際采集時數(shù)據(jù)傳輸實際上是拆分成如圖的數(shù)據(jù)包(Packet) RawData形式傳遞的,內(nèi)存中存儲形式為一維數(shù)組棕兼,在每一幀圖像的起始存在不同的標(biāo)識表明一幀的開始和結(jié)束检吆,每一個Packet都有標(biāo)識表明當(dāng)前所屬的通道。為了顯示圖像程储,用戶程序需要重新將一維數(shù)組數(shù)據(jù)拼裝成圖像形式蹭沛,這一過程由用戶完成,通痴吕穑可借助OpenCV或MIL等圖像處理包完成該操作摊灭。
編程模型和流程
??對于相機(jī)來說,常見編程時我們關(guān)注三個對象——相機(jī)對象败徊、采集對象帚呼、參數(shù)對象。
相機(jī)對象(Camera Object):負(fù)責(zé)相機(jī)的連接皱蹦、斷開等工作煤杀。
采集對象(Grab Streamer):負(fù)責(zé)相機(jī)的采集隊列分配、相機(jī)單幀沪哺、連續(xù)采集沈自。
參數(shù)對象(Parameter Object):負(fù)責(zé)相機(jī)參數(shù)的設(shè)置。
??不同的SDK可能安排不一樣辜妓,一般來說要不是三種對象的功能合并到“相機(jī)對象”中枯途,要不是分為三種對象,其實采集對象和參數(shù)對象都是在“相機(jī)對象”上封裝而來籍滴。
通用編程流程如下圖:
可以看到相機(jī)編程需要做三方面工作:
1.初始化操作
??首先初始化相機(jī)驅(qū)動Com環(huán)境酪夷,然后遍歷得到當(dāng)前的相機(jī)列表,根據(jù)相機(jī)ID或List 編號選擇對應(yīng)相機(jī)孽惰。之后連接指定相機(jī)晚岭,首先設(shè)置本次采集的相機(jī)參數(shù)(幀速、圖像大小勋功、縮放比等)坦报,然后是分配和注冊當(dāng)前DMA隊列库说,這里有的是用戶完成,有的是SDK完成燎竖。之后先開啟DMA邏輯等待相機(jī)采圖璃弄,然后使相機(jī)開始工作采圖,整個系統(tǒng)就按照之前工作流程運(yùn)作起來了构回,許多SDK將“開啟DMA”和“相機(jī)開始工作”合并為“開始采集”夏块。
2.結(jié)束操作
??先停止相機(jī)工作再關(guān)閉DMA邏輯,許多SDK將“開啟DMA”和“相機(jī)開始工作”合并為“結(jié)束采集”纤掸。然后清理DMA隊列脐供,和分配時對應(yīng),這里有的是用戶完成借跪,有的是SDK完成政己。最后斷開相機(jī)并清理工作環(huán)境。
3.中斷響應(yīng)操作
??當(dāng)相機(jī)一幀采集完成后掏愁,自動跳轉(zhuǎn)進(jìn)入中斷回調(diào)函數(shù)歇由,這里分了兩種中斷回調(diào)函數(shù)。
第一種為簡單的取Buffer->處理->放回果港。
第二種結(jié)合Windows的消息隊列沦泌,在此處再給一個“處理隊列”,給處理一個緩沖時間辛掠。
??這里的處理包括常見的圖像處理谢谦、計算和顯示及RawData拼裝為圖像等用到Buffer的地方。
??前面也說過萝衩,常用的是中斷響應(yīng)處理回挽,除此之外,自己去查詢Buffer填充狀態(tài)并作相關(guān)同步操作在某些場合也會用到猩谊,這個請查詢不同相機(jī)SDK給出的同步方案千劈。[轉(zhuǎn)自:文大俠]