FangHanTools.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. /// <summary>
  10. /// 防焊的图像预处理
  11. /// </summary>
  12. public class FangHanTools
  13. {
  14. /// <summary>
  15. /// 二值化右侧的值
  16. /// </summary>
  17. public static int rightV = 0;
  18. /// <summary>
  19. /// 二值化mat
  20. /// </summary>
  21. public static Mat mat_er, final, mat_er1;
  22. /// <summary>
  23. /// 颜色
  24. /// </summary>
  25. public static Vec4b vec4B = new Vec4b(255, 0, 0, 255);
  26. public unsafe static Mat RemoveCircle(Mat srcImage)
  27. {
  28. Mat gray = null;
  29. try
  30. {
  31. Mat clone = srcImage.Clone();
  32. gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
  33. //计算灰度平均值
  34. Scalar mean_rgb = srcImage.Mean();
  35. Scalar mean = gray.Mean(gray);
  36. //计算直方图
  37. float[] hist_float = HistTools.CalcHist(gray);
  38. List<OpenCvSharp.Point[]> contoursAll = new List<OpenCvSharp.Point[]>();
  39. //循环直方图数据
  40. //for (int i = 0; i < mean[0]; i += 2)
  41. //{
  42. // if (hist_float[i] > 0)
  43. // {
  44. // rightV = i;
  45. // ////进行二值
  46. // //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  47. // //gray.ForEachAsByte(GrayForEachAsByte);
  48. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
  49. // ////去除边界对象
  50. // ////mat_er = BinaryTools.DeleteContours_New(mat_er);
  51. // ////去碎屑
  52. // //mat_er = BinaryTools.DebrisRemoval_New(mat_er);
  53. // ////空洞填充
  54. // //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
  55. // //Cv2.Dilate(mat_er, mat_er, null, null, 4);
  56. // //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  57. // //mat_er1 = ~mat_er1;
  58. // ////然后寻找轮廓
  59. // //OpenCvSharp.Point[][] contours;
  60. // //HierarchyIndex[] hierachy;
  61. // //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
  62. // ////然后找近似圆的
  63. // //if (contours.Length > 0)
  64. // //{
  65. // // int p = 0;
  66. // // foreach (OpenCvSharp.Point[] ps in contours)
  67. // // {
  68. // // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
  69. // // {
  70. // // contoursAll.Add(ps);
  71. // // }
  72. // // p++;
  73. // // }
  74. // //}
  75. // }
  76. //}
  77. //使用轮廓在空白图上绘制并填充,然后腐蚀
  78. mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
  79. Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
  80. //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
  81. mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  82. //对结果图进行二值提取和空洞填充
  83. //进行二值
  84. final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
  85. mat_er.ForEachAsByte(GrayForEachAsByte_final);
  86. //空洞填充
  87. final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
  88. //反色
  89. final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
  90. //膨胀
  91. Cv2.Erode(final, final, null, null, 6);
  92. for (int h = 0; h < final.Height; h++)
  93. {
  94. for (int w = 0; w < final.Width; w++)
  95. {
  96. if (final.At<byte>(h, w) < 255)
  97. clone.Set<Vec4b>(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
  98. }
  99. }
  100. return clone;
  101. }
  102. catch(Exception)
  103. {
  104. }
  105. finally
  106. {
  107. if(mat_er!=null && !mat_er.IsDisposed)
  108. {
  109. mat_er.Dispose();
  110. mat_er = null;
  111. }
  112. if (final != null && !final.IsDisposed)
  113. {
  114. final.Dispose();
  115. final = null;
  116. }
  117. if (gray != null && !gray.IsDisposed)
  118. {
  119. gray.Dispose();
  120. gray = null;
  121. }
  122. rightV = 0;
  123. System.GC.Collect();
  124. }
  125. return srcImage;
  126. }
  127. public unsafe static Mat RemoveCircle(Mat srcImage, out int mean0, out Scalar mean_rgb)
  128. {
  129. Mat gray = null;
  130. mean0 = 0; mean_rgb = new Scalar();
  131. try
  132. {
  133. Mat clone = srcImage.Clone();
  134. gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
  135. //计算灰度平均值
  136. /*Scalar */mean_rgb = srcImage.Mean();
  137. Scalar mean = gray.Mean(gray);
  138. //计算直方图
  139. float[] hist_float = HistTools.CalcHist(gray);
  140. List<OpenCvSharp.Point[]> contoursAll = new List<OpenCvSharp.Point[]>();
  141. mean0 = (int)mean[0];
  142. //循环直方图数据
  143. //for (int i = 0; i < mean[0]; i += 2)
  144. //{
  145. // if (hist_float[i] > 0)
  146. // {
  147. // rightV = i;
  148. // ////进行二值
  149. // //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  150. // //gray.ForEachAsByte(GrayForEachAsByte);
  151. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
  152. // ////去除边界对象
  153. // ////mat_er = BinaryTools.DeleteContours_New(mat_er);
  154. // ////去碎屑
  155. // //mat_er = BinaryTools.DebrisRemoval_New(mat_er);
  156. // ////空洞填充
  157. // //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
  158. // //Cv2.Dilate(mat_er, mat_er, null, null, 4);
  159. // //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  160. // //mat_er1 = ~mat_er1;
  161. // ////然后寻找轮廓
  162. // //OpenCvSharp.Point[][] contours;
  163. // //HierarchyIndex[] hierachy;
  164. // //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
  165. // ////然后找近似圆的
  166. // //if (contours.Length > 0)
  167. // //{
  168. // // int p = 0;
  169. // // foreach (OpenCvSharp.Point[] ps in contours)
  170. // // {
  171. // // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
  172. // // {
  173. // // contoursAll.Add(ps);
  174. // // }
  175. // // p++;
  176. // // }
  177. // //}
  178. // }
  179. //}
  180. //使用轮廓在空白图上绘制并填充,然后腐蚀
  181. mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
  182. Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
  183. //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
  184. mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  185. //对结果图进行二值提取和空洞填充
  186. //进行二值
  187. final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
  188. mat_er.ForEachAsByte(GrayForEachAsByte_final);
  189. //空洞填充
  190. final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
  191. //反色
  192. final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
  193. //膨胀
  194. Cv2.Erode(final, final, null, null, 6);
  195. for (int h = 0; h < final.Height; h++)
  196. {
  197. for (int w = 0; w < final.Width; w++)
  198. {
  199. if (final.At<byte>(h, w) < 255)
  200. clone.Set<Vec4b>(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
  201. }
  202. }
  203. return clone;
  204. }
  205. catch (Exception)
  206. {
  207. }
  208. finally
  209. {
  210. if (mat_er != null && !mat_er.IsDisposed)
  211. {
  212. mat_er.Dispose();
  213. mat_er = null;
  214. }
  215. if (final != null && !final.IsDisposed)
  216. {
  217. final.Dispose();
  218. final = null;
  219. }
  220. if (gray != null && !gray.IsDisposed)
  221. {
  222. gray.Dispose();
  223. gray = null;
  224. }
  225. rightV = 0;
  226. System.GC.Collect();
  227. }
  228. return srcImage;
  229. }
  230. public unsafe static Mat RemoveCircle(Mat srcImage, int mean0, Scalar mean_rgb, out bool foundCircle)
  231. {
  232. Mat gray = null;
  233. foundCircle = false;
  234. //mean0 = 0;
  235. try
  236. {
  237. Mat clone = srcImage.Clone();
  238. gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
  239. ////计算灰度平均值
  240. //Scalar mean_rgb = srcImage.Mean();
  241. //Scalar mean = gray.Mean(gray);
  242. //计算直方图
  243. float[] hist_float = HistTools.CalcHist(gray);
  244. List<OpenCvSharp.Point[]> contoursAll = new List<OpenCvSharp.Point[]>();
  245. //mean0 = (int)mean[0];
  246. //循环直方图数据
  247. for (int i = 0; i < mean0/*mean[0]*/; i += 2)
  248. {
  249. if (hist_float[i] > 0)
  250. {
  251. rightV = i;
  252. //进行二值
  253. mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  254. gray.ForEachAsByte(GrayForEachAsByte);
  255. //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
  256. //去除边界对象
  257. //mat_er = BinaryTools.DeleteContours_New(mat_er);
  258. //去碎屑
  259. mat_er = BinaryTools.DebrisRemoval_New(mat_er);
  260. //空洞填充
  261. mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
  262. Cv2.Dilate(mat_er, mat_er, null, null, 4);
  263. mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  264. mat_er1 = ~mat_er1;
  265. //然后寻找轮廓
  266. OpenCvSharp.Point[][] contours;
  267. HierarchyIndex[] hierachy;
  268. Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
  269. //然后找近似圆的
  270. if (contours.Length > 0)
  271. {
  272. int p = 0;
  273. foreach (OpenCvSharp.Point[] ps in contours)
  274. {
  275. if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
  276. {
  277. contoursAll.Add(ps);
  278. }
  279. p++;
  280. }
  281. }
  282. }
  283. }
  284. //使用轮廓在空白图上绘制并填充,然后腐蚀
  285. mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
  286. Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
  287. //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
  288. mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
  289. //对结果图进行二值提取和空洞填充
  290. //进行二值
  291. final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
  292. mat_er.ForEachAsByte(GrayForEachAsByte_final);
  293. //空洞填充
  294. final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
  295. //反色
  296. final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
  297. //膨胀
  298. Cv2.Erode(final, final, null, null, 6);
  299. for (int h = 0; h < final.Height; h++)
  300. {
  301. for (int w = 0; w < final.Width; w++)
  302. {
  303. if (final.At<byte>(h, w) < 255)
  304. {
  305. if (!foundCircle) foundCircle = true;
  306. break;
  307. //clone.Set<Vec4b>(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
  308. }
  309. }
  310. if (foundCircle)
  311. {
  312. break;
  313. }
  314. }
  315. return foundCircle ? final.Clone() : clone;
  316. }
  317. catch (Exception)
  318. {
  319. }
  320. finally
  321. {
  322. if (mat_er != null && !mat_er.IsDisposed)
  323. {
  324. mat_er.Dispose();
  325. mat_er = null;
  326. }
  327. if (final != null && !final.IsDisposed)
  328. {
  329. final.Dispose();
  330. final = null;
  331. }
  332. if (gray != null && !gray.IsDisposed)
  333. {
  334. gray.Dispose();
  335. gray = null;
  336. }
  337. rightV = 0;
  338. System.GC.Collect();
  339. }
  340. return srcImage;
  341. }
  342. private unsafe static void GrayForEachAsByte_final(byte* value, int* position)
  343. {
  344. int y = position[0];
  345. int x = position[1];
  346. byte v = *value;
  347. if (v > 0)
  348. {
  349. final.Set<Vec4b>(y, x, vec4B);
  350. }
  351. }
  352. private unsafe static void GrayForEachAsByte(byte* value, int* position)
  353. {
  354. int y = position[0];
  355. int x = position[1];
  356. byte v = *value;
  357. if (v > 0 && v <= rightV)
  358. {
  359. mat_er.Set<Vec4b>(y, x, vec4B);
  360. }
  361. /*else
  362. {
  363. mat_er.Set<Vec4b>(y, x, new Vec4b(0,0,0,0));
  364. }*/
  365. }
  366. }
  367. }