首页 > 编程语言 >DALSA工业相机SDK二次开发(图像采集及保存)C#

DALSA工业相机SDK二次开发(图像采集及保存)C#

时间:2023-02-03 14:22:06浏览次数:52  
标签:C# AcqDevice private int DALSA 二次开发 Xfer Buffers out

一,首先先配置生成项目,根据官方文档步骤来:

这个没啥好说的,一步步照做就是了,就最后一步,开始我没重视,最后代码写完测试的时候还真的遇到问题了,一直出这样的错:

 查了官方文档才看到最后一条~,然后在项目属性中把这个勾掉了,代码完美运行拉……

二,功能步骤

其实整个步骤很简单:

1,首先初始化连接相机:点击Init按钮会有MessageBox打印相机名

2,然后读取配置文件(配置文件是通过官方自带的CamExpert来生成的)读取参数,也可以在程序中配置,本程序有个setting按钮,按一下就可以配置拉,把想配置的参数写在对应的代码块里(当然小编很懒,没做显示的功能,所以按按钮的时候你可能觉得按了个寂寞,但已经配置好了)。还有个读取参数的按钮(当然小编也没做显示的功能,所以也按了个寂寞),但有助于debug的时候查看数据,也可以自己打印出来看看。

3,Snap是快照,可以设置快照的张数,因为写本程序时只有相机没有镜头,所以是黑乎乎一片…但用光源照的时候会呈现白色,所以还是有点反应知道不是卡住的哈哈。

4,Grab就是连续抓取图像了,Freeze是停止。

5,最后的保存结果(没有镜头只能可怜巴巴的用感光性来测试了T_T)

PS:程序最重要的是一个回调函数:m_Xfer_XferNotify,每读取一帧图片的时候会调用这个函数,当然回调函数是自己加的,通过这个命令:

m_Xfer.XferNotify += new SapXferNotifyHandler(m_Xfer_XferNotify);

这条命令和m_Xfer_XferNotify函数是精髓!精髓!精髓!

没啥说的,上代码。可运行代码一字不差的放上来咯,注释也尽可能详细了:

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

 

标签:C#,AcqDevice,private,int,DALSA,二次开发,Xfer,Buffers,out
From: https://www.cnblogs.com/ybqjymy/p/17089086.html

相关文章