DieGouTools.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. using OpenCvSharp;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace SmartCoalApplication.Base.CommTool
  8. {
  9. public class DieGouTools
  10. {
  11. /// <summary>
  12. /// 判断是否进行图像增强
  13. /// 获取直方图,判断第一个峰的像素个数如果占全图的百分之八十以上,则不增强,否则增强
  14. /// </summary>
  15. /// <param name="gray"></param>
  16. /// <returns></returns>
  17. public static bool CalcEnhanceFlag(Mat gray)
  18. {
  19. float[] hist_float = HistTools.CalcHist(gray);
  20. //直方图平滑
  21. int[] hist_int = HistTools.Smooth(hist_float, 20);
  22. List<int> mountainsList = new List<int>();
  23. List<int[]> mountainsArrList = new List<int[]>();
  24. List<int[]> mountainsArrListBackUp = new List<int[]>();
  25. Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, 255, mountainsList, mountainsArrList, mountainsArrListBackUp, new List<string>(), 15);
  26. float sum = 0;
  27. for(int i= mountainsArrList[0][0]; i<= mountainsArrList[0][1]; i++)
  28. {
  29. sum += hist_int[i];
  30. }
  31. if(sum / hist_int.Sum() > 0.8) return false;
  32. return true;
  33. }
  34. /// <summary>
  35. /// 使用两次阈值寻找线
  36. /// </summary>
  37. /// <param name="gray"></param>
  38. /// <returns></returns>
  39. public static List<int> CalcDarkOrLight(Mat gray, Vec4b vec4B)
  40. {
  41. List<int> SplitListB = new List<int>();
  42. double thresh = Cv2.Threshold(gray, new Mat(), 0, 255, ThresholdTypes.Triangle);
  43. Mat mask_dark = new Mat(gray.Size(), gray.Type());
  44. Mat mask_light = new Mat(gray.Size(), gray.Type());
  45. for (int h = 0; h < gray.Height; h++)
  46. {
  47. for (int w = 0; w < gray.Width; w++)
  48. {
  49. int v = gray.At<byte>(h, w);
  50. if (v <= thresh)
  51. mask_dark.Set<byte>(h, w, 255);
  52. if (v >= 105)
  53. mask_light.Set<byte>(h, w, 255);
  54. }
  55. }
  56. //去碎屑
  57. mask_dark = BinaryTools.SingleChannelDebrisRemoval(mask_dark, 10000);
  58. //空洞填充
  59. mask_dark = BinaryTools.SingleChannelHoleFilling(mask_dark, vec4B);
  60. //去碎屑
  61. mask_light = BinaryTools.SingleChannelDebrisRemoval(mask_light, 10000);
  62. //空洞填充
  63. mask_light = BinaryTools.SingleChannelHoleFilling(mask_light, vec4B);
  64. int first = -1, end = -1;
  65. for (int i = 0; i < mask_dark.Height - 1; i++)
  66. {
  67. /*if (mask_dark.Row[i].CountNonZero() == mask_dark.Width)
  68. {
  69. if (first == -1) first = i;
  70. end = i;
  71. }
  72. if(mask_dark.Row[i].CountNonZero() == 0)
  73. {
  74. if(first!=-1) SplitListB.Add(first);
  75. if (end != -1) SplitListB.Add(end);
  76. first = -1;
  77. end = -1;
  78. }*/
  79. int v1 = mask_dark.At<byte>(i, mask_dark.Width / 2);
  80. int v2 = mask_dark.At<byte>(i + 1, mask_dark.Width / 2);
  81. if ((v1 == 255 && v2 == 0) || (v1 == 0 && v2 == 255))
  82. {
  83. SplitListB.Add(i);
  84. }
  85. }
  86. //if(SplitListB.Count==0) 如果不加这个条件,会丢失一些线,但是加了会有一些干扰出现
  87. {
  88. first = -1;
  89. end = -1;
  90. Mat labels_light = new Mat();
  91. Mat stats_light = new Mat();
  92. Mat centroids_light = new Mat();
  93. //连通域数量
  94. int num_1 = Cv2.ConnectedComponentsWithStats(mask_light, labels_light, stats_light, centroids_light, PixelConnectivity.Connectivity8);
  95. int all = 0;
  96. int abc = -1;
  97. for (int j = 1; j < stats_light.Height; j++)
  98. {
  99. int x = stats_light.At<int>(j, 0);
  100. int y = stats_light.At<int>(j, 1);
  101. int width = stats_light.At<int>(j, 2);
  102. int height = stats_light.At<int>(j, 3);
  103. int area = stats_light.At<int>(j, 4);
  104. if (width == mask_light.Width)
  105. {
  106. if (abc == -1) abc = j;
  107. all++;
  108. }
  109. }
  110. if (all >= 3) mask_light[stats_light.At<int>(abc, 1), stats_light.At<int>(abc, 3) + stats_light.At<int>(abc, 1),
  111. stats_light.At<int>(abc, 0), stats_light.At<int>(abc, 2) - 1] *= 0;
  112. for (int i = 0; i < mask_light.Height - 1; i++)
  113. {
  114. /*if (mask_light.Row[i].CountNonZero() == mask_light.Width)
  115. {
  116. if (first == -1) first = i;
  117. end = i;
  118. }
  119. if (mask_light.Row[i].CountNonZero() == 0)
  120. {
  121. if (first != -1) SplitListB.Add(first);
  122. if (end != -1) SplitListB.Add(end);
  123. first = -1;
  124. end = -1;
  125. }*/
  126. int v1 = mask_light.At<byte>(i, mask_light.Width / 2);
  127. int v2 = mask_light.At<byte>(i + 1, mask_light.Width / 2);
  128. if ((v1 == 255 && v2 == 0) || (v1 == 0 && v2 == 255))
  129. {
  130. SplitListB.Add(i);
  131. }
  132. }
  133. }
  134. SplitListB.Sort();
  135. for (int h = SplitListB.Count - 1; h >= 1; h--)
  136. {
  137. if (Math.Abs(SplitListB[h] - SplitListB[h - 1]) > 5)
  138. {
  139. continue;
  140. }
  141. SplitListB.RemoveAt(h);
  142. }
  143. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_dark.jpg", mask_dark);
  144. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_light.jpg", mask_light);
  145. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\a+b.jpg", mask_dark+mask_light);
  146. if (!SplitListB.Contains(0)) SplitListB.Insert(0, 0);
  147. if (!SplitListB.Contains(gray.Height)) SplitListB.Add(gray.Height);
  148. return SplitListB;
  149. }
  150. public static List<int> LoopMiddlePic(Mat originGray, Mat gray, Vec4b vec4B, int top, int bottom, int i)
  151. {
  152. List<int> arrs = new List<int>();
  153. //截取中间的,进行再次寻找
  154. var centerA = gray.Width / 2 - 100;
  155. Mat temp1 = new Mat(gray, new Rect(centerA, top, 200, bottom - top));
  156. //判断是否是亮的
  157. int mean = (int)Cv2.Mean(temp1);
  158. if(mean>120)
  159. {
  160. temp1 = new Mat(originGray, new Rect(centerA, top, 200, bottom - top));
  161. }
  162. /*else
  163. {
  164. //对比度拉伸
  165. double min, max;
  166. Cv2.MinMaxIdx(temp1, out min, out max);
  167. for (int h = 0; h < temp1.Height; h++)
  168. {
  169. for (int w = 0; w < temp1.Width; w++)
  170. {
  171. temp1.Set<byte>(h, w, (byte)((temp1.At<byte>(h, w) - min) * 255 / (max - min)));
  172. }
  173. }
  174. }*/
  175. /*Mat edge = new Mat();
  176. Cv2.Canny(temp1, edge, 0, 80);
  177. int nums = Cv2.CountNonZero(edge);
  178. Cv2.ImWrite(@"C:\Users\zyh\Desktop\edge" + i + ".jpg", edge);
  179. if (nums * 1f / (temp1.Width* temp1.Height) < 0.05) continue;*/
  180. Mat mask_temp1 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0));
  181. Mat mask_temp2 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0));
  182. double thresh_a = Cv2.Threshold(temp1, new Mat(), 0, 255, ThresholdTypes.Otsu);
  183. double thresh_b = Cv2.Threshold(temp1, new Mat(), 0, 255, ThresholdTypes.Triangle);
  184. double thresh1 = (thresh_a < thresh_b ? thresh_a : thresh_b) + 1;
  185. //对temp1进行加强
  186. temp1 = Tools.adaptEdgeEnhancement(temp1, 11, 0);
  187. //InputArray kernel = InputArray.Create<int>(new int[1, 11] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } });
  188. //Cv2.MorphologyEx(temp1, temp1, MorphTypes.Open, kernel, null, 5);
  189. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\grayOrigin.jpg", grayOrigin);
  190. for (int h = 0; h < temp1.Height; h++)
  191. {
  192. for (int w = 0; w < temp1.Width; w++)
  193. {
  194. int v = temp1.At<byte>(h, w);
  195. if (v <= thresh1)
  196. mask_temp1.Set<byte>(h, w, 255);
  197. if (v > thresh1 + 6)
  198. mask_temp2.Set<byte>(h, w, 255);
  199. }
  200. }
  201. //去碎屑
  202. mask_temp1 = BinaryTools.SingleChannelDebrisRemoval(mask_temp1, 100);
  203. //空洞填充
  204. mask_temp1 = BinaryTools.SingleChannelHoleFilling(mask_temp1, vec4B);
  205. //去碎屑
  206. mask_temp2 = BinaryTools.SingleChannelDebrisRemoval(mask_temp2, 100);
  207. //空洞填充
  208. mask_temp2 = BinaryTools.SingleChannelHoleFilling(mask_temp2, vec4B);
  209. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp_origin_" + i + ".jpg", temp1);
  210. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp_mask_" + i + ".jpg", mask_temp1);
  211. //循环所有联通区域,找到边
  212. Mat labels_left_1 = new Mat();
  213. Mat stats_left_1 = new Mat();
  214. Mat centroids_left_1 = new Mat();
  215. //连通域数量
  216. int num_1 = Cv2.ConnectedComponentsWithStats(mask_temp1, labels_left_1, stats_left_1, centroids_left_1, PixelConnectivity.Connectivity8);
  217. for (int j = 1; j < stats_left_1.Height; j++)
  218. {
  219. int x = stats_left_1.At<int>(j, 0);
  220. int y = stats_left_1.At<int>(j, 1);
  221. int width = stats_left_1.At<int>(j, 2);
  222. int height = stats_left_1.At<int>(j, 3);
  223. int area = stats_left_1.At<int>(j, 4);
  224. //使用均值判断是否是亮的区域
  225. //如果y 或者 y+height 的行或者相近行不为0的数量>180
  226. if (width == mask_temp1.Width)
  227. {
  228. if (height >= 30)
  229. {
  230. int first = -1;
  231. int end = -1;
  232. for (int a = y; a < y + height; a++)
  233. {
  234. if (mask_temp1.Row[a].CountNonZero() > mask_temp1.Width * 0.95)
  235. {
  236. if (first == -1) first = a;
  237. end = a;
  238. }
  239. }
  240. int ft = first + top;
  241. int et = end + top;
  242. if (Math.Abs(ft - top) > 14 && Math.Abs(ft - bottom) > 14)
  243. arrs.Add(ft);
  244. if (Math.Abs(et - top) > 14 && Math.Abs(et - bottom) > 14)
  245. arrs.Add(et);
  246. /* if(mask_temp1.Row[y+20].CountNonZero()> mask_temp1.Width*0.8)
  247. arrs.Add(y + SplitListB[i]);
  248. if (mask_temp1.Row[y+ height-20].CountNonZero() > mask_temp1.Width * 0.8)
  249. arrs.Add(y + height + SplitListB[i]);*/
  250. }
  251. else
  252. {
  253. int tempV = y + height / 2 + top;
  254. if (Math.Abs(tempV-top)>14 && Math.Abs(tempV - bottom)> 14)
  255. arrs.Add(y + height / 2 + top);
  256. }
  257. }
  258. }
  259. //需要判断是否是不是一个比较亮的,就不需要强行找了
  260. if(mean > 120 && arrs.Count<=1)
  261. {
  262. Mat temp_light = new Mat(originGray, new Rect(centerA, top, 200, bottom - top));
  263. Mat mask_temp3 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0));
  264. for (int h = 0; h < temp_light.Height; h++)
  265. {
  266. for (int w = 0; w < temp_light.Width; w++)
  267. {
  268. int v = temp_light.At<byte>(h, w);
  269. if (v <= thresh_a)
  270. mask_temp3.Set<byte>(h, w, 255);
  271. }
  272. }
  273. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_temp3_" + i + ".jpg", mask_temp3);
  274. for (int h=10; h< mask_temp3.Height-10; h++)
  275. {
  276. if (mask_temp3.Row[h].CountNonZero() > mask_temp3.Width*0.6)
  277. {
  278. int tempV = h + top;
  279. if (Math.Abs(tempV - top) > 14 && Math.Abs(tempV - bottom) > 14)
  280. arrs.Add(tempV);
  281. }
  282. }
  283. }
  284. /*labels_left_1 = new Mat();
  285. stats_left_1 = new Mat();
  286. centroids_left_1 = new Mat();
  287. int num_2 = Cv2.ConnectedComponentsWithStats(mask_temp2, labels_left_1, stats_left_1, centroids_left_1, PixelConnectivity.Connectivity8);
  288. for (int j = 1; j < stats_left_1.Height; j++)
  289. {
  290. int x = stats_left_1.At<int>(j, 0);
  291. int y = stats_left_1.At<int>(j, 1);
  292. int width = stats_left_1.At<int>(j, 2);
  293. int height = stats_left_1.At<int>(j, 3);
  294. int area = stats_left_1.At<int>(j, 4);
  295. //如果y 或者 y+height 的行或者相近行不为0的数量>180
  296. if (width == mask_temp2.Width)
  297. {
  298. if (height >= 30)
  299. {
  300. first = -1;
  301. end = -1;
  302. for (int a = y; a < y + height; a++)
  303. {
  304. if (mask_temp2.Row[a].CountNonZero() > mask_temp2.Width * 0.95)
  305. {
  306. if (first == -1) first = a;
  307. end = a;
  308. }
  309. }
  310. arrs.Add(first + SplitListB[i]);
  311. arrs.Add(end + SplitListB[i]);
  312. *//* if(mask_temp1.Row[y+20].CountNonZero()> mask_temp1.Width*0.8)
  313. arrs.Add(y + SplitListB[i]);
  314. if (mask_temp1.Row[y+ height-20].CountNonZero() > mask_temp1.Width * 0.8)
  315. arrs.Add(y + height + SplitListB[i]);*//*
  316. }
  317. else
  318. {
  319. arrs.Add(y + height / 2 + SplitListB[i]);
  320. }
  321. }
  322. }*/
  323. return arrs;
  324. }
  325. }
  326. }