DALSA相机SDK不完全教程
1、SDK介绍
Dalsa是全球顶尖的CCD/CMOS芯⽚和相机制造商,总部位于加拿⼤,我使⽤的是 Dalsa的 Genie_TS_M1920(⿊⽩)和
Genie_TS_C2048(彩⾊)两款⼯业相机。
打开SDK包,SDK⽂件和例程在 Sapera⽂件夹中,SDK分x64和x86两个版本,x86的版本不能在64位机器上运⾏,x64的版本不能在32位机器上运⾏。
打开后
2、C#的使⽤⽅法
1)添加类库的引⽤,即Components/Net/Bin/DALSA.SaperaLT.SapClassBasic.dll⽂件的引⽤,注意x64和x86的版本问题。
2)声明SaperaLT的对象
我没有使⽤SDK中的视图对象,⽽是从缓存中取出图像数据转为C#的Bitmap,这样更灵活,所以不需要声明 SapView。
private SapLocation m_ServerLocation; // 设备的连接地址
private SapAcqDevice m_AcqDevice; // 采集设备
private SapBuffer m_Buffers; // 缓存对象
private SapAcqDeviceToBuf m_Xfer; // 传输对象
3)创建对象
private bool CreateNewObjects()
{
// 创建采集设备
m_AcqDevice = new SapAcqDevice(m_ServerLocation, false);
if (m_AcqDevice.Create() == false)
{
DestroyObjects();
DisposeObjects();
return false;
}
// 创建缓存对象
if (SapBuffer.IsBufferTypeSupported(m_ServerLocation, SapBuffer.MemoryType.ScatterGather))
{
m_Buffers = new SapBufferWithTrash(2, m_AcqDevice, SapBuffer.MemoryType.ScatterGather);
}
else
{
m_Buffers = new SapBufferWithTrash(2, m_AcqDevice, SapBuffer.MemoryType.ScatterGatherPhysical);
}
if (m_Buffers.Create() == false)
{
DestroyObjects();
DisposeObjects();
return false;
}
// 创建传输对象
m_Xfer = new SapAcqDeviceToBuf(m_AcqDevice, m_Buffers);
m_Xfer.XferNotify += new SapXferNotifyHandler(m_Xfer_XferNotify);
m_Xfer.XferNotifyContext = this;
m_Xfer.Pairs[0].EventType = SapXferPair.XferEventType.EndOfFrame;
m_Xfer.Pairs[0].Cycle = SapXferPair.CycleMode.NextWithTrash;
if (m_Xfer.Pairs[0].Cycle != SapXferPair.CycleMode.NextWithTrash)
{
DestroyObjects();
DisposeObjects();
return false;
}
if (m_Xfer.Create() == false)
sdk{
DestroyObjects();
DisposeObjects();
return false;
}
return true;
}
4)销毁对象
private void DestroyObjects()
{
if (m_Xfer != null && m_Xfer.Initialized)
m_Xfer.Destroy();
if (m_Buffers != null && m_Buffers.Initialized)
m_Buffers.Destroy();
if (m_AcqDevice != null && m_AcqDevice.Initialized)
m_AcqDevice.Destroy();
}
private void DisposeObjects()
{
if (m_Xfer != null)
{ m_Xfer.Dispose(); m_Xfer = null; }
if (m_Buffers != null)
{ m_Buffers.Dispose(); m_Buffers = null; }
if (m_AcqDevice != null)
{ m_AcqDevice.Dispose(); m_AcqDevice = null; }
}
5)获取参数值及最⼤值、最⼩值
参数值的类型有string,int,double,bool⼏种,需根据参数的可能值类型选择对应的⽅法,否则会出错。⽂本型:
string val;
m_AcqDevice.GetFeatureValue(featureName, out val));
整数型:
int val;
m_AcqDevice.GetFeatureValue(featureName, out val));
⼩数型:
double val;
m_AcqDevice.GetFeatureValue(featureName, out val));
布尔型:
boolean val;
m_AcqDevice.GetFeatureValue(featureName, out val));
常⽤参数的值类型
中⽂名参数名值类型
图像X坐标OffsetX int
图像Y坐标OffsetY int
图像宽度Width int
图像⾼度Height int
采集帧率AcquisitionFrameRate double
曝光时间ExposureTime double
外触发⽅式TriggerMode bool
获取参数最⼤值,以整数类型举例:
SapFeature feature = new SapFeature(m_ServerLocation);
if (!feature.Create())
return -1;
if (!m_AcqDevice.GetFeatureInfo(featureName, feature))
return -1;
int maxValue = 0;
if (!feature.GetValueMax(out maxValue))
return -1;
return maxValue;
获取参数最⼩值,以整数类型举例:
SapFeature feature = new SapFeature(m_ServerLocation);
if (!feature.Create())
return -1;
if (!m_AcqDevice.GetFeatureInfo(featureName, feature))
return -1;
int minValue = 0;
if (!feature.GetValueMin(out minValue))
return -1;
return minValue;
6)设置参数值
设置参数值同样需要根据参数的值类型,选择对应的设参⽅法,否则会出现报错的情况,我发现使⽤字符型可以兼容,所以可以把值转为字符型,再设参。
string value;
m_AcqDevice.SetFeatureValue(featureName, value);
根据实际使⽤发现,曝光时间可以在采集过程中设置,采集帧率在采集过程中设置不能⽴即⽣效,需在下次采集⽅能⽣效,⽽X、Y坐标及图形宽度、⾼度、外触发模式需在设备对象创建后,缓存对象创建前进⾏设置,否则报错。
7)图形采集控制
开始采集:
m_Xfer.Grab();
停⽌采集:
m_Xfer.Freeze();
单张或指定张数抓拍:
m_Xfer.Snap();
8)图像获取及显⽰
开始采集后,得到每帧图像时,会触发XferNotify事件,可在此事件中进⾏图像的获取及显⽰⼯作。
⾸先需判断此帧是否是废弃帧,若是则⽴即返回,等待下⼀帧:
if (e.Trash) return;
取得缓存中的图像数据⾸地址:
IntPtr addr;
m_Buffers.GetAddress(out addr);
再将数据转为Bitmap对象:
PixelFormat pf = PixelFormat.Format8bppIndexed;
Bitmap bmp = new Bitmap(m_Buffers.Width, m_Buffers.Height, m_Buffers.Pitch, pf, addr);
bmp.Palette = m_grayPalette;
以上是8位⿊⽩图像的转换⽅法,创建图像后需给Bitmap对象赋⼀个⿊⽩调⾊板,创建调⾊板的代码如下:
using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
m_grayPalette = bmp.Palette;
}
for (int i = 0; i <= 255; i++)
{
m_grayPalette.Entries[i] = Color.FromArgb(i, i, i);
}
如果是彩⾊相机,得到的数据是Bayer格式,需⽤Bayer转换⽅法,转换为24位彩⾊图⽚,我到Aforge,OpenCV都可以进⾏Bayer转换。
Aforge的Bayer转换代码:
private BayerFilter m_bayerFilter = new BayerFilter();
m_bayerFilter.BayerPattern = new int[2, 2] { { RGB.G, RGB.B }, { RGB.R, RGB.G } };
bmp = m_bayerFilter.Apply(bmp);
OpenCV的Bayer转换代码:
IplImage *frame;
frame = cvCreateImage(cvSize(width, height), depth, 1);
frame->imageData = (char*)pData;
IplImage *bgr = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
cvCvtColor(frame, bgr, CV_BayerGR2BGR);
pDlg->ShowImage(bgr, IDC_PIC1);
cvReleaseImage(&frame);
cvReleaseImage(&bgr);
如果⽤Bitmap直接赋给PictureBox的办法,有时候会有内存泄露的情况,所以可采⽤GDI+绘图的⽅式显⽰图像,缺点是采集停⽌时,窗体
被覆盖后图像会消失。
private void DrawImageInPictureBox(PictureBox picBox, Image img)
{
Graphics g = picBox.CreateGraphics();
g.DrawImage(img, 0, 0, picBox.Width, picBox.Height);
g.Dispose();
}
9)采集图像开窗和⾯阵做线扫描
图像开窗通过设置Width和Height两参数即可,经过实验发现,横向开窗对采集帧率最⼤值没有影响,⽽竖向开窗,采集帧率最⼤值会成⽐变化,竖向最⼩可设为2,即可当做线扫描使⽤,帧率最⼤可到1~2K。
如果做线扫使⽤,可以⽤List链表来存储每帧数据,最后再合成⼤图,转成Bitmap的⽅法是⼀样的,只是注意图像的⾼度是每帧⾼度乘以帧数。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论