LineMeasure.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Drawing.Imaging;
  9. using System.Threading;
  10. using System.Diagnostics;
  11. using Extensometer.Model.RequestModel;
  12. using Extensometer.Model.ResultModel;
  13. using Extensometer.BLL;
  14. using ThridLibray;
  15. namespace LineMeasurementLib
  16. {
  17. public class ImageLinePosition
  18. {
  19. public short left;
  20. public short top;
  21. public short right;
  22. public short bottom;
  23. }
  24. /// <summary>
  25. /// 像素间距识别算法
  26. /// </summary>
  27. public class LineMeasure:IDisposable
  28. {
  29. #region 变量、类和对象
  30. private static LineMeasure lineMeasure = null;
  31. //识别列表
  32. public Queue<IdentifResultClass> BitmapList = new Queue<IdentifResultClass>();
  33. //识别结果列表
  34. public Queue<IdentifResultClass> ProcessResult = new Queue<IdentifResultClass>();
  35. public Mutex m_mutex = new Mutex();
  36. Thread ProcessThread = null;
  37. public float FirstPointLength = 0; //记录第一个结果点;
  38. public Stopwatch LineMessSW = null;
  39. #endregion
  40. #region 方法
  41. /// <summary>
  42. /// 释放
  43. /// </summary>
  44. public void Dispose()
  45. {
  46. Release();
  47. }
  48. /// <summary>
  49. /// 构造方法
  50. /// </summary>
  51. private LineMeasure()
  52. {
  53. _lmInitPara.stLineDetPara = new LM_LINEDET_PARA_S[LM_LINE_NUM_MAX];
  54. }
  55. /// <summary>
  56. /// 提供给外部获取实例的方法
  57. /// </summary>
  58. /// <returns></returns>
  59. public static LineMeasure GetLineMeasure()
  60. {
  61. if (lineMeasure == null)
  62. {
  63. lineMeasure = new LineMeasure();
  64. }
  65. return lineMeasure;
  66. }
  67. /// <summary>
  68. /// 算法初始化
  69. /// </summary>
  70. /// <param name="cfgFile"></param>
  71. /// <param name="distFile"></param>
  72. /// <returns></returns>
  73. public int Init(string cfgFile, string distFile)
  74. {
  75. //AllocConsole();
  76. LoadConfigFile(cfgFile);
  77. LoadDistortionPara(distFile);
  78. WriteLine("Init Start", ConsoleColor.DarkGreen);
  79. _handle = LM_LineMeasureInit(ParaStructToPtr(_lmInitPara), 0);
  80. if (_distortionPara.iFlagEnable == 1)
  81. {
  82. LM_DistortionCalibSet(_handle, _distortionPara);
  83. }
  84. return 1;
  85. }
  86. /// <summary>
  87. /// 算法初始化
  88. /// </summary>
  89. /// <param name="cfgFile"></param>
  90. /// <param name="distFile"></param>
  91. /// <returns></returns>
  92. public int Init(RequestConfigParameterModel parameterModel, string distFile)
  93. {
  94. //AllocConsole();
  95. LoadConfigFile(parameterModel);
  96. LoadDistortionPara(distFile);
  97. WriteLine("Init Start", ConsoleColor.DarkGreen);
  98. _handle = LM_LineMeasureInit(ParaStructToPtr(_lmInitPara), 0);
  99. if (_distortionPara.iFlagEnable == 1)
  100. {
  101. LM_DistortionCalibSet(_handle, _distortionPara);
  102. }
  103. return 1;
  104. }
  105. /// <summary>
  106. /// 算法初始化-返回配置文件范围选择
  107. /// </summary>
  108. /// <param name="cfgFile"></param>
  109. /// <param name="distFile"></param>
  110. /// <param name="LinePositionList"></param>
  111. /// <returns></returns>
  112. public int Init(string cfgFile, string distFile, ref List<ImageLinePosition> LinePositionList)
  113. {
  114. AllocConsole();
  115. LoadConfigFile(cfgFile, ref LinePositionList);
  116. LoadDistortionPara(distFile);
  117. WriteLine("Init Start", ConsoleColor.DarkGreen);
  118. _handle = LM_LineMeasureInit(ParaStructToPtr(_lmInitPara), 0);
  119. if (_distortionPara.iFlagEnable == 1)
  120. {
  121. LM_DistortionCalibSet(_handle, _distortionPara);
  122. }
  123. return 1;
  124. }
  125. IntPtr ptr;
  126. LM_RULT_S res;
  127. /// <summary>
  128. /// 算法运行并返回结果
  129. /// </summary>
  130. /// <param name="grayimg">图片byte</param>
  131. /// <param name="width"></param>
  132. /// <param name="height"></param>
  133. /// <returns></returns>
  134. public LM_RULT_S Process(byte[] grayimg, int width, int height)
  135. {
  136. ptr = ResultToPtr(_result);
  137. res = new LM_RULT_S();
  138. if (B_ThreadProcess == false)
  139. {
  140. res.rultnum = 0;
  141. return res;
  142. }
  143. try
  144. {
  145. if (LM_LineMeasureProcess(_handle, grayimg, width, height, ptr) > 0)
  146. {
  147. _result = PtrToResult(ptr);
  148. if (_calibrationRes.iFlagSuccess == 1)
  149. {
  150. _result.LinePhysicaldis1 = _result.LinePixeldis1 * _calibrationRes.fConvertCoefficient;
  151. _result.LinePhysicaldis2 = _result.LinePixeldis2 * _calibrationRes.fConvertCoefficient;
  152. }
  153. else
  154. {
  155. _result.LinePhysicaldis1 = 0;
  156. _result.LinePhysicaldis2 = 0;
  157. }
  158. Marshal.FreeHGlobal(pP1);
  159. return _result;
  160. }
  161. }
  162. catch
  163. {
  164. //日志写入处
  165. }
  166. res.rultnum = 0;
  167. return res;
  168. }
  169. /// <summary>
  170. /// 算法释放
  171. /// </summary>
  172. public void Release()
  173. {
  174. LM_LineMeasureRelease(_handle);
  175. }
  176. /// <summary>
  177. /// 加载配置文件
  178. /// </summary>
  179. /// <param name="file"></param>
  180. public void LoadDistortionPara(String file)
  181. {
  182. FileStream fs = File.OpenRead(file);
  183. StreamReader sr = new StreamReader(fs);
  184. string line = sr.ReadLine();
  185. var header = line.Split(new char[] { ' ' });
  186. if (header != null && header.Length > 0)
  187. {
  188. var enable = int.Parse(header[0]);
  189. _distortionPara.iFlagEnable = enable;
  190. if (enable == 0)
  191. return;
  192. _distortionPara.iImgWidth = int.Parse(header[1]);
  193. _distortionPara.iImgHeight = int.Parse(header[2]);
  194. line = sr.ReadLine();
  195. var camMat = line.Split(new char[] { ' ' });
  196. for (int i = 0; i < 6; i++)
  197. {
  198. _distortionPara.fCammatrix[i] = double.Parse(camMat[i]);
  199. }
  200. line = sr.ReadLine();
  201. var paraK = line.Split(new char[] { ' ' });
  202. for (int i = 0; i < 3; i++)
  203. {
  204. _distortionPara.fDisK[i] = double.Parse(paraK[i]);
  205. }
  206. line = sr.ReadLine();
  207. var paraP = line.Split(new char[] { ' ' });
  208. for (int i = 0; i < 2; i++)
  209. {
  210. _distortionPara.fDisP[i] = double.Parse(paraP[i]);
  211. }
  212. line = sr.ReadLine();
  213. var corrPara = line.Split(new char[] { ' ' });
  214. for (int i = 0; i < 6; i++)
  215. {
  216. _distortionPara.fNewcammatInv[i] = double.Parse(corrPara[i]);
  217. }
  218. sr.Close();
  219. fs.Close();
  220. }
  221. else
  222. {
  223. sr.Close();
  224. fs.Close();
  225. return;
  226. }
  227. }
  228. /// <summary>
  229. /// 加载识别配置参数(文件)
  230. /// </summary>
  231. /// <param name="file"></param>
  232. public void LoadConfigFile(String file)
  233. {
  234. _lmInitPara.iLineDetNum = int.Parse(ReadString("Config", "linedetnum", "0", file));
  235. _lmInitPara.paraimgw = int.Parse(ReadString("Config", "imgw", "0", file));
  236. _lmInitPara.paraimgh = int.Parse(ReadString("Config", "imgh", "0", file));
  237. _lmInitPara.eLineDisMode = (LM_LINEDIS_MODE_E)int.Parse(ReadString("Config", "dismode", "0", file));
  238. _calibrationRes.iFlagSuccess = int.Parse(ReadString("Config", "calibsuccess", "0", file));
  239. _calibrationRes.fConvertCoefficient = float.Parse(ReadString("Config", "calibcoeff", "0.0", file));
  240. for (int i = 0; i < _lmInitPara.iLineDetNum; i++)
  241. {
  242. _lmInitPara.stLineDetPara[i].stRoirectpara.left = short.Parse(ReadString("Config", "left" + i.ToString(), "0", file));
  243. _lmInitPara.stLineDetPara[i].stRoirectpara.top = short.Parse(ReadString("Config", "top" + i.ToString(), "0", file));
  244. _lmInitPara.stLineDetPara[i].stRoirectpara.right = short.Parse(ReadString("Config", "right" + i.ToString(), "0", file));
  245. _lmInitPara.stLineDetPara[i].stRoirectpara.bottom = short.Parse(ReadString("Config", "bottom" + i.ToString(), "0", file));
  246. _lmInitPara.stLineDetPara[i].stRoirect = _lmInitPara.stLineDetPara[i].stRoirectpara;
  247. _lmInitPara.stLineDetPara[i].eGrayDir = (LM_LINE_GRAYDIR_E)int.Parse(ReadString("Config", "eGrayDir" + i.ToString(), "0", file));
  248. _lmInitPara.stLineDetPara[i].eLineDirection = (LM_LINE_DIRECTION_E)int.Parse(ReadString("Config", "eLineDirection" + i.ToString(), "0", file));
  249. _lmInitPara.stLineDetPara[i].eLineOrder = (LM_LINE_ORDER_E)int.Parse(ReadString("Config", "eLineOrder" + i.ToString(), "0", file));
  250. }
  251. return;
  252. }
  253. /// <summary>
  254. /// 加载识别配置参数(类)
  255. /// </summary>
  256. /// <param name="file"></param>
  257. public ResultModel LoadConfigFile(RequestConfigParameterModel file)
  258. {
  259. ResultModel result = new ResultModel();
  260. _lmInitPara.iLineDetNum = file.iLineDetNum;
  261. _lmInitPara.paraimgw = file.paraimgw;
  262. _lmInitPara.paraimgh = file.paraimgh;
  263. _lmInitPara.eLineDisMode = (LM_LINEDIS_MODE_E)file.eLineDisMode;
  264. _calibrationRes.iFlagSuccess = file.iFlagSuccess;
  265. _calibrationRes.fConvertCoefficient = file.fConvertCoefficient;
  266. for (int i = 0; i < _lmInitPara.iLineDetNum; i++)
  267. {
  268. _lmInitPara.stLineDetPara[i].stRoirectpara.left = file.stLineDetParas[i].LeftValue;
  269. _lmInitPara.stLineDetPara[i].stRoirectpara.top = file.stLineDetParas[i].TopValue;
  270. _lmInitPara.stLineDetPara[i].stRoirectpara.right = file.stLineDetParas[i].RightValue;
  271. _lmInitPara.stLineDetPara[i].stRoirectpara.bottom = file.stLineDetParas[i].BottomValue;
  272. _lmInitPara.stLineDetPara[i].stRoirect = _lmInitPara.stLineDetPara[i].stRoirectpara;
  273. _lmInitPara.stLineDetPara[i].eGrayDir = (LM_LINE_GRAYDIR_E)file.stLineDetParas[i].eGrayDir;
  274. _lmInitPara.stLineDetPara[i].eLineDirection = (LM_LINE_DIRECTION_E)file.stLineDetParas[i].eLineDirection;
  275. _lmInitPara.stLineDetPara[i].eLineOrder = (LM_LINE_ORDER_E)file.stLineDetParas[i].eLineOrder;
  276. }
  277. return result;
  278. }
  279. /// <summary>
  280. /// 加载配置文件并返回数据
  281. /// </summary>
  282. /// <param name="file"></param>
  283. /// <param name="linePositions"></param>
  284. public void LoadConfigFile(String file, ref List<ImageLinePosition> linePositions)
  285. {
  286. _lmInitPara.iLineDetNum = int.Parse(ReadString("Config", "linedetnum", "0", file));
  287. _lmInitPara.paraimgw = int.Parse(ReadString("Config", "imgw", "0", file));
  288. _lmInitPara.paraimgh = int.Parse(ReadString("Config", "imgh", "0", file));
  289. _lmInitPara.eLineDisMode = (LM_LINEDIS_MODE_E)int.Parse(ReadString("Config", "dismode", "0", file));
  290. _calibrationRes.iFlagSuccess = int.Parse(ReadString("Config", "calibsuccess", "0", file));
  291. _calibrationRes.fConvertCoefficient = float.Parse(ReadString("Config", "calibcoeff", "0.0", file));
  292. for (int i = 0; i < _lmInitPara.iLineDetNum; i++)
  293. {
  294. _lmInitPara.stLineDetPara[i].stRoirectpara.left = short.Parse(ReadString("Config", "left" + i.ToString(), "0", file));
  295. _lmInitPara.stLineDetPara[i].stRoirectpara.top = short.Parse(ReadString("Config", "top" + i.ToString(), "0", file));
  296. _lmInitPara.stLineDetPara[i].stRoirectpara.right = short.Parse(ReadString("Config", "right" + i.ToString(), "0", file));
  297. _lmInitPara.stLineDetPara[i].stRoirectpara.bottom = short.Parse(ReadString("Config", "bottom" + i.ToString(), "0", file));
  298. linePositions.Add(new ImageLinePosition
  299. {
  300. left = _lmInitPara.stLineDetPara[i].stRoirectpara.left,
  301. right = _lmInitPara.stLineDetPara[i].stRoirectpara.right,
  302. top = _lmInitPara.stLineDetPara[i].stRoirectpara.top,
  303. bottom = _lmInitPara.stLineDetPara[i].stRoirectpara.bottom
  304. });
  305. _lmInitPara.stLineDetPara[i].stRoirect = _lmInitPara.stLineDetPara[i].stRoirectpara;
  306. _lmInitPara.stLineDetPara[i].eGrayDir = (LM_LINE_GRAYDIR_E)int.Parse(ReadString("Config", "eGrayDir" + i.ToString(), "0", file));
  307. _lmInitPara.stLineDetPara[i].eLineDirection = (LM_LINE_DIRECTION_E)int.Parse(ReadString("Config", "eLineDirection" + i.ToString(), "0", file));
  308. _lmInitPara.stLineDetPara[i].eLineOrder = (LM_LINE_ORDER_E)int.Parse(ReadString("Config", "eLineOrder" + i.ToString(), "0", file));
  309. }
  310. return;
  311. }
  312. #endregion
  313. #region 线程方法
  314. /// <summary>
  315. /// 识别线程运行控制变量
  316. /// </summary>
  317. private bool B_ThreadProcess = false;
  318. /// <summary>
  319. /// 识别线程方法
  320. /// </summary>
  321. private void ThreadProcess()
  322. {
  323. IdentifResultClass identifResult = new IdentifResultClass();
  324. IdentifResultClass Ident = new IdentifResultClass();
  325. while (B_ThreadProcess)
  326. {
  327. if (BitmapList.Count == 0)
  328. {
  329. Thread.Sleep(10);
  330. continue;
  331. }
  332. lock(this)
  333. {
  334. Ident = BitmapList.Dequeue();
  335. }
  336. if (BitmapList.Count > 10)
  337. {
  338. LOG.error("ThreadProcess-BitmapList数据异常抛出,帧丢弃");
  339. BitmapList.Clear();
  340. }
  341. if (Ident == null) continue;
  342. LM_RULT_S result = new LM_RULT_S();
  343. LineMessSW = new Stopwatch();
  344. LineMessSW.Start();
  345. result = lineMeasure.Process(Ident.ImageByte, Ident.ImageBitMap.Width, Ident.ImageBitMap.Height);
  346. LineMessSW.Stop();
  347. //有无结果都返回
  348. if (identifResult.LinePixeldis2 == 0 && result.LinePixeldis2 != 0) { FirstPointLength = result.LinePixeldis2; }
  349. identifResult = new IdentifResultClass()
  350. {
  351. ImageBitMap = Ident.ImageBitMap,
  352. ImageByte = Ident.ImageByte,
  353. ImageTime = Ident.ImageTime,
  354. Rultnum = result.rultnum,
  355. Displacement = (identifResult.LinePixeldis2 == 0 && identifResult.Displacement == 0) ? 0 : result.LinePixeldis2 - identifResult.LinePixeldis1,
  356. StrainValue = (identifResult.LinePixeldis2 == 0 && identifResult.StrainValue == 0) ? 0 : result.LinePixeldis2 - FirstPointLength,
  357. Distance = result.LinePixeldis2,
  358. LinePixeldis1 = result.LinePixeldis1,
  359. LinePhysicaldis1 = result.LinePhysicaldis1,
  360. LinePixeldis2 = result.LinePixeldis2,
  361. LinePhysicaldis2 = result.LinePhysicaldis2,
  362. IsFunction = true
  363. };
  364. ProcessResult.Enqueue(identifResult);
  365. }
  366. }
  367. /// <summary>
  368. /// 识别线程开启
  369. /// </summary>
  370. public void ProcessStart()
  371. {
  372. //修改识别标志量,代表开始识别
  373. B_ThreadProcess = true;
  374. if (lineMeasure != null)
  375. {
  376. //加载配置文件
  377. lineMeasure.Init(@AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "lm_config.ini",
  378. @AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"coffrate.txt");
  379. }
  380. //赋予ProcessThread线程方法
  381. ProcessThread = new Thread(ThreadProcess);
  382. //清空待识别队列和识别结果队列
  383. ProcessResult.Clear();
  384. BitmapList.Clear();
  385. //运行线程
  386. ProcessThread.Start();
  387. }
  388. /// <summary>
  389. /// 识别线程开启
  390. /// </summary>
  391. public void ProcessStart(RequestConfigParameterModel parameterModel)
  392. {
  393. //修改识别标志量,代表开始识别
  394. B_ThreadProcess = true;
  395. if (lineMeasure != null)
  396. {
  397. //加载配置文件
  398. lineMeasure.Init(parameterModel,
  399. @AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "coffrate.txt");
  400. //lineMeasure.Init(parameterModel, @".\coffrate.txt");
  401. }
  402. //赋予ProcessThread线程方法
  403. ProcessThread = new Thread(ThreadProcess);
  404. //清空待识别队列和识别结果队列
  405. ProcessResult.Clear();
  406. BitmapList.Clear();
  407. //运行线程
  408. ProcessThread.Start();
  409. }
  410. /// <summary>
  411. /// 识别线程关闭
  412. /// </summary>
  413. public void ProcessStop()
  414. {
  415. B_ThreadProcess = false;
  416. lineMeasure.Dispose();
  417. }
  418. public bool GetThreadProcessStatic()
  419. {
  420. return B_ThreadProcess;
  421. }
  422. #endregion
  423. #region C++ 算法变量、结构体
  424. public const int LM_LINE_NUM_MAX = 4;
  425. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  426. public struct LM_RECT_S
  427. {
  428. public short left;
  429. public short top;
  430. public short right;
  431. public short bottom;
  432. }
  433. public enum LM_LINE_GRAYDIR_E : Int32
  434. {
  435. LINE_GRAYDIR_DEFAULT = 0, //不确定;默认由浅及深;
  436. LINE_GRAYDIR_SHALLOWTODEEP, //由浅及深;
  437. LINE_GRAYDIR_DEEPTOSHALLOW //由深及浅;
  438. }
  439. public enum LM_LINE_DIRECTION_E : Int32
  440. {
  441. LINE_DIR_DEFAULT = 0, //默认为水平方向直线;
  442. LINE_DIR_HORIZONTAL, //水平方向直线;
  443. LINE_DIR_VERTICAL //竖直方向直线;
  444. }
  445. public enum LM_LINE_ORDER_E : Int32
  446. {
  447. LINE_ORDER_DEFAULT = 0, //默认第一条线;
  448. LINE_ORDER_FIRSTLINE, //第一条线
  449. LINE_ORDER_BESTLINE, //最佳线
  450. LINE_ORDER_LASTLINE //最后一条线;
  451. }
  452. public enum LM_LINEDIS_MODE_E : Int32
  453. {
  454. LINE_DISMODE_DEFAULT = 0,
  455. LINE_DISMODE_CNTTOCNT, //中点到中点的距离;
  456. LINE_DISMODE_CNTTOLINE, //中点到直线的距离
  457. LINE_DISMODE_LINETOLINE //线到线的距离;暂不支持;
  458. }
  459. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  460. public struct LM_LINEDET_PARA_S
  461. {
  462. [MarshalAs(UnmanagedType.Struct)]
  463. public LM_RECT_S stRoirectpara;
  464. [MarshalAs(UnmanagedType.Struct)]
  465. public LM_RECT_S stRoirect; //roi区域;内部实际使用;
  466. public LM_LINE_GRAYDIR_E eGrayDir; //边缘由浅及深;0.浅及深;1,由深浅;
  467. public LM_LINE_ORDER_E eLineOrder; //第一条边;
  468. public LM_LINE_DIRECTION_E eLineDirection; //线条方向;
  469. }
  470. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  471. public struct LM_CALIB_RULT_S
  472. {
  473. public int iFlagSuccess; //是否标定成功
  474. public float fConvertCoefficient; //标定结果
  475. }
  476. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  477. public struct LM_DISCORRECT_PARA_S
  478. {
  479. public int iFlagEnable; //是否使能畸变矫正;
  480. public int iImgWidth;
  481. public int iImgHeight;
  482. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
  483. public double[] fCammatrix; //相机参数;
  484. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
  485. public double[] fNewcammatInv; //相机相关参数;
  486. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  487. public double[] fDisK; //径向畸变参数;
  488. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  489. public double[] fDisP; //切向畸变参数;
  490. }
  491. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  492. public struct LM_INIT_PARA_S
  493. {
  494. public int iLineDetNum; //线数量;
  495. public int paraimgw; //参数设置对应的w;需要换算;
  496. public int paraimgh; //参数设置对应的h;需要换算;
  497. [MarshalAs(UnmanagedType.ByValArray, SizeConst = LM_LINE_NUM_MAX, ArraySubType = UnmanagedType.LPStruct)]
  498. public LM_LINEDET_PARA_S[] stLineDetPara; //线检测参数;
  499. public LM_LINEDIS_MODE_E eLineDisMode; //距离模式;
  500. }
  501. public struct LM_POINT_S
  502. {
  503. short px;
  504. short py;
  505. }
  506. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  507. public struct LM_LINE_RULT_INFO_S
  508. {
  509. bool bIsValid;
  510. float fA;
  511. float fB;
  512. float fC;
  513. LM_POINT_S stDisPt;
  514. LM_POINT_S stStartPt;
  515. LM_POINT_S stEndPt;
  516. }
  517. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  518. public struct LM_RULT_S
  519. {
  520. public int rultnum; //线条数;
  521. public float LinePixeldis1; //结果1,像素结果;
  522. public float LinePhysicaldis1; //结果1对应的物理结果;
  523. public float LinePixeldis2; //结果2,像素结果;
  524. public float LinePhysicaldis2; //结果2对应的物理结果;
  525. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.LPStruct)]
  526. LM_LINE_RULT_INFO_S[] LineInfoF;
  527. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.LPStruct)]
  528. LM_LINE_RULT_INFO_S[] LineInfoS;
  529. }
  530. private IntPtr _handle;
  531. private LM_RULT_S _result;
  532. private LM_CALIB_RULT_S _calibrationRes;
  533. private LM_DISCORRECT_PARA_S _distortionPara;
  534. public LM_DISCORRECT_PARA_S DistortionPara
  535. {
  536. get
  537. {
  538. return _distortionPara;
  539. }
  540. set
  541. {
  542. _distortionPara = value;
  543. }
  544. }
  545. private LM_INIT_PARA_S _lmInitPara;
  546. public LM_INIT_PARA_S LMInitPara
  547. {
  548. get
  549. {
  550. return _lmInitPara;
  551. }
  552. set
  553. {
  554. _lmInitPara = value;
  555. }
  556. }
  557. #endregion
  558. #region C++DLLToC#DLL
  559. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureInit@@YAPAXPAU_LM_INIT_PARA_S_@@H@Z", CallingConvention = CallingConvention.Cdecl)]
  560. //[DllImport("LineMeasure.dll")]
  561. //[DllImport("LineMeasure.dll", EntryPoint = "#5")]
  562. private static extern IntPtr LM_LineMeasureInit([In, Out] IntPtr stInitPara, int iDebugMode);
  563. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureProcess@@YAHPAXPAEHHPAU_LM_Rult_S_@@@Z", CallingConvention = CallingConvention.Cdecl)]
  564. //[DllImport("LineMeasure.dll")]
  565. private static extern int LM_LineMeasureProcess(IntPtr handle, [In, Out]byte[] grayimg, int imgw, int imgh, [In, Out]IntPtr lmrult);
  566. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureRelease@@YAXPAX@Z", CallingConvention = CallingConvention.Cdecl)]
  567. //[DllImport("LineMeasure.dll")]
  568. private static extern void LM_LineMeasureRelease(IntPtr handle);
  569. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureCalibration@@YAXPAEHHMPAU_LM_CALIB_RULT_S_@@@Z", CallingConvention = CallingConvention.Cdecl)]
  570. //[DllImport("LineMeasure.dll")]
  571. private static extern void LM_LineMeasureCalibration(IntPtr handle, [In, Out]byte[] grayimg, int imgw, int imgh, float rangedis, [In, Out]LM_CALIB_RULT_S calibrult);
  572. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureCalibSet@@YAXPAXPAU_LM_CALIB_RULT_S_@@@Z", CallingConvention = CallingConvention.Cdecl)]
  573. //[DllImport("LineMeasure.dll")]
  574. private static extern void LM_LineMeasureCalibSet(IntPtr handle, [In, Out]LM_CALIB_RULT_S calibrult);
  575. [DllImport("LineMeasure.dll", EntryPoint = "?LM_DistortionCalibSet@@YAXPAXPAU_LM_DISCORRECT_PARA_S_@@@Z", CallingConvention = CallingConvention.Cdecl)]
  576. //[DllImport("LineMeasure.dll")]
  577. private static extern void LM_DistortionCalibSet(IntPtr handle, [In, Out]LM_DISCORRECT_PARA_S discorrpara);
  578. [DllImport("LineMeasure.dll", EntryPoint = "?LM_LineMeasureReConfig@@YAXPEAXPEAU_LM_INIT_PARA_S_@@@Z", CallingConvention = CallingConvention.Cdecl)]
  579. //[DllImport("LineMeasure.dll")]
  580. private static extern void LM_LineMeasureReConfig(IntPtr handle, [In, Out]LM_INIT_PARA_S para);
  581. [DllImport("kernel32")]
  582. private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
  583. [DllImport("kernel32")]
  584. private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
  585. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  586. private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, [In, Out] char[] lpReturnedString, uint nSize, string lpFileName);
  587. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  588. private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
  589. [DllImport("kernel32.dll")]
  590. public static extern Boolean AllocConsole();
  591. [DllImport("kernel32.dll")]
  592. public static extern Boolean FreeConsole();
  593. /// <summary>
  594. /// 控制台输出内容
  595. /// </summary>
  596. /// <param name="output">输入文本</param>
  597. /// <param name="color">输出颜色</param>
  598. public static void WriteLine(string output, ConsoleColor color)
  599. {
  600. Console.ForegroundColor = color;
  601. Console.WriteLine(@"[{0}] {1}", DateTime.Now, output);
  602. }
  603. private string ReadString(string section, string key, string def, string fileName)
  604. {
  605. StringBuilder temp = new StringBuilder(1024);
  606. try
  607. {
  608. GetPrivateProfileString(section, key, def, temp, 1024, fileName);
  609. }
  610. catch
  611. { }
  612. return temp.ToString();
  613. }
  614. private IntPtr ParaStructToPtr(LM_INIT_PARA_S para)
  615. {
  616. IntPtr pP1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LM_INIT_PARA_S)));
  617. Marshal.WriteByte(pP1, 0);
  618. Marshal.StructureToPtr(para, pP1, true);
  619. return pP1;
  620. }
  621. IntPtr pP1;
  622. private IntPtr ResultToPtr(LM_RULT_S res)
  623. {
  624. pP1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LM_RULT_S)));
  625. Marshal.WriteByte(pP1, 0);
  626. Marshal.StructureToPtr(res, pP1, true);
  627. return pP1;
  628. }
  629. private LM_RULT_S PtrToResult(IntPtr ptRes)
  630. {
  631. return (LM_RULT_S)Marshal.PtrToStructure(ptRes, typeof(LM_RULT_S));
  632. }
  633. public int Init(LM_INIT_PARA_S para, int debug)
  634. {
  635. _handle = LM_LineMeasureInit(ParaStructToPtr(para), debug);
  636. return 0;
  637. }
  638. public void Calibration(byte[] grayimg, int width, int height, float rangedis)
  639. {
  640. LM_LineMeasureCalibration(_handle, grayimg, width, height, rangedis, _calibrationRes);
  641. }
  642. public void CaliSet()
  643. {
  644. LM_LineMeasureCalibSet(_handle, _calibrationRes);
  645. }
  646. //public void Cali
  647. public void DistortionCali()
  648. {
  649. }
  650. private IntPtr StructToPtr(Type tp, Object val)
  651. {
  652. IntPtr pP1 = Marshal.AllocHGlobal(Marshal.SizeOf(tp));
  653. Marshal.WriteByte(pP1, 0);
  654. Marshal.StructureToPtr(val, pP1, true);
  655. return pP1;
  656. }
  657. #endregion
  658. }
  659. }