RuleCfg_Form.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  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 System.Threading;
  10. using System.IO;
  11. using System.Globalization;
  12. using System.Runtime.InteropServices;
  13. namespace VzClientSDKDemo
  14. {
  15. public partial class RuleCfg_Form : Form
  16. {
  17. private int lpr_handle_ = 0;
  18. private uint IMG_SIZE = 1920 * 1080;
  19. private byte[] pic_data_ = new byte[1920*1080];
  20. private IntPtr img_buf_ptr_;
  21. private GCHandle img_object_;
  22. private System.Timers.Timer draw_rule_timer_;
  23. public static Mutex mutex_rule_ = new Mutex();
  24. private const int LOOP_POINT_COUNT = 4;
  25. private Graphics g_box_;
  26. private Point[] loop_point_array_ = new Point[LOOP_POINT_COUNT];
  27. private Pen pen_loop_ = new Pen(Color.LightCoral, 2);
  28. private uint graph_width_ = 1280;
  29. private uint graph_heigh_ = 720;
  30. private const int BOUND_VALUE = 5;
  31. private const int SELE_BOUND_VALUE = 8;
  32. private const int CONTROL_BORDER = 2;
  33. private VzClientSDK.VZ_LPRC_VIRTUAL_LOOPS loops_ = new VzClientSDK.VZ_LPRC_VIRTUAL_LOOPS();
  34. private int active_pt_index_ = -1;
  35. private double zoom_x_rate = 0.0;
  36. private double zoom_y_rate = 0.0;
  37. private bool mouse_down_ = false;
  38. private Point pt_mouse_down_ = new Point();
  39. private Point pt_prev_ = new Point();
  40. private bool select_loop_ = false;
  41. public void SetLPRHandle(int handle)
  42. {
  43. lpr_handle_ = handle;
  44. }
  45. public RuleCfg_Form()
  46. {
  47. InitializeComponent();
  48. }
  49. private void RuleCfg_Form_Load(object sender, EventArgs e)
  50. {
  51. // 开启获取实时解码数据
  52. if (lpr_handle_ > 0)
  53. {
  54. VzClientSDK.VzLPRClient_StartRealPlayDecData(lpr_handle_);
  55. }
  56. img_object_ = GCHandle.Alloc(pic_data_, GCHandleType.Pinned);
  57. img_buf_ptr_ = img_object_.AddrOfPinnedObject();
  58. draw_rule_timer_ = new System.Timers.Timer(80);
  59. draw_rule_timer_.Elapsed += drawTimer_Elapsed;
  60. draw_rule_timer_.AutoReset = true;
  61. draw_rule_timer_.Enabled = true;
  62. g_box_ = picBoxVideo.CreateGraphics();
  63. LoadRuleParam();
  64. }
  65. private void LoadRuleParam()
  66. {
  67. if (lpr_handle_ > 0)
  68. {
  69. // 加载虚拟线圈的规则
  70. int ret = VzClientSDK.VzLPRClient_GetVirtualLoop(lpr_handle_, ref loops_);
  71. if (loops_.uNumVirtualLoop > 0)
  72. {
  73. LoadLoopParam();
  74. uint x = 0, y = 0;
  75. for( int i = 0; i < LOOP_POINT_COUNT; i++ )
  76. {
  77. x = loops_.struLoop[0].struVertex[i].X_1000 * graph_width_ / 1000;
  78. y = loops_.struLoop[0].struVertex[i].Y_1000 * graph_heigh_ / 1000;
  79. loop_point_array_[i] = new Point((int)x, (int)y);
  80. }
  81. zoom_x_rate = (double)picBoxVideo.Width / (double)graph_width_;
  82. zoom_y_rate = (double)picBoxVideo.Height / (double)graph_heigh_;
  83. }
  84. else
  85. {
  86. EnableLoopParamCtrl(false);
  87. }
  88. }
  89. }
  90. private void drawTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  91. {
  92. mutex_rule_.WaitOne();
  93. int nBufSize = VzClientSDK.VzLPRClient_GetJpegStreamFromRealPlayDec(lpr_handle_, img_buf_ptr_, IMG_SIZE, 100);
  94. if (nBufSize > 0)
  95. {
  96. // 显示图像到界面
  97. MemoryStream ms = new MemoryStream(pic_data_);
  98. Bitmap bitmap = new Bitmap(ms);
  99. Graphics g = Graphics.FromImage(bitmap);
  100. if ( loops_.uNumVirtualLoop == 1 )
  101. {
  102. g.DrawPolygon(pen_loop_, loop_point_array_);
  103. if (graph_width_ != bitmap.Width || graph_heigh_ != bitmap.Height)
  104. {
  105. graph_width_ = (uint)bitmap.Width;
  106. graph_heigh_ = (uint)bitmap.Height;
  107. zoom_x_rate = (double)picBoxVideo.Width / (double)graph_width_;
  108. zoom_y_rate = (double)picBoxVideo.Height / (double)graph_heigh_;
  109. ReloadLoop( );
  110. }
  111. for( int i = 0; i < LOOP_POINT_COUNT; i++ )
  112. {
  113. if ( i == active_pt_index_ )
  114. {
  115. g.DrawRectangle(Pens.LightGreen, loop_point_array_[i].X - SELE_BOUND_VALUE, loop_point_array_[i].Y - SELE_BOUND_VALUE, SELE_BOUND_VALUE * 2, SELE_BOUND_VALUE * 2);
  116. }
  117. else
  118. {
  119. g.DrawRectangle(Pens.LightYellow, loop_point_array_[i].X - BOUND_VALUE, loop_point_array_[i].Y - BOUND_VALUE, BOUND_VALUE * 2, BOUND_VALUE * 2);
  120. }
  121. }
  122. }
  123. Rectangle rc_dest = new Rectangle(0, 0, picBoxVideo.Width, picBoxVideo.Height);
  124. Rectangle rc_src = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
  125. g_box_.DrawImage(bitmap, rc_dest, rc_src, GraphicsUnit.Pixel);
  126. }
  127. mutex_rule_.ReleaseMutex();
  128. }
  129. private void ReloadLoop( )
  130. {
  131. for (int i = 0; i < LOOP_POINT_COUNT; i++)
  132. {
  133. loop_point_array_[i].X = (int)(loops_.struLoop[0].struVertex[i].X_1000 * graph_width_ / 1000);
  134. loop_point_array_[i].Y = (int)(loops_.struLoop[0].struVertex[i].Y_1000 * graph_heigh_ / 1000);
  135. }
  136. }
  137. private void RuleCfg_Form_FormClosed(object sender, FormClosedEventArgs e)
  138. {
  139. draw_rule_timer_.Enabled = false;
  140. draw_rule_timer_.Stop();
  141. VzClientSDK.VzLPRClient_StopRealPlayDecData(lpr_handle_);
  142. if (img_object_.IsAllocated)
  143. {
  144. img_object_.Free();
  145. }
  146. }
  147. private int Point2PointDist(Point pt_start, Point pt_end)
  148. {
  149. double dbDist = (pt_start.X - pt_end.X) * (pt_start.X - pt_end.X) + (pt_start.Y - pt_end.Y) * (pt_start.Y - pt_end.Y);
  150. int nDist = (int)Math.Sqrt(dbDist);
  151. return nDist;
  152. }
  153. private int GetPointIndex(Point pt, int max_dist)
  154. {
  155. int index = -1;
  156. int dist = 0;
  157. for( int i = 0; i < LOOP_POINT_COUNT; i++ )
  158. {
  159. dist = Point2PointDist(pt, loop_point_array_[i]);
  160. if (dist <= max_dist)
  161. {
  162. max_dist = dist;
  163. index = i;
  164. }
  165. }
  166. return index;
  167. }
  168. private Point PointToImgPoint(Point pt)
  169. {
  170. Point pt_img = new Point();
  171. pt_img.X = GetImgX(pt.X);
  172. pt_img.Y = GetImgY(pt.Y);
  173. return pt_img;
  174. }
  175. private int GetImgX(int x)
  176. {
  177. int img_x = x;
  178. if( zoom_x_rate > 0.01 )
  179. {
  180. img_x = (int)(x / zoom_x_rate);
  181. }
  182. return img_x;
  183. }
  184. private int GetImgY(int y)
  185. {
  186. int img_y = y;
  187. if ( zoom_y_rate > 0.01 )
  188. {
  189. img_y = (int)(y / zoom_y_rate);
  190. }
  191. return img_y;
  192. }
  193. private void btnSave_Click(object sender, EventArgs e)
  194. {
  195. int nMinLPWidth = int.Parse(txtMinWidth.Text);
  196. int nMaxLPWidth = int.Parse(txtMaxWidth.Text);
  197. if (nMinLPWidth < 45 || nMaxLPWidth > 600 || nMinLPWidth >= nMaxLPWidth)
  198. {
  199. MessageBox.Show("车牌宽度限制填写不正确,请重新输入!");
  200. return;
  201. }
  202. if( lpr_handle_ > 0 )
  203. {
  204. if (loops_.uNumVirtualLoop == 1)
  205. {
  206. for (int i = 0; i < LOOP_POINT_COUNT; i++)
  207. {
  208. loops_.struLoop[0].struVertex[i].X_1000 = (uint)(loop_point_array_[i].X * 1000 / graph_width_);
  209. loops_.struLoop[0].struVertex[i].Y_1000 = (uint)(loop_point_array_[i].Y * 1000 / graph_heigh_);
  210. }
  211. loops_.struLoop[0].uMinLPWidth = uint.Parse(txtMinWidth.Text);
  212. loops_.struLoop[0].uMaxLPWidth = uint.Parse(txtMaxWidth.Text);
  213. loops_.struLoop[0].uTriggerTimeGap = uint.Parse(txtTimes.Text);
  214. loops_.struLoop[0].eCrossDir = (uint)(cmbDir.SelectedIndex);
  215. loops_.struLoop[0].byDraw = (chkDraw.Checked ? (byte)1 : (byte)0);
  216. loops_.struLoop[0].byEnable = (chkEnable.Checked ? (byte)1 : (byte)0);
  217. }
  218. else
  219. {
  220. // 清空数据
  221. for (int i = 0; i < LOOP_POINT_COUNT; i++)
  222. {
  223. loops_.struLoop[0].struVertex[i].X_1000 = 0;
  224. loops_.struLoop[0].struVertex[i].Y_1000 = 0;
  225. }
  226. loops_.struLoop[0].strName = "";
  227. loops_.struLoop[0].uMinLPWidth = 0;
  228. loops_.struLoop[0].uMaxLPWidth = 0;
  229. loops_.struLoop[0].uTriggerTimeGap = 0;
  230. loops_.struLoop[0].eCrossDir = 0;
  231. loops_.struLoop[0].byDraw = 0;
  232. loops_.struLoop[0].byEnable = 0;
  233. }
  234. int ret = VzClientSDK.VzLPRClient_SetVirtualLoop(lpr_handle_, ref loops_);
  235. if (ret == 0)
  236. {
  237. MessageBox.Show("保存线圈参数成功!");
  238. }
  239. else
  240. {
  241. MessageBox.Show("保存线圈参数失败!");
  242. }
  243. }
  244. }
  245. private void picBoxVideo_MouseMove(object sender, MouseEventArgs e)
  246. {
  247. Point pt_mouse = new Point(e.X, e.Y);
  248. Point pt_img = PointToImgPoint(pt_mouse);
  249. int dis_x = 0, dis_y = 0;
  250. if (mouse_down_)
  251. {
  252. if ( active_pt_index_ >= 0 && active_pt_index_ < LOOP_POINT_COUNT )
  253. {
  254. Point ptNow = GetInBoundPoint(pt_img);
  255. if (!GetEditIsCross(active_pt_index_, ptNow))
  256. {
  257. // 移动点
  258. loop_point_array_[active_pt_index_] = ptNow;
  259. }
  260. }
  261. else
  262. {
  263. // 移动整个图形
  264. if( select_loop_ )
  265. {
  266. // 获取当前位置与之前位置的坐标差
  267. dis_x = pt_img.X - pt_prev_.X;
  268. dis_y = pt_img.Y - pt_prev_.Y;
  269. // 如果图形上所有的点没有超过图形范围,则移动图形
  270. MoveBoundLimit(ref dis_x, ref dis_y);
  271. if (dis_x != 0 || dis_y != 0)
  272. {
  273. MoveAllPoints(dis_x, dis_y);
  274. // 保存之前的坐标
  275. pt_prev_.X += dis_x;
  276. pt_prev_.Y += dis_y;
  277. }
  278. }
  279. }
  280. }
  281. else
  282. {
  283. active_pt_index_ = GetPointIndex(pt_img, 10);
  284. PointIsInPolygen(pt_img);
  285. }
  286. }
  287. private void MoveAllPoints(int dis_x, int dis_y)
  288. {
  289. for( int i = 0; i < LOOP_POINT_COUNT; i++ )
  290. {
  291. loop_point_array_[i].X += dis_x;
  292. loop_point_array_[i].Y += dis_y;
  293. }
  294. }
  295. private void picBoxVideo_MouseDown(object sender, MouseEventArgs e)
  296. {
  297. pt_mouse_down_.X = e.X;
  298. pt_mouse_down_.Y = e.Y;
  299. Point pt_img = PointToImgPoint(pt_mouse_down_);
  300. select_loop_ = PointIsInPolygen(pt_img);
  301. if ( select_loop_ )
  302. {
  303. pt_prev_ = pt_img;
  304. }
  305. mouse_down_ = true;
  306. }
  307. private void picBoxVideo_MouseUp(object sender, MouseEventArgs e)
  308. {
  309. mouse_down_ = false;
  310. }
  311. bool PointIsInPolygen(Point pt)
  312. {
  313. Point pt0, pt1;
  314. int dist = 0;
  315. int counter = 0;
  316. bool result = false;
  317. for ( int i = 0; i < LOOP_POINT_COUNT - 1; i++ )
  318. {
  319. pt0 = loop_point_array_[i];
  320. pt1 = loop_point_array_[i + 1];
  321. if ((pt0.Y <= pt.Y && pt1.Y <= pt.Y) ||
  322. (pt0.Y > pt.Y && pt1.Y > pt.Y) ||
  323. (pt0.X < pt.X && pt1.X < pt.X) )
  324. {
  325. if( pt.Y == pt1.Y && (pt.X == pt1.X || (pt.Y == pt0.Y &&
  326. ((pt0.X <= pt.X && pt.X <= pt1.X) || (pt1.X <= pt.X && pt.X <= pt0.X)))) )
  327. return true;
  328. continue;
  329. }
  330. dist = (pt.Y - pt0.Y)*(pt1.X - pt0.X) - (pt.X - pt0.X)*(pt1.Y - pt0.Y);
  331. if( dist == 0 )
  332. return true;
  333. if( pt1.Y < pt0.Y )
  334. dist = -dist;
  335. if (dist > 0)
  336. {
  337. counter ++;
  338. }
  339. // counter += dist > 0;
  340. }
  341. result = (counter % 2) == 0 ? false : true;
  342. return result;
  343. }
  344. private void MoveBoundLimit(ref int nDisX, ref int nDisY)
  345. {
  346. int nCurX = 0;
  347. int nCurY = 0;
  348. for( int i = 0; i < LOOP_POINT_COUNT; i++ )
  349. {
  350. nCurX = loop_point_array_[i].X + nDisX;
  351. nCurY = loop_point_array_[i].Y + nDisY;
  352. if (nCurX > ((int)graph_width_ - CONTROL_BORDER))
  353. {
  354. nCurX = ((int)graph_width_ - CONTROL_BORDER);
  355. }
  356. else if( nCurX < 0 ){
  357. nCurX = 0;
  358. }
  359. nDisX = nCurX - loop_point_array_[i].X;
  360. if (nCurY > ((int)graph_heigh_ - CONTROL_BORDER))
  361. {
  362. nCurY = ((int)graph_heigh_ - CONTROL_BORDER);
  363. }
  364. else if( nCurY < 0 )
  365. {
  366. nCurY = 0 ;
  367. }
  368. nDisY = nCurY -loop_point_array_[i].Y;
  369. }
  370. }
  371. private bool GetEditIsCross( int nPtIndex, Point ptMouse )
  372. {
  373. int nMaxIndex = LOOP_POINT_COUNT - 1;
  374. bool bCross = false;
  375. bool bCross1, bCross2;
  376. Point ptEdge1Start, ptEdge1End;
  377. Point ptEdge2Start, ptEdge2End;
  378. Point ptStart, ptEnd;
  379. // 移动起点
  380. if( nPtIndex == 0 )
  381. {
  382. ptStart = loop_point_array_[1];
  383. ptEnd = ptStart;
  384. // 第一条边
  385. ptEdge1Start = ptMouse;
  386. ptEdge1End = loop_point_array_[1];
  387. for (int i = 2; i < LOOP_POINT_COUNT; i++)
  388. {
  389. ptEnd = loop_point_array_[i];
  390. bCross = GetLineIsCross(ptEdge1Start, ptEdge1End, ptStart, ptEnd);
  391. if( bCross )
  392. {
  393. break;
  394. }
  395. ptStart = ptEnd;
  396. }
  397. } // 移动终点
  398. else if( nPtIndex == nMaxIndex )
  399. {
  400. ptStart = loop_point_array_[0];
  401. ptEnd = ptStart;
  402. // 第一条边
  403. ptEdge1Start = loop_point_array_[nMaxIndex - 1];
  404. ptEdge1End = ptMouse;
  405. for( int i = 1; i < nMaxIndex; i++ )
  406. {
  407. ptEnd = loop_point_array_[i];
  408. bCross = GetLineIsCross(ptEdge1Start, ptEdge1End, ptStart, ptEnd);
  409. if( bCross )
  410. {
  411. break;
  412. }
  413. ptStart = ptEnd;
  414. }
  415. }
  416. else
  417. {
  418. ptStart = loop_point_array_[0];
  419. ptEnd = ptStart;
  420. // 第一条边
  421. ptEdge1Start = loop_point_array_[nPtIndex-1];
  422. ptEdge1End = ptMouse;
  423. // 第二条边
  424. ptEdge2Start = ptMouse;
  425. ptEdge2End = loop_point_array_[nPtIndex + 1];
  426. for (int i = 1; i < LOOP_POINT_COUNT; i++)
  427. {
  428. ptEnd = loop_point_array_[i];
  429. if( (i == nPtIndex) || (i == (nPtIndex + 1)) )
  430. {
  431. ptStart = ptEnd;
  432. continue;
  433. }
  434. bCross1 = GetLineIsCross(ptEdge1Start, ptEdge1End, ptStart, ptEnd);
  435. bCross2 = GetLineIsCross(ptEdge2Start, ptEdge2End, ptStart, ptEnd);
  436. if( bCross1 || bCross2 )
  437. {
  438. bCross = true;
  439. break;
  440. }
  441. ptStart = ptEnd;
  442. }
  443. }
  444. return bCross;
  445. }
  446. private bool GetLineIsCross(Point ptMa, Point ptMb, Point ptNa, Point ptNb)
  447. {
  448. double dbV1, dbV2, dbV3, dbV4;
  449. dbV1 = (ptMb.X - ptMa.X) * (ptNb.Y - ptMa.Y) - (ptMb.Y - ptMa.Y) * (ptNb.X - ptMa.X);
  450. dbV2 = (ptMb.X - ptMa.X) * (ptNa.Y - ptMa.Y) - (ptMb.Y - ptMa.Y) * (ptNa.X - ptMa.X);
  451. double dbResult1 = dbV1 * dbV2;
  452. if( dbResult1 >= 0 )
  453. {
  454. return false;
  455. }
  456. dbV3 = (ptNb.X - ptNa.X) * (ptMb.Y - ptNa.Y) - (ptNb.Y - ptNa.Y) * (ptMb.X - ptNa.X);
  457. dbV4 = (ptNb.X - ptNa.X) * (ptMa.Y - ptNa.Y) - (ptNb.Y - ptNa.Y) * (ptMa.X - ptNa.X);
  458. double dbResult2 = dbV3 * dbV4;
  459. if( dbResult2 >= 0 )
  460. {
  461. return false;
  462. }
  463. return true;
  464. }
  465. private Point GetInBoundPoint( Point pt )
  466. {
  467. Point ptResult = pt;
  468. if( ptResult.X < 0 )
  469. {
  470. ptResult.X = 0;
  471. }
  472. if( ptResult.X > ((int)graph_width_ - CONTROL_BORDER) )
  473. {
  474. ptResult.X = (int)graph_width_ - CONTROL_BORDER;
  475. }
  476. if( ptResult.Y < 0 )
  477. {
  478. ptResult.Y = 0;
  479. }
  480. if (ptResult.Y > ((int)graph_heigh_ - CONTROL_BORDER))
  481. {
  482. ptResult.Y = (int)graph_heigh_ - CONTROL_BORDER;
  483. }
  484. return ptResult;
  485. }
  486. private void EnableLoopParamCtrl(bool enable)
  487. {
  488. txtMinWidth.Enabled = enable;
  489. txtMaxWidth.Enabled = enable;
  490. txtTimes.Enabled = enable;
  491. cmbDir.Enabled = enable;
  492. chkDraw.Enabled = enable;
  493. chkEnable.Enabled = enable;
  494. }
  495. // 删除线圈
  496. private void btnDeleRule_Click(object sender, EventArgs e)
  497. {
  498. loops_.uNumVirtualLoop = 0;
  499. for ( int i = 0; i < LOOP_POINT_COUNT; i++ )
  500. {
  501. loop_point_array_[i].X = 0;
  502. loop_point_array_[i].Y = 0;
  503. }
  504. EnableLoopParamCtrl(false);
  505. }
  506. private void LoadLoopParam()
  507. {
  508. string rule_name = loops_.struLoop[0].strName;
  509. txtRuleName.Text = rule_name;
  510. uint time_gap = loops_.struLoop[0].uTriggerTimeGap;
  511. txtTimes.Text = time_gap.ToString();
  512. if (loops_.struLoop[0].byDraw == 1)
  513. {
  514. chkDraw.Checked = true;
  515. }
  516. if (loops_.struLoop[0].byEnable == 1)
  517. {
  518. chkEnable.Checked = true;
  519. }
  520. uint min_lp_width = loops_.struLoop[0].uMinLPWidth;
  521. uint max_lp_width = loops_.struLoop[0].uMaxLPWidth;
  522. txtMinWidth.Text = min_lp_width.ToString();
  523. txtMaxWidth.Text = max_lp_width.ToString();
  524. uint cross_dir = loops_.struLoop[0].eCrossDir;
  525. if (cross_dir >= 0 && cross_dir < 3)
  526. {
  527. cmbDir.SelectedIndex = (int)cross_dir;
  528. }
  529. else
  530. {
  531. cmbDir.SelectedIndex = 0;
  532. }
  533. }
  534. // 添加线圈的功能
  535. private void btnAddRule_Click(object sender, EventArgs e)
  536. {
  537. if (loops_.uNumVirtualLoop >= 1)
  538. {
  539. MessageBox.Show("只允许配置一个虚拟线圈!");
  540. return;
  541. }
  542. int RULE_GRAPH_BORDER = 100;
  543. int nWidth = (int)graph_width_;
  544. int nHeight = (int)graph_heigh_;
  545. int nMaxWidth = nWidth - RULE_GRAPH_BORDER;
  546. int nMaxHeight = nHeight - RULE_GRAPH_BORDER;
  547. Point pt1 = new Point(RULE_GRAPH_BORDER,RULE_GRAPH_BORDER + nMaxHeight / 2 );
  548. Point pt2 = new Point(nWidth - RULE_GRAPH_BORDER, RULE_GRAPH_BORDER + nMaxHeight/2);
  549. Point pt3 = new Point(nWidth - RULE_GRAPH_BORDER, nHeight - RULE_GRAPH_BORDER);
  550. Point pt4 = new Point(RULE_GRAPH_BORDER, nMaxHeight);
  551. loop_point_array_[0] = pt1;
  552. loop_point_array_[1] = pt2;
  553. loop_point_array_[2] = pt3;
  554. loop_point_array_[3] = pt4;
  555. loops_.uNumVirtualLoop = 1;
  556. loops_.struLoop[0].strName = "电子线圈";
  557. loops_.struLoop[0].eCrossDir = 0;
  558. loops_.struLoop[0].uTriggerTimeGap = 10;
  559. loops_.struLoop[0].byDraw = 1;
  560. loops_.struLoop[0].byEnable = 1;
  561. loops_.struLoop[0].uMinLPWidth = 45;
  562. loops_.struLoop[0].uMaxLPWidth = 600;
  563. loops_.uNumVirtualLoop = 1;
  564. LoadLoopParam();
  565. EnableLoopParamCtrl(true);
  566. }
  567. private void btnROI_Click(object sender, EventArgs e)
  568. {
  569. VzClientSDK.VZ_LPRC_ROI_EX struROI = new VzClientSDK.VZ_LPRC_ROI_EX();
  570. int nRet = VzClientSDK.VzLPRClient_GetRegionOfInterestEx(lpr_handle_, ref struROI);
  571. if (nRet == 0)
  572. {
  573. }
  574. }
  575. }
  576. }