Class1.cs
13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
namespace Asa
{
/// <summary>
/// Careray平板图像
/// </summary>
public class CarerayImage
{
private byte[] buffer;
private API.CR_EventID eventID;
private API.CallbackDelegate callback;
private const int HEAD = 64;
private const int DEV_INDEX = 1;
private const int MODE_ID = 103;
private readonly log4net.ILog LOG;
/// <summary>
/// Careray平板图像
/// </summary>
public CarerayImage(string logName = "CarerayImage")
{
callback = new API.CallbackDelegate(Process);
LOG = log4net.LogManager.GetLogger(logName);
}
/// <summary>
/// 窗宽
/// </summary>
public int WindowWidth { set; get; }
/// <summary>
/// 窗位
/// </summary>
public int WindowLevel { set; get; }
/// <summary>
/// 图像宽度
/// </summary>
public int ImageWidth { private set; get; }
/// <summary>
/// 图像高度
/// </summary>
public int ImageHeight { private set; get; }
/// <summary>
/// IP地址
/// </summary>
public string IP { private set; get; }
/// <summary>
/// 打开设备
/// </summary>
/// <returns></returns>
public bool Open()
{
int rtn;
//注册回调函数
callback = new API.CallbackDelegate(Process);
rtn = API.CR_RegisterEventCallbackFun(DEV_INDEX, callback);
LOG.Info("CR_RegisterEventCallbackFun Return " + rtn);
if (rtn != 0) return false;
GC.KeepAlive(callback);
//连接设备
rtn = API.CR_Connect(DEV_INDEX);
LOG.Info("CR_Connect Return " + rtn);
if (rtn != 0) return false;
//获取IP
rtn = API.CR_GetDetectorIndexAndIPAddress(out API.CR_DetrIdxAndIPAddr pDetrIdxAndIPAddr, out int pDetrNum);
LOG.Info("CR_GetDetectorIndexAndIPAddress Return " + rtn + " DetrNum=" + pDetrNum);
if (rtn != 0) return false;
int len = Array.FindIndex(pDetrIdxAndIPAddr.szIPAddr, b => b == 0);
IP = System.Text.Encoding.ASCII.GetString(pDetrIdxAndIPAddr.szIPAddr, 0, len);
//重置不重启
rtn = API.CR_ResetDetector(DEV_INDEX, false);
LOG.Info("CR_ResetDetector Return " + rtn);
if (rtn != 0) return false;
//获取应用模式
API.CR_ModeInfo[] pModeInfo = new API.CR_ModeInfo[10];
for (int i = 0; i < pModeInfo.Length; i++)
pModeInfo[i] = new API.CR_ModeInfo();
rtn = API.CR_GetApplicationMode(DEV_INDEX, pModeInfo, out int pModeNum);
LOG.Info("CR_GetApplicationMode Return " + rtn + " ModeNum=" + pModeNum);
if (rtn != 0) return false;
//获取图像宽度高度
for (int i = 0; i < pModeNum; i++)
{
if (pModeInfo[i].nModeID == MODE_ID)
{
ImageWidth = pModeInfo[i].nImageWidth;
ImageHeight = pModeInfo[i].nImageHeight;
break;
}
}
//设置参数
float pFrameRate = 1.2f; //帧率
int pExposureTime = 0; //积分时间
int nTriggType = 9; //触发类型,内触发
int nGainIndex = 6; //增益
rtn = API.CR_SetApplicationModeWithParam(DEV_INDEX, MODE_ID, ref pFrameRate, ref pExposureTime, nTriggType, nGainIndex);
LOG.Info(string.Format("CR_SetApplicationModeWithParam({0},{1},{2},{3},{4},{5}) Return {6}", DEV_INDEX, MODE_ID, pFrameRate, pExposureTime, nTriggType, nGainIndex, rtn));
if (rtn != 0) return false;
return true;
}
/// <summary>
/// 关闭设备
/// </summary>
/// <returns></returns>
public bool Close()
{
int rtn;
//还在采集图像
if (eventID == API.CR_EventID.CR_EVT_NEW_FRAME)
{
rtn = API.CR_StopAcquisition(DEV_INDEX);
LOG.Info("CR_StopAcquisition Return " + rtn);
}
//关闭设备
rtn = API.CR_Disconnect(DEV_INDEX);
LOG.Info("CR_Disconnect Return " + rtn);
if (rtn != 0) return false;
return true;
}
/// <summary>
/// 获取图像
/// </summary>
/// <returns></returns>
public bool GetImage()
{
buffer = new byte[ImageWidth * ImageHeight * 2 + HEAD];
for (int i = 0; i < buffer.Length; i++)
buffer[i] = 255;
int rtn;
rtn = API.CR_StartAcquisition(DEV_INDEX, 1, buffer);
LOG.Info("CR_StartAcquisition Return " + rtn);
if (rtn != 0) return false;
System.Threading.Thread.Sleep(5000);
rtn = API.CR_StopAcquisition(DEV_INDEX);
LOG.Info("CR_StopAcquisition Return " + rtn);
if (rtn != 0) return false;
return true;
}
/// <summary>
/// 加载本地RAW图片,64字节头
/// </summary>
/// <param name="filePath"></param>
public void LoadRAW(string filePath)
{
buffer = System.IO.File.ReadAllBytes(filePath);
}
/// <summary>
/// 获取48位RGB图像
/// </summary>
/// <returns></returns>
public Bitmap Get48bImage()
{
if (buffer == null) return null;
int count = ImageWidth * ImageHeight;
byte[] gray = new byte[count * 2];
Array.Copy(buffer, HEAD, gray, 0, gray.Length);
int idx1 = 0;
int idx2 = 0;
int half = WindowWidth / 2;
byte[] buff = new byte[gray.Length * 3];
for (int i = 0; i < count; i++)
{
short point = BitConverter.ToInt16(gray, idx1);
point += 20000;
if (point < WindowLevel - half)
{
buff[idx2++] = 0;
buff[idx2++] = 0;
buff[idx2++] = 0;
buff[idx2++] = 0;
buff[idx2++] = 0;
buff[idx2++] = 0;
}
else if (point > WindowLevel + half)
{
//buff[idx2++] = 255;
//buff[idx2++] = 127;
//buff[idx2++] = 255;
//buff[idx2++] = 127;
//buff[idx2++] = 255;
//buff[idx2++] = 127;
buff[idx2++] = 255;
buff[idx2++] = 255;
buff[idx2++] = 255;
buff[idx2++] = 255;
buff[idx2++] = 255;
buff[idx2++] = 255;
}
else
{
byte[] bb = BitConverter.GetBytes(point);
buff[idx2++] = bb[0];
buff[idx2++] = bb[1];
buff[idx2++] = bb[0];
buff[idx2++] = bb[1];
buff[idx2++] = bb[0];
buff[idx2++] = bb[1];
}
idx1 += 2;
}
Bitmap bmp = new Bitmap(ImageWidth, ImageHeight, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, ImageWidth, ImageHeight), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
Marshal.Copy(buff, 0, bmpData.Scan0, bmpData.Stride * ImageHeight);
bmp.UnlockBits(bmpData);
return bmp;
}
internal void Process(int nEventID, ref API.CR_Event pEvent)
{
eventID = (API.CR_EventID)nEventID;
LOG.Debug(string.Format("nEventID={0} {1}", nEventID, eventID));
Debug.Print("nEventID=" + nEventID);
}
}
internal static class API
{
[DllImport("CRInterface.dll")]
internal static extern int CR_Connect(int nDetrIndex);
[DllImport("CRInterface.dll")]
internal static extern int CR_Disconnect(int nDetrIndex);
[DllImport("CRInterface.dll")]
internal static extern int CR_GetSystemInformation(int nDetrIndex, out CR_SystemInfo pSystemInformation);
[DllImport("CRInterface.dll")]
internal static extern int CR_ResetDetector(int nDetrIndex, bool needReboot);
[DllImport("CRInterface.dll")]
internal static extern int CR_StartAcquisition(int nDetrIndex, int nFrameNum, [In, Out] byte[] pBuffer, int nNumFrmReqFromDetr = -1); // nNumFrmReqFromDetr == -1 means that detector sends out frames continuously until StopAcquisition() is received.
[DllImport("CRInterface.dll")]
internal static extern int CR_StopAcquisition(int nDetrIndex);
[DllImport("CRCallback.dll")]
internal static extern int CR_RegisterEventCallbackFun(int nDetrIndex, CallbackDelegate pCallback);
[DllImport("CRInterface.dll")]
internal static extern int CR_SetApplicationMode(int nDetrIndex, int nModeIndex);
[DllImport("CRInterface.dll")]
internal static extern int CR_GetApplicationMode(int nDetrIndex, [In, Out] CR_ModeInfo[] pModeInfo, out int pModeNum);
[DllImport("CRInterface.dll")]
internal static extern int CR_GetDetectorIndexAndIPAddress(out CR_DetrIdxAndIPAddr pDetrIdxAndIPAddr, out int pDetrNum);
[DllImport("CRInterface.dll")]
internal static extern int CR_SetApplicationModeWithParam(int nDetrIndex, int nModeIndex, ref float pFrameRate, ref int pExposureTime, int nTriggType, int nGainIndex);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void CallbackDelegate(int nEventID, ref CR_Event pEvent);
[StructLayout(LayoutKind.Sequential)]
internal struct CR_Event
{
internal int nDetrIndex;
internal int nWidth;
internal int nHeight;
internal int nPixelDepth;
internal int pData;
}
[StructLayout(LayoutKind.Sequential)]
internal struct CR_SystemInfo
{
internal uint nRawImageWidth;
internal uint nRawImageHeight;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szHardwareVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szSerialNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szSoftwareVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szFirmwareVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szDetrMachineID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
internal byte[] szDetrDesc;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
internal byte[] szReserved;
}
[StructLayout(LayoutKind.Sequential)]
internal struct CR_ModeInfo
{
internal int nModeID; // Application mode ID
internal int nImageWidth;
internal int nImageHeight;
internal int nCutoffX;
internal int nCutoffY;
internal int nBinX; // Binning scheme along X direction
internal int nBinY; // Binning scheme along Y direction
internal float fMaxFrmRate; // Maximal frame rate in fps
internal int nMaxExpTime; // Maximal exposure time in ms
internal int nPixelDepth; // Pixel depth in bits
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
internal int[] nTrigTypes;
internal int nTrigTypeNum; // 0 - 15
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
internal int[] nGainLevels;
internal int nGainLevelNum; // 0 - 15
internal int nDefaultTrigType; // Default trigger type
internal int nDefaultGainLevel; // Default gain level
internal int nRoiX;
internal int nRoiY;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
internal byte[] szDesc; // Additional description
}
[StructLayout(LayoutKind.Sequential)]
internal struct CR_DetrIdxAndIPAddr
{
internal int nIdx;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] szIPAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
internal byte[] szReserved;
}
internal enum CR_EventID
{
CR_EVT_SERVER_DISCONNECTED,
CR_EVT_DETR_DISCONNECTED,
CR_EVT_EXPOSURE_INFO,
CR_EVT_TEMPERATURE_INFO,
CR_EVT_BATTERY_INFO,
CR_EVT_WIRELESS_INFO,
CR_EVT_NEW_FRAME,
CR_EVT_CALIBRATION_IN_PROGRESS,
CR_EVT_CALIBRATION_FINISHED,
CR_EVT_ACQ_STAT_INFO
};
}
}