ImageSplicer.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using OpenCvSharp;
  2. using OpenCvSharp.Extensions;
  3. using OTSCommon.Model;
  4. using OTSIncAReportGraph;
  5. using OTSIncAReportGraph.Class;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Data;
  9. using System.Drawing;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. namespace OTSIncAReportApp._1_UI.Control_Graph.Controls
  14. {
  15. class ImageSplicer
  16. {
  17. public double picYmin { get; set; }
  18. public double picXmin { get; set; }
  19. public int imgeH { get; set; }
  20. public int imgeW { get; set; }
  21. /// <summary>
  22. /// 单纯图像拼接无颗粒颜色渲染
  23. /// </summary>
  24. /// <param name="resultFile"></param>
  25. /// <param name="m_list_allDfield"></param>
  26. /// <returns></returns>
  27. public List<DataTable> Mosaics(ResultFile resultFile,List<DisplayRectangle> m_list_allDfield)
  28. {
  29. List<DataTable> list_dt_picdata = new List<DataTable>();
  30. DataTable picDatat = new DataTable();
  31. List<Field> fieldlist = resultFile.List_OTSField;
  32. picDatat.Columns.Add("X", typeof(double));
  33. picDatat.Columns.Add("Y", typeof(double));
  34. foreach (var f in m_list_allDfield)
  35. {
  36. DataRow dr = picDatat.NewRow();
  37. dr["X"] = f.OTSCoordinatePos.X;
  38. dr["Y"] = f.OTSCoordinatePos.Y;
  39. picDatat.Rows.Add(dr);
  40. }
  41. DataTable total_dt_X = picDatat.Copy();
  42. DataView dv_x = total_dt_X.DefaultView;
  43. DataView dv_x_2 = dv_x.ToTable(true, "X").DefaultView;
  44. dv_x_2.Sort = "X ASC";
  45. total_dt_X = dv_x_2.ToTable();
  46. DataTable total_dt_Y = picDatat.Copy();
  47. DataView dv_Y = total_dt_Y.DefaultView;
  48. DataView dv_Y_2 = dv_Y.ToTable(true, "Y").DefaultView;
  49. dv_Y_2.Sort = "Y ASC";
  50. total_dt_Y = dv_Y_2.ToTable();
  51. //循环每一行图片
  52. for (int i = 0; i < total_dt_Y.Rows.Count; i++)
  53. {
  54. NLog.LogManager.GetCurrentClassLogger().Info("Splice line" + i + 1.ToString() + "of" + total_dt_Y.Rows.Count.ToString() + ".....");
  55. DataTable data = new DataTable();
  56. data.Columns.Add("mat", typeof(Bitmap));
  57. data.Columns.Add("X", typeof(double));
  58. //循环每行图片进行拼接
  59. Bitmap bitmap = new Bitmap((int)m_list_allDfield[0].OriginalImage.Width, (int)m_list_allDfield[0].OriginalImage.Height);
  60. for (int a = 0; a < total_dt_X.Rows.Count; a++)
  61. {
  62. DataRow dr2 = data.NewRow();
  63. Graphics g = Graphics.FromImage(bitmap);
  64. g.Clear(Color.White);
  65. g.Dispose();
  66. dr2["mat"] = bitmap;
  67. dr2["X"] = total_dt_X.Rows[a]["X"];
  68. data.Rows.Add(dr2);
  69. }
  70. //循环所有图片
  71. foreach (var f in m_list_allDfield)
  72. {
  73. if (total_dt_Y.Rows[i]["Y"].ToString() == f.OTSCoordinatePos.Y.ToString())
  74. {
  75. //循环图片的行数
  76. for (int c = 0; c < data.Rows.Count; c++)
  77. {
  78. if (data.Rows[c]["X"].ToString() == f.OTSCoordinatePos.X.ToString())
  79. {
  80. Bitmap image = new Bitmap(bitmap.Width, bitmap.Height);
  81. Graphics g2 = Graphics.FromImage(image);
  82. //g2.Clear(Color.White);
  83. Color color1 = Color.FromArgb(217, 217, 217);
  84. g2.Clear(color1);
  85. g2.DrawImage(image, 0, 0, f.OriginalImage.Width, f.OriginalImage.Height);
  86. Graphics graph_2 = Graphics.FromImage(image);
  87. for (int a = 0; a < fieldlist.Count; a++)
  88. {
  89. if (fieldlist[a].FieldID.ToString() == f.FieldID.ToString())
  90. {
  91. //先获取该Field中的所有Particle
  92. List<Particle> list_particle;
  93. list_particle = fieldlist[a].ParticleList;
  94. //再循环计算所有的Particle对象
  95. foreach (Particle particle in list_particle)
  96. {
  97. List<Segment> list_seg;
  98. list_seg = particle.SegmentList;
  99. //创建颗粒分布图对应的类对象
  100. List<DisplaySegment> list_dsegment = new List<DisplaySegment>();
  101. //再循环取出里面所有的segment
  102. foreach (Segment seg in list_seg)
  103. {
  104. #region 创建DSegment对象,并将STD分析出的化合物颜色保存到DSegment对象中
  105. System.Drawing.Point on_p = new System.Drawing.Point() { X = seg.Start, Y = seg.Height };
  106. System.Drawing.Point off_p = new System.Drawing.Point() { X = seg.Start + seg.Length, Y = seg.Height };
  107. Pen npen = new Pen(Color.FromArgb(255 - particle.AveGray, 0, 0, 0));
  108. graph_2.DrawLine(npen, on_p, off_p);
  109. #endregion
  110. }
  111. }
  112. }
  113. }
  114. data.Rows[c]["mat"] = image;
  115. data.Rows[c]["X"] = f.OTSCoordinatePos.X;
  116. }
  117. }
  118. }
  119. }
  120. DataView dataView1 = data.DefaultView;
  121. dataView1.Sort = "X ASC";
  122. data = dataView1.ToTable();
  123. list_dt_picdata.Add(data);
  124. }
  125. return list_dt_picdata;
  126. }
  127. /// <summary>
  128. /// 图像拼接并进行颗粒渲染颜色
  129. /// </summary>
  130. /// <param name="resultFile"></param>
  131. /// <param name="m_list_allDfield"></param>
  132. /// <returns></returns>
  133. public List<DataTable> ImageStitchingParticleRendering(ResultFile resultFile, List<DisplayRectangle> m_list_allDfield)
  134. {
  135. List<DataTable> list_dt_picdata = new List<DataTable>();
  136. DataTable picDatat = new DataTable();
  137. List<Field> fieldlist = resultFile.List_OTSField;
  138. picDatat.Columns.Add("X", typeof(double));
  139. picDatat.Columns.Add("Y", typeof(double));
  140. foreach (var f in m_list_allDfield)
  141. {
  142. DataRow dr = picDatat.NewRow();
  143. dr["X"] = f.OTSCoordinatePos.X;
  144. dr["Y"] = f.OTSCoordinatePos.Y;
  145. picDatat.Rows.Add(dr);
  146. }
  147. DataTable total_dt_X = picDatat.Copy();
  148. DataView dv_x = total_dt_X.DefaultView;
  149. DataView dv_x_2 = dv_x.ToTable(true, "X").DefaultView;
  150. dv_x_2.Sort = "X ASC";
  151. total_dt_X = dv_x_2.ToTable();
  152. DataTable total_dt_Y = picDatat.Copy();
  153. DataView dv_Y = total_dt_Y.DefaultView;
  154. DataView dv_Y_2 = dv_Y.ToTable(true, "Y").DefaultView;
  155. dv_Y_2.Sort = "Y ASC";
  156. total_dt_Y = dv_Y_2.ToTable();
  157. picYmin = Convert.ToDouble(total_dt_Y.Rows[total_dt_Y.Rows.Count - 1]["Y"]);
  158. picXmin = Convert.ToDouble(total_dt_X.Rows[0]["X"]);
  159. for (int i = 0; i < total_dt_Y.Rows.Count; i++)
  160. {
  161. NLog.LogManager.GetCurrentClassLogger().Info("Splice line" + i + 1.ToString() + "of" + total_dt_Y.Rows.Count.ToString() + ".....");
  162. DataTable data = new DataTable();
  163. data.Columns.Add("mat", typeof(Bitmap));
  164. data.Columns.Add("X", typeof(double));
  165. data.Columns.Add("Y", typeof(double));
  166. imgeH = (int)m_list_allDfield[0].OriginalImage.Height;
  167. imgeW = (int)m_list_allDfield[0].OriginalImage.Width;
  168. Bitmap bitmap = new Bitmap((int)m_list_allDfield[0].OriginalImage.Width, (int)m_list_allDfield[0].OriginalImage.Height);
  169. for (int a = 0; a < total_dt_X.Rows.Count; a++)
  170. {
  171. DataRow dr2 = data.NewRow();
  172. Graphics g = Graphics.FromImage(bitmap);
  173. g.Clear(Color.White);
  174. g.Dispose();
  175. dr2["mat"] = bitmap;
  176. dr2["X"] = total_dt_X.Rows[a]["X"];
  177. data.Rows.Add(dr2);
  178. }
  179. foreach (var f in m_list_allDfield)
  180. {
  181. if (total_dt_Y.Rows[i]["Y"].ToString() == f.OTSCoordinatePos.Y.ToString())
  182. {
  183. for (int c = 0; c < data.Rows.Count; c++)
  184. {
  185. if (data.Rows[c]["X"].ToString() == f.OTSCoordinatePos.X.ToString())
  186. {
  187. Bitmap image = new Bitmap(bitmap.Width, bitmap.Height);
  188. Graphics graph_2 = Graphics.FromImage(image);
  189. Color color1 = Color.FromArgb(217, 217, 217);
  190. graph_2.Clear(color1);
  191. //Color color1 = Color.FromArgb(217, 217, 217);
  192. //graph_2.Clear(color1);
  193. for (int a = 0; a < fieldlist.Count; a++)
  194. {
  195. if (fieldlist[a].FieldID.ToString() == f.FieldID.ToString())
  196. {
  197. //先获取该Field中的所有Particle
  198. List<Particle> list_particle;
  199. list_particle = fieldlist[a].ParticleList;
  200. //再循环计算所有的Particle对象
  201. foreach (Particle particle in list_particle)
  202. {
  203. List<Segment> list_seg;
  204. list_seg = particle.SegmentList;
  205. //创建颗粒分布图对应的类对象
  206. List<DisplaySegment> list_dsegment = new List<DisplaySegment>();
  207. //再循环取出里面所有的segment
  208. foreach (Segment seg in list_seg)
  209. {
  210. #region 创建DSegment对象,并将STD分析出的化合物颜色保存到DSegment对象中
  211. System.Drawing.Point on_p = new System.Drawing.Point() { X = seg.Start, Y = seg.Height };
  212. System.Drawing.Point off_p = new System.Drawing.Point() { X = seg.Start + seg.Length, Y = seg.Height };
  213. var color = DrawFunction.GetColorBySTDTypeIDForBSEAndSorImage(particle.TypeColor, particle.TypeId);
  214. Pen npen = new Pen(color);
  215. graph_2.DrawLine(npen, on_p, off_p);
  216. #endregion
  217. }
  218. }
  219. }
  220. }
  221. data.Rows[c]["mat"] = image;
  222. data.Rows[c]["X"] = f.OTSCoordinatePos.X;
  223. data.Rows[c]["Y"] = f.OTSCoordinatePos.Y;
  224. }
  225. }
  226. }
  227. }
  228. DataView dataView1 = data.DefaultView;
  229. dataView1.Sort = "X ASC";
  230. data = dataView1.ToTable();
  231. list_dt_picdata.Add(data);
  232. }
  233. return list_dt_picdata;
  234. }
  235. public Mat DrawingOfNationalStandardBoxes(DataTable GBDatatableOne,int GridLength, Mat save_pano)
  236. {
  237. // 创建一个HashSet来存储唯一的值
  238. HashSet<int> distinctValuesY = new HashSet<int>();
  239. // 创建一个HashSet来存储唯一的值
  240. HashSet<int> distinctValuesX = new HashSet<int>();
  241. for (int i = 0; i < GBDatatableOne.Rows.Count; i++)
  242. {
  243. distinctValuesY.Add(Convert.ToInt32(GBDatatableOne.Rows[i]["fieldY"]));
  244. distinctValuesX.Add(Convert.ToInt32(GBDatatableOne.Rows[i]["fieldX"]));
  245. }
  246. //OTS坐标向上为正,向右为正
  247. var distinctY = distinctValuesY.ToList();
  248. distinctY.Sort((a, b) => b.CompareTo(a));
  249. var distinctX = distinctValuesX.ToList();
  250. distinctX.Sort();
  251. //取到Y轴图片的最上边的位置
  252. picYmin = picYmin + (imgeH / 2);
  253. int GBY = distinctY.Max() + (GridLength / 2);
  254. int Yzhou = (int)picYmin - GBY;
  255. picXmin = picXmin - (imgeW / 2);
  256. int GBX = distinctX.Min() - (GridLength / 2);
  257. for (int i = 0; i < distinctY.Count; i++)
  258. {
  259. int Xzhou = (int)picXmin - GBX;
  260. DataTable number = CountTheNumberOfX_axes(GBDatatableOne, "fieldY", distinctY[i].ToString());
  261. for (int j = 0; j < number.Rows.Count; j++)
  262. {
  263. // 定义矩形的左上角和右下角坐标
  264. OpenCvSharp.Point topLeft = new OpenCvSharp.Point(Xzhou, Yzhou);
  265. int XzhouDOW = Xzhou + GridLength;
  266. int YzhouDOW = Yzhou + GridLength;
  267. OpenCvSharp.Point textOrg = new OpenCvSharp.Point(Xzhou + 20, Yzhou + 70); // 文字开始的位置
  268. OpenCvSharp.Point bottomRight = new OpenCvSharp.Point(XzhouDOW, YzhouDOW);
  269. Xzhou = Xzhou + GridLength;
  270. // 定义矩形的颜色(BGR)和线宽
  271. Scalar color = new OpenCvSharp.Scalar(0, 0, 255, 255); // 蓝色
  272. int thickness = 2;
  273. // 在图像上绘制矩形
  274. Cv2.Rectangle(save_pano, topLeft, bottomRight, color, thickness);
  275. // 设置要绘制的文字及其位置
  276. string text = number.Rows[j]["data"].ToString();
  277. string input = number.Rows[j]["data"].ToString();
  278. double fontScale = 1; // 字体大小缩放因子
  279. int thickness2 = 1; // 字体粗细
  280. // 获取文字的大小,以便我们可以更好地定位它
  281. OpenCvSharp.Size textSize = OpenCvSharp.Cv2.GetTextSize(input, HersheyFonts.HersheySimplex, fontScale, thickness2, out int baseline);
  282. int chunkSize = GridLength / textSize.Height; // 分割长度
  283. // 使用LINQ的Enumerable.Chunk扩展方法分割字符串
  284. var chunks = Enumerable.Range(0, input.Length / chunkSize + (input.Length % chunkSize > 0 ? 1 : 0))
  285. .Select(x => input.Substring(x * chunkSize, Math.Min(chunkSize, input.Length - x * chunkSize)))
  286. .ToList();
  287. int topgrade = Convert.ToInt32(number.Rows[j]["color"]);
  288. // 设置字体样式和大小
  289. Color color1 = new Color();
  290. switch (topgrade)
  291. {
  292. case 0:
  293. color1 = Color.White;
  294. break;
  295. case 1:
  296. color1 = Color.DarkGray;
  297. break;
  298. case 2:
  299. color1 = Color.Purple;
  300. break;
  301. case 3:
  302. color1 = Color.Blue;
  303. break;
  304. case 4:
  305. color1 = Color.Red;
  306. break;
  307. case 5:
  308. color1 = Color.Red;
  309. break;
  310. default:
  311. color1 = Color.Red;
  312. break;
  313. }
  314. Scalar fontColor = new OpenCvSharp.Scalar(color1.B, color1.G, color1.R, 255); // 文字颜色:黑色
  315. LineTypes lineType = OpenCvSharp.LineTypes.AntiAlias; // 线条类型
  316. foreach (var chunk in chunks)
  317. {
  318. // 使用PutText方法在图像上绘制文字
  319. Cv2.PutText(save_pano, chunk, textOrg, HersheyFonts.HersheySimplex, fontScale, fontColor, thickness, lineType);
  320. textOrg.Y = textOrg.Y + 70;
  321. }
  322. }
  323. Yzhou = Yzhou + GridLength;
  324. }
  325. return save_pano;
  326. }
  327. private DataTable CountTheNumberOfX_axes(DataTable dataTable, string ColumnName, string name)
  328. {
  329. DataTable data = new DataTable();
  330. data.Columns.Add("data");
  331. data.Columns.Add("color");
  332. for (int i = 0; i < dataTable.Rows.Count; i++)
  333. {
  334. if (name == dataTable.Rows[i][ColumnName].ToString())
  335. {
  336. DataRow dr = data.NewRow();
  337. dr["data"] = dataTable.Rows[i]["gradeDetail"].ToString();
  338. dr["color"] = dataTable.Rows[i]["topGrade"].ToString();
  339. data.Rows.Add(dr);
  340. }
  341. }
  342. return data;
  343. }
  344. }
  345. }