背景
我們在做圖像處理時,都會對一些相機的SDK進行開發完成圖像采集的操作,為后續圖像處理做準備。本文主要的目的是降低圖像采集的耗時,應用在一些高速檢測的場景下。利用循環隊列+內存復用的方式,去掉或者減少新建內存的時間。
線掃描相機
線掃描相機會將采集到的1-N行打包回工控機中,由SDK將這些行的數據拷貝到內部的循環隊列中。
正常流程:
1)相機SDK給出完成回調
2)軟件拷貝根據圖像大小和通道數拷貝指針數據
3)圖像處理。
該流程在2)的時候需要執行 new memory / copy memory的操作,我們現在的步驟就是需要簡化掉這兩步,有以下兩種優化方案。
優化方案一
新建循環隊列,每次只執行copy動作,耗時減少一半
1)相機SDK給出完成回調
2)循環隊列獲取當前圖像
3)拷貝內存至當前圖像上
4)循環隊列移至下一張圖像
5)圖像處理
優化方案二
新建循環隊列,將循環隊列個數和指針直接設置進SDK中(這個需要相機廠家支持,SDK內部隊列可以由用戶設置),整體耗時為0ms
拿IKAP(埃科)的相機舉例,設置SDK內部隊列的方式如下:
IKapBoardClassLibrary.IKapBoard.IKapSetBufferAddress(m_ptrBoard, ptrs.Count, ptr); //采集卡
1)相機SDK給出完成回調
2)直接根據相機給出的圖像指針找到 循環隊列中的圖像
3)圖像處理
4)只針對黑白圖像,彩色圖像還是執行新建吧,因為halcon的這個存儲格式獲取彩色圖像指針時是三個指針,而相機SDK給出的指針一般是 RGBRGB這樣的格式,去做這個拆包循環有點得不償失了
注意事項
1)以上兩種方式都需要用到循環隊列,要注意一個循環內要把圖像處理完成
2)建議把 queue的size開大一些,拿內存去換時間
3)需要長時間保留在內存的圖片,建議直接執行copy再自行刪除
面陣相機
面陣相機的方案跟線掃描的方案一是一致的,方案二的方式可以嘗試一下(我沒有試過,因為面陣一般來說圖比較小,創建耗時比較低,沒去特地做優化)
線掃描相機行數復用
優化方案
這個功能主要是用在循環拍攝時,當前圖片需要上一張圖像尾巴上的固定若干行信息,按照以下方式,整體的內存拷貝效率高,只需要拷貝復用的行數即可。
我們可以把這個步驟直接做到相機中,可以參考線掃描相機的優化的兩個點,在這直接加一些邏輯。
先假設相機SDK設置的圖像是 8192*3000,復用的行數是100.
1)首先,如果我們需要復用100行上一張的圖像,我們在制作圖像指針時要制作比SDK設置圖像的高度+100,那么我們需要做 8192*3100的圖像指針出來。
2)在設置指針給SDK時,需要對指針進行偏移 100行,這樣相機能正常的采集圖像并拷貝進指針中
3)每次采集完成回調后,需要將上一張圖的尾巴100行的指針拷貝到當前圖像的前100行中
4)圖像處理
注意事項
1、第一張圖頭部幾行會是全黑的,這里建議判斷是否是第一張圖像,如果是的話,給圖的時候做指針偏移給3000行的圖,這樣可以避免第一張圖的異常