DALSA网口线扫相机SDK开发详解例程(C#版)

我的开发硬件、软件信息:

操作系统:windows 10、windows 7 64bit都有

线扫相机:Dalsa Linea Mono 4k 26 kHz GigE (LA-GM-04K08A)

IDE :Visual studio 2013

第一篇文章我直接运行代码报错了,是到了跟Dalsa相关的dll的语句时报错的。Win 10系统很扯淡,报错的提示一点都看不懂,我换Win 7的系统后,也报错,但是明确把错误原因找出来了。其实是Dalsa的dll中有低版本.Net Framework的代码,导致不兼容。解决的办法,网上一大推,核心就一句:在app.config的合适位置,加这句话useLegacyV2RuntimeActivationPolicy=”true”。

如果没有app.config文件,你就需要创建这个文件。

我的app.config文件内容如下:

<?xml version="1.0" encoding="utf-8"?>

现在你需要把我上文提到的两篇博客仔细看一下了。

……

看完了吗?看完了的话,接着往下看我的文章。

首先学习一下相机配置文件(.ccf)如何生成:

① 打开相机软件Sapera CamExpert,确保相机已经正常工作,然后自己改变到合适的参数;

② 点击软件左上角的File——Save As…,选择文件夹路径,修改文件名。

我的解决方案资源结构如下:

因为我是用Halcon显示图片,因此我添加了两个dll引用。除了app.config之外,我所有自己编写的代码全部在Form1.cs中。其实相当于我把全部源代码一字不漏全告诉你了。

我的Form1界面如下:

(点击Init初始化,会弹出该线阵相机的型号)

然后点击“snap”的话,它会连续采集15张图,并保存,如下:

Form1.cs的全部内容如下:

复制代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using DALSA.SaperaLT.SapClassBasic;
10 using HalconDotNet;
11
12 namespace WinDalsa
13 {
14 public partial class Form1 : Form
15 {
16 private SapLocation m_ServerLocation; // 设备的连接地址
17 private SapAcqDevice m_AcqDevice; // 采集设备
18 private SapBuffer m_Buffers; // 缓存对象
19 private SapAcqDeviceToBuf m_Xfer; // 传输对象
20
21 public Form1()
22 {
23 InitializeComponent();
24 }
25
26
27 private void Form1_Load(object sender, EventArgs e)
28 {
29
30 }
31
32 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
33 {
34 DestroyObjects();
35 DisposeObjects();
36 }
37
38
39 private void btn_init_Click(object sender, EventArgs e)
40 {
41 CreateNewObjects();
42 }
43
44 private void btn_setting_Click(object sender, EventArgs e)
45 {
46 //设置曝光值,为了设置的值不超限,需要获取曝光值的允许范围(主要是最大值)
47 double valuetemp = GetMaxValue(“ExposureTime”);
48 if (valuetemp > 0)
49 {
50 m_AcqDevice.SetFeatureValue(“ExposureTime”, valuetemp);
51 }
52
53 m_AcqDevice.SetFeatureValue(“Gain”, “9.9”);
54 }
55
56
57 // 获得相机部分属性的值
58 private void btn_getValue_Click(object sender, EventArgs e)
59 {
60 string deviceModelName;
61 string deviceUserId;
62 string pixelFormat;
63 string triggerMode;
64
65 double acquisitionLineRate; //行频和曝光时间不能设置为int类型
66 double exposureTime;
67 double gain;
68 int width;
69 int height;
70 int sensorWidth;
71 int sensorHeight;
72
73
74 m_AcqDevice.GetFeatureValue(“DeviceModelName”, out deviceModelName); //Linea M4096-7um
75 m_AcqDevice.GetFeatureValue(“DeviceUserID”, out deviceUserId); //空
76 m_AcqDevice.GetFeatureValue(“PixelFormat”, out pixelFormat); //Mono8
77 m_AcqDevice.GetFeatureValue(“TriggerMode”, out triggerMode); //Off
78
79 m_AcqDevice.GetFeatureValue(“AcquisitionLineRate”, out acquisitionLineRate); //10000.0
80 m_AcqDevice.GetFeatureValue(“ExposureTime”, out exposureTime); //70.0
81 m_AcqDevice.GetFeatureValue(“Gain”, out gain); //9.0
82 m_AcqDevice.GetFeatureValue(“Width”, out width); //4096
83 m_AcqDevice.GetFeatureValue(“Height”, out height); //2800
84 m_AcqDevice.GetFeatureValue(“SensorWidth”, out sensorWidth); //4096
85 m_AcqDevice.GetFeatureValue(“SensorHeight”, out sensorHeight); //1
86
87 }
88
89
90 #region 单步采集、连续采集、冻结采集
91 private void btn_snap_Click(object sender, EventArgs e)
92 {
93
94 //Snap()只采集一张,如果是Snap(15)则连续采集15张
95 m_Xfer.Snap(15);//m_Xfer.Snap(m_Buffers.Count)
96 }
97
98 private void btn_grab_Click(object sender, EventArgs e)
99 {
100 m_Xfer.Grab();
101 }
102
103 private void btn_freeze_Click(object sender, EventArgs e)
104 {
105 m_Xfer.Freeze(); //还有m_Xfer.Abort()的用法;
106
107 }
108
109 #endregion
110
111
112
113 //得到所有连接的相机信息,并将它们加入到ArrayList里面去
114 public bool GetCameraInfo(out string sCameraName, out int nIndex)
115 {
116 sCameraName = “”;
117 nIndex = 0;
118
119 int serverCount = SapManager.GetServerCount();
120 int GenieIndex = 0;
121 System.Collections.ArrayList listServerNames = new System.Collections.ArrayList();
122
123 bool bFind = false;
124 string serverName = “”;
125 for (int serverIndex = 0; serverIndex < serverCount; serverIndex++)
126 {
127 if (SapManager.GetResourceCount(serverIndex, SapManager.ResourceType.AcqDevice) != 0)
128 {
129 serverName = SapManager.GetServerName(serverIndex);
130 listServerNames.Add(serverName);
131 GenieIndex++;
132 bFind = true;
133 }
134 }
135
136 int count = 1;
137 string deviceName = “”;
138 foreach (string sName in listServerNames)
139 {
140 deviceName = SapManager.GetResourceName(sName, SapManager.ResourceType.AcqDevice, 0);
141 count++;
142 }
143
144 sCameraName = serverName;
145 nIndex = GenieIndex;
146
147 return bFind;
148 }
149
150
151
152 private bool CreateNewObjects()
153 {
154
155 string Name;
156 int Index;
157 bool RTemp = GetCameraInfo(out Name, out Index);
158 if (RTemp)
159 {
160 MessageBox.Show(Name);
161 }
162 else
163 {
164 MessageBox.Show(“Get camera info false!”);
165 return false;
166 }
167
168
169 m_ServerLocation = new SapLocation(Name, 0);
170
171
172 // 创建采集设备,new SapAcqDevice()的括号中第二个参数既可以写配置文件路径,也可以写false,猜测false是用相机当前的设置
173 //m_AcqDevice = new SapAcqDevice(m_ServerLocation, false);
174 m_AcqDevice = new SapAcqDevice(m_ServerLocation, @“C:\Users\xh6300\Desktop\dalsa_win7_develop\gray\T_Linea_M4096-7um_Default_Default_2800.ccf”);
175
176
177 if (m_AcqDevice.Create() == false)
178 {
179 DestroyObjects();
180 DisposeObjects();
181 return false;
182 }
183 // 创建缓存对象
184 if (SapBuffer.IsBufferTypeSupported(m_ServerLocation, SapBuffer.MemoryType.ScatterGather))
185 {
186 m_Buffers = new SapBufferWithTrash(2, m_AcqDevice, SapBuffer.MemoryType.ScatterGather);
187 }
188 else
189 {
190 m_Buffers = new SapBufferWithTrash(2, m_AcqDevice, SapBuffer.MemoryType.ScatterGatherPhysical);
191 }
192 if (m_Buffers.Create() == false)
193 {
194 DestroyObjects();
195 DisposeObjects();
196 return false;
197 }
198
199 m_AcqDevice.SetFeatureValue(“AcquisitionLineRate”, 20000.0); //注意:行频在相机工作时不能设置(曝光、增益可以),最好在初始化阶段设置
200
201 // 创建传输对象
202 m_Xfer = new SapAcqDeviceToBuf(m_AcqDevice, m_Buffers);
203 m_Xfer.XferNotify += new SapXferNotifyHandler(m_Xfer_XferNotify);
204 m_Xfer.XferNotifyContext = this;
205 m_Xfer.Pairs[0].EventType = SapXferPair.XferEventType.EndOfFrame;
206 m_Xfer.Pairs[0].Cycle = SapXferPair.CycleMode.NextWithTrash;
207 if (m_Xfer.Pairs[0].Cycle != SapXferPair.CycleMode.NextWithTrash)
208 {
209 DestroyObjects();
210 DisposeObjects();
211 return false;
212 }
213 if (m_Xfer.Create() == false)
214 {
215 DestroyObjects();
216 DisposeObjects();
217 return false;
218 }
219 return true;
220 }
221
222
223 private void DestroyObjects()
224 {
225 if (m_Xfer != null && m_Xfer.Initialized)
226 m_Xfer.Destroy();
227 if (m_Buffers != null && m_Buffers.Initialized)
228 m_Buffers.Destroy();
229 if (m_AcqDevice != null && m_AcqDevice.Initialized)
230 m_AcqDevice.Destroy();
231 }
232
233 private void DisposeObjects()
234 {
235 if (m_Xfer != null)
236 { m_Xfer.Dispose(); m_Xfer = null; }
237 if (m_Buffers != null)
238 { m_Buffers.Dispose(); m_Buffers = null; }
239 if (m_AcqDevice != null)
240 { m_AcqDevice.Dispose(); m_AcqDevice = null; }
241 }
242
243
244 private static int picCountNum = 0; //统计采集了多少张图,有利于理解m_Xfer.Snap(15)中15的意思
245
246 void m_Xfer_XferNotify(object sender, SapXferNotifyEventArgs argsNotify)
247 {
248 //首先需判断此帧是否是废弃帧,若是则立即返回,等待下一帧(但这句话似乎有时候m_Xfer.Snap(n)时会导致丢帧,可以注释掉试试)
249 if (argsNotify.Trash) return;
250
251 //获取m_Buffers的地址(指针),只要知道了图片内存的地址,其实就能有各种办法搞出图片了(例如转成Bitmap)
252 IntPtr addr;
253 m_Buffers.GetAddress(out addr);
254
255 //观察buffer中的图片的一些属性值,语句后注释里面的值是可能的值
256 int count = m_Buffers.Count; //2
257 SapFormat format = m_Buffers.Format; //Uint8
258 double rate = m_Buffers.FrameRate; //30.0,连续采集时,这个值会动态变化
259 int height = m_Buffers.Height; //2800
260 int weight = m_Buffers.Width; //4096
261 int pixd = m_Buffers.PixelDepth; //8
262
263 //显示实时帧率
264 UpdateFrameRate();
265 lbl_FrameRate.BeginInvoke(new Action(() => { lbl_FrameRate.Text = m_Buffers.FrameRate.ToString();}));
266
267 //利用halcon从内存中采集图片并保存
268 HObject ImageTemp = null;
269 HOperatorSet.GenImage1(out ImageTemp, “byte”, 4096, 2000, addr);//取内存数据,生成图像,halcon实现
270
271 hWindowControl1.HalconWindow.SetPart(0, 0, 2000, 4096);
272 HOperatorSet.DispObj(ImageTemp, hWindowControl1.HalconWindow);
273 picCountNum++;
274 HOperatorSet.WriteImage(ImageTemp, “bmp”, 0, “C:\Users\xh6300\Desktop\tt\” + picCountNum);
275
276 }
277
278
279 private void UpdateFrameRate()
280 {
281 if (m_Xfer.UpdateFrameRateStatistics())
282 {
283 float framerate = 0.0f;
284 SapXferFrameRateInfo stats = m_Xfer.FrameRateStatistics;
285
286 if (stats.IsBufferFrameRateAvailable)
287 framerate = stats.BufferFrameRate;
288 else if (stats.IsLiveFrameRateAvailable && !stats.IsLiveFrameRateStalled)
289 framerate = stats.LiveFrameRate;
290
291 m_Buffers.FrameRate = framerate;
292 }
293 }
294
295
296
297 //获得相机参数的最大值(行频和曝光时间是近似倒数的关系,获得参数最大值可以防止设置参数超限)
298 private double GetMaxValue(string featureName)
299 {
300 SapFeature feature = new SapFeature(m_ServerLocation);
301 if (!feature.Create())
302 return -1;
303 if (!m_AcqDevice.GetFeatureInfo(featureName, feature))
304 return -1;
305 double maxValue = 0;
306 if (!feature.GetValueMax(out maxValue))
307 return -1;
308 return maxValue;
309 }
310
311
312 //这个一般用得少,最小值一般是很小的数(比如Gain最小0.125,width最小128),我们一般不会设置这样的数
313 private double GetMinValue(string featureName)
314 {
315 SapFeature feature = new SapFeature(m_ServerLocation);
316 if (!feature.Create())
317 return -1;
318 if (!m_AcqDevice.GetFeatureInfo(featureName, feature))
319 return -1;
320 int minValue = 0;
321 if (!feature.GetValueMin(out minValue))
322 return -1;
323 return minValue;
324 }
325 }
326 }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值