Classify.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace OTSExtremum.Business
  8. {
  9. public class Classify
  10. {
  11. public static double[] getClass(string path)
  12. {
  13. Data.ParticleData particleData = new Data.ParticleData(path);
  14. DataTable particles = particleData.GetParticleListAndEm();
  15. double A=0, B=0, C=0, D=0, DS = 0;
  16. DataTable BD = particles.Clone();
  17. foreach (DataRow item in particles.Rows)
  18. {
  19. if (Convert.ToInt32(item["RectWidth"]) == 0)
  20. {
  21. continue;
  22. }
  23. //获取最大长度和最小宽度
  24. double h = Convert.ToDouble(item["DMAX"]);
  25. double w = Convert.ToDouble(item["DMIN"]);
  26. double dLengthWidthRatio = h / w;
  27. if (dLengthWidthRatio < 1)
  28. {
  29. dLengthWidthRatio = 1 / dLengthWidthRatio;
  30. }
  31. if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类
  32. {
  33. //A or C class
  34. string element = item["Element"].ToString();
  35. if (element.IndexOf("S-") > -1)
  36. {
  37. if (Convert.ToDouble(item["PERIMETER"]) > A)
  38. {
  39. A = Convert.ToDouble(item["PERIMETER"]);
  40. }
  41. }
  42. else if (element.IndexOf("O-") > -1)
  43. {
  44. if (Convert.ToDouble(item["PERIMETER"]) > C)
  45. {
  46. C = Convert.ToDouble(item["PERIMETER"]);
  47. }
  48. }
  49. }
  50. else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒
  51. {
  52. // B, or D or DS
  53. // compute Feret's diameter
  54. double dFeretDiameter = Convert.ToDouble(item["PERIMETER"]);
  55. if (dFeretDiameter >= 13)
  56. {
  57. // DS
  58. if (Convert.ToDouble(item["PERIMETER"]) > DS)
  59. {
  60. DS = Convert.ToDouble(item["PERIMETER"]);
  61. }
  62. }
  63. else
  64. {
  65. //不能确定是B或D,先设为INVALID
  66. BD.Rows.Add(item.ItemArray);
  67. }
  68. }
  69. }
  70. foreach (DataRow item in BD.Rows)
  71. {
  72. double xs = 1142 / 1024;
  73. int left = Convert.ToInt32(item["RectLeft"]);
  74. int top = Convert.ToInt32(item["RectTop"]);
  75. int width = Convert.ToInt32(item["RectWidth"]);
  76. int height = Convert.ToInt32(item["RectHeight"]);
  77. int cenX = left + width / 2;
  78. int Bottom = top- height;
  79. bool isline = false;
  80. for (int i = 0; i < BD.Rows.Count; i++)
  81. {
  82. int leftB = Convert.ToInt32(item["RectLeft"]);
  83. int topB = Convert.ToInt32(item["RectTop"]);
  84. int widthB = Convert.ToInt32(item["RectWidth"]);
  85. int heightB = Convert.ToInt32(item["RectHeight"]);
  86. int cenBX = leftB + widthB / 2;
  87. int BottomB = topB - heightB;
  88. double dd = 0, ds = 0;
  89. ds =Math.Abs(cenX - cenBX);
  90. if (ds* xs < 10)//认为两个颗粒在一条竖直线上,但不在一起
  91. {
  92. if (Bottom > topB)//current particle is on the above
  93. {
  94. dd = Bottom - topB;
  95. if (dd* xs < 40)//认为这两个颗粒在一个串条上
  96. {
  97. isline= true;
  98. break;
  99. }
  100. }
  101. else if (BottomB > top) //current particle is on the below
  102. {
  103. dd = BottomB - top;
  104. if (dd* xs < 40)
  105. {
  106. isline= true;
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. if (isline)
  113. {
  114. if (Convert.ToDouble(item["PERIMETER"]) > B)
  115. {
  116. B = Convert.ToDouble(item["PERIMETER"]);
  117. }
  118. }
  119. else
  120. {
  121. if (Convert.ToDouble(item["PERIMETER"]) > D)
  122. {
  123. D = Convert.ToDouble(item["PERIMETER"]);
  124. }
  125. }
  126. }
  127. return new double[] {A,B,C,D,DS};
  128. }
  129. }
  130. }