Halcon采相功能非常强大,基本支持各大品牌以及各个通信接口的相机,并且Halcon提供为相机厂商提供了制作Halcon相机接口库的办法,总之Halcon基本可以直接连接所有工业相机。
但是Halcon连接相机采相存在两个问题:一是相机参数可调整范围有限,不如相机的SDK提供的可调参数多;二是相机SDK提供了采相回调函数,采相实时性更好(Halcon下也可回调,没研究过)。因此大部分视觉工程师仍然采用相机SDK采相。
使用相机SDK采相,必然面临的问题就是如何将图像在内存中直接转换为HImage格式。今天我们将学习如何将内存中的图像转化为HImage。
首先,简单介绍三个算子;然后,纵向比较三个算子不同点;举例说明算子的用法。
gen_image1( : Image : Type, Width, Height, PixelPointer : )
从像素指针创建图像,即得到像素的内存指针(PixelPointer),已知图像的类型(Type)、尺寸(Width、Height)就可将其转化为HImage。
gen_image3(: ImageRGB : Type, Width, Height, PixelPointerRed, PixelPointerGreen, PixelPointerBlue : )
从像素指针创建图像,即得到像素的RGB三通道内存指针(PixelPointerRed、PixelPointerGreen、PixelPointerBlue),已知图像的类型(Type)、尺寸(Width、Height)就可将其转化为HImage。
gen_image_interleaved( : ImageRGB : PixelPointer, ColorFormat, OriginalWidth, OriginalHeight, Alignment, Type, ImageWidth, ImageHeight, StartRow,StartColumn, BitsPerChannel, BitShift : )
从像素指针创建图像,即得到像素的内存指针(PixelPointer),已知图像的类型(ColorFormat)、尺寸(ImageWidth、ImageHeight)就可将其转化为HImage。
gen_image1适合于单通道图像转化,gen_image3转化需要分别知道RGB三个通道的指针,gen_image_interleaved转化需要知道图像的内存的总指针以及图像的格式。
因此gen_image1适合单通道灰度图转化,gen_image3适合RGB三通道内存分别存放的相机转化,gen_image_interleaved基本适合所有格式的转化,操作简单且可以进行ROI操作,因为大部分相机采相为1个总指针,所以gen_image_interleaved适用范围非常广,所以我们首先结合Halcon的例子来展示一下这个算子的魅力。
*1.读取图像
read_image (Image, ‘lena’)
*2.将图像分离为三通道后合并得到图像总指针(这一步是一个外部函数,大家不必关心,因为相机SDK基本可以直接拿到这个指针)
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图像由内存中转化为HImage
gen_image_interleaved (BImageRGB1, Pointer,’rgb’, Width / 3, Height, -1, ‘byte’, 0, 0, 0, 0, -1, 0)
stop ()
*4图像由内存中转化为HImage,并进行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,展示这个功能主要是想提醒小伙伴,如果转化火来颜色不对,可能是由于格式选择错误
gen_image_interleaved (BImageBGR1, Pointer,’bgr’, Width / 3, Height, -1, ‘byte’, 0, 0, 0, 0, -1, 0)
原图
RGB转化结果
快速ROI
BGR转化
接下来我们将结合度申相机SDK来展示如何从将图像由内存转化至HImage
首先我们来看度申相机SDK的采相回调函数如下:
public int _dvpStreamCallback (uint handle, dvpStreamEvent _event, IntPtrpContext, refdvpFrame refFrame, IntPtr pBuffer)
handle——相机句柄
refFrame——帧信息
pBuffer——数据内存指针
那么数据内存指针就有了,接着我们查看帧信息中有什么,打开类定义如下
publicstructdvpFrame
{
[Description(“是否水平翻转”)]
publicbyte bFlipHorizontalState;
[Description(“是否垂直翻转”)]
publicbyte bFlipVerticalState;
[Description(“位宽”)]
publicdvpBits bits;
[Description(“是否逆时针旋转”)]
publicbyte bRotateOpposite;
[Description(“是否旋转90度”)]
publicbyte bRotateState;
[Description(“模拟增益”)]
publicfloat fAGain;
[Description(“曝光时间(微秒)”)]
publicdouble fExposure;
[Description(“格式”)]
publicdvpImageFormat format;
[Description(“高度”)]
publicint iHeight;
[Description(“宽度”)]
publicint iWidth;
[Description(“像素点的位置”)]
publicdvpFirstPosition position;
[Description(“保留字节”)]
publicuint[] reserved;
[Description(“字节数”)]
publicuint uBytes;
[Description(“帧编号”)]
publiculong uFrameID;
[Description(“时间戳”)]
publiculong uTimestamp;
}
gen_image_interleaved(: ImageRGB : PixelPointer, ColorFormat, OriginalWidth, OriginalHeight, Alignment, Type, ImageWidth, ImageHeight, StartRow,StartColumn, BitsPerChannel, BitShift : )
从帧信息中可以得到图像格式、位数、图像宽度、图像高度,于是gen_image_interleaved的必备参数全部得到。
写到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);//格式转换
}
GC.GetTotalMemory(true);//需要实时将图像的内存回收掉,防止占用过多CPU资源控制系统垃圾回收器,专制内存不足
}
参考这个相机SDK采相转HImage的例子,各位小伙伴应该学会如何使用相机SDK再Halcon中采相了吧。