Halcon采相功能非常強(qiáng)大,基本支持各大品牌以及各個(gè)通信接口的相機(jī),并且Halcon提供為相機(jī)廠商提供了制作Halcon相機(jī)接口庫(kù)的辦法,總之Halcon基本可以直接連接所有工業(yè)相機(jī)。
但是Halcon連接相機(jī)采相存在兩個(gè)問題:一是相機(jī)參數(shù)可調(diào)整范圍有限,不如相機(jī)的SDK提供的可調(diào)參數(shù)多;二是相機(jī)SDK提供了采相回調(diào)函數(shù),采相實(shí)時(shí)性更好(Halcon下也可回調(diào),沒研究過)。因此大部分視覺工程師仍然采用相機(jī)SDK采相。
使用相機(jī)SDK采相,必然面臨的問題就是如何將圖像在內(nèi)存中直接轉(zhuǎn)換為HImage格式。今天我們將學(xué)習(xí)如何將內(nèi)存中的圖像轉(zhuǎn)化為HImage。
首先,簡(jiǎn)單介紹三個(gè)算子;然后,縱向比較三個(gè)算子不同點(diǎn);舉例說明算子的用法。
gen_image1( : Image : Type, Width, Height, PixelPointer : )
從像素指針創(chuàng)建圖像,即得到像素的內(nèi)存指針(PixelPointer),已知圖像的類型(Type)、尺寸(Width、Height)就可將其轉(zhuǎn)化為HImage。
gen_image3(: ImageRGB : Type, Width, Height, PixelPointerRed, PixelPointerGreen, PixelPointerBlue : )
從像素指針創(chuàng)建圖像,即得到像素的RGB三通道內(nèi)存指針(PixelPointerRed、PixelPointerGreen、PixelPointerBlue),已知圖像的類型(Type)、尺寸(Width、Height)就可將其轉(zhuǎn)化為HImage。
gen_image_interleaved( : ImageRGB : PixelPointer, ColorFormat, OriginalWidth, OriginalHeight, Alignment, Type, ImageWidth, ImageHeight, StartRow,StartColumn, BitsPerChannel, BitShift : )
從像素指針創(chuàng)建圖像,即得到像素的內(nèi)存指針(PixelPointer),已知圖像的類型(ColorFormat)、尺寸(ImageWidth、ImageHeight)就可將其轉(zhuǎn)化為HImage。
gen_image1適合于單通道圖像轉(zhuǎn)化,gen_image3轉(zhuǎn)化需要分別知道RGB三個(gè)通道的指針,gen_image_interleaved轉(zhuǎn)化需要知道圖像的內(nèi)存的總指針以及圖像的格式。
因此gen_image1適合單通道灰度圖轉(zhuǎn)化,gen_image3適合RGB三通道內(nèi)存分別存放的相機(jī)轉(zhuǎn)化,gen_image_interleaved基本適合所有格式的轉(zhuǎn)化,操作簡(jiǎn)單且可以進(jìn)行ROI操作,因?yàn)榇蟛糠窒鄼C(jī)采相為1個(gè)總指針,所以gen_image_interleaved適用范圍非常廣,所以我們首先結(jié)合Halcon的例子來展示一下這個(gè)算子的魅力。
*1.讀取圖像
read_image (Image, ‘lena’)
*2.將圖像分離為三通道后合并得到圖像總指針(這一步是一個(gè)外部函數(shù),大家不必關(guān)心,因?yàn)橄鄼C(jī)SDK基本可以直接拿到這個(gè)指針)
rgb3_to_interleaved (Image,ImageInterleaved)
get_image_pointer1 (ImageInterleaved,Pointer, TypeRGB, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width / 3, Height,’black’, WindowHandle)
dev_set_part (0, 0, Height, Width / 3)
*3圖像由內(nèi)存中轉(zhuǎn)化為HImage
gen_image_interleaved (BImageRGB1, Pointer,’rgb’, Width / 3, Height, -1, ‘byte’, 0, 0, 0, 0, -1, 0)
stop ()
*4圖像由內(nèi)存中轉(zhuǎn)化為HImage,并進(jìn)行ROI
gen_image_interleaved (BImageRGB2, Pointer,’rgb’, Width / 3, Height, -1, ‘byte’, Width / 6, Height / 2, Height / 3, Width/ 12, -1, 0)
stop ()
*5圖像格式有RGB定義為BGR,展示這個(gè)功能主要是想提醒小伙伴,如果轉(zhuǎn)化火來顏色不對(duì),可能是由于格式選擇錯(cuò)誤
gen_image_interleaved (BImageBGR1, Pointer,’bgr’, Width / 3, Height, -1, ‘byte’, 0, 0, 0, 0, -1, 0)
原圖
RGB轉(zhuǎn)化結(jié)果
快速ROI
BGR轉(zhuǎn)化
接下來我們將結(jié)合度申相機(jī)SDK來展示如何從將圖像由內(nèi)存轉(zhuǎn)化至HImage
首先我們來看度申相機(jī)SDK的采相回調(diào)函數(shù)如下:
public int _dvpStreamCallback (uint handle, dvpStreamEvent _event, IntPtrpContext, refdvpFrame refFrame, IntPtr pBuffer)
handle——相機(jī)句柄
refFrame——幀信息
pBuffer——數(shù)據(jù)內(nèi)存指針
那么數(shù)據(jù)內(nèi)存指針就有了,接著我們查看幀信息中有什么,打開類定義如下
publicstructdvpFrame
{
[Description(“是否水平翻轉(zhuǎn)”)]
publicbyte bFlipHorizontalState;
[Description(“是否垂直翻轉(zhuǎn)”)]
publicbyte bFlipVerticalState;
[Description(“位寬”)]
publicdvpBits bits;
[Description(“是否逆時(shí)針旋轉(zhuǎn)”)]
publicbyte bRotateOpposite;
[Description(“是否旋轉(zhuǎn)90度”)]
publicbyte bRotateState;
[Description(“模擬增益”)]
publicfloat fAGain;
[Description(“曝光時(shí)間(微秒)”)]
publicdouble fExposure;
[Description(“格式”)]
publicdvpImageFormat format;
[Description(“高度”)]
publicint iHeight;
[Description(“寬度”)]
publicint iWidth;
[Description(“像素點(diǎn)的位置”)]
publicdvpFirstPosition position;
[Description(“保留字節(jié)”)]
publicuint[] reserved;
[Description(“字節(jié)數(shù)”)]
publicuint uBytes;
[Description(“幀編號(hào)”)]
publiculong uFrameID;
[Description(“時(shí)間戳”)]
publiculong uTimestamp;
}
gen_image_interleaved(: ImageRGB : PixelPointer, ColorFormat, OriginalWidth, OriginalHeight, Alignment, Type, ImageWidth, ImageHeight, StartRow,StartColumn, BitsPerChannel, BitShift : )
從幀信息中可以得到圖像格式、位數(shù)、圖像寬度、圖像高度,于是gen_image_interleaved的必備參數(shù)全部得到。
寫到C#格式下
public int _dvpStreamCallback0(uint handle, dvpStreamEvent _event, IntPtrpContext, refdvpFrame refFrame, IntPtr pBuffer)
{
if (ho_Img != null)
{
ho_Img.Dispose();//釋放HIamge資源
}
else
{
HOperatorSet.GenEmptyObj(out ho_Img);//初始化HImage
}
if ((long)pBuffer != 0)
{
HOperatorSet.GenImageInterleaved(out ho_Img, pBuffer, “bgr”, refFrame.iWidth, refFrame.iHeight, -1, “byte”, refFrame.iWidth,refFrame.iHeight, 0, 0, -1, 0);//格式轉(zhuǎn)換
}
GC.GetTotalMemory(true);//需要實(shí)時(shí)將圖像的內(nèi)存回收掉,防止占用過多CPU資源控制系統(tǒng)垃圾回收器,專制內(nèi)存不足
}
參考這個(gè)相機(jī)SDK采相轉(zhuǎn)HImage的例子,各位小伙伴應(yīng)該學(xué)會(huì)如何使用相機(jī)SDK再Halcon中采相了吧。