using OpenCvSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SmartCoalApplication.Base.CommTool { /// /// 防焊的图像预处理 /// public class FangHanTools { /// /// 二值化右侧的值 /// public static int rightV = 0; /// /// 二值化mat /// public static Mat mat_er, final, mat_er1; /// /// 颜色 /// public static Vec4b vec4B = new Vec4b(255, 0, 0, 255); public unsafe static Mat RemoveCircle(Mat srcImage) { Mat gray = null; try { Mat clone = srcImage.Clone(); gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY); //计算灰度平均值 Scalar mean_rgb = srcImage.Mean(); Scalar mean = gray.Mean(gray); //计算直方图 float[] hist_float = HistTools.CalcHist(gray); List contoursAll = new List(); //循环直方图数据 //for (int i = 0; i < mean[0]; i += 2) //{ // if (hist_float[i] > 0) // { // rightV = i; // ////进行二值 // //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0)); // //gray.ForEachAsByte(GrayForEachAsByte); // //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er); // ////去除边界对象 // ////mat_er = BinaryTools.DeleteContours_New(mat_er); // ////去碎屑 // //mat_er = BinaryTools.DebrisRemoval_New(mat_er); // ////空洞填充 // //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B); // //Cv2.Dilate(mat_er, mat_er, null, null, 4); // //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); // //mat_er1 = ~mat_er1; // ////然后寻找轮廓 // //OpenCvSharp.Point[][] contours; // //HierarchyIndex[] hierachy; // //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone); // ////然后找近似圆的 // //if (contours.Length > 0) // //{ // // int p = 0; // // foreach (OpenCvSharp.Point[] ps in contours) // // { // // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75) // // { // // contoursAll.Add(ps); // // } // // p++; // // } // //} // } //} //使用轮廓在空白图上绘制并填充,然后腐蚀 mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0)); Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4); //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er); mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); //对结果图进行二值提取和空洞填充 //进行二值 final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255)); mat_er.ForEachAsByte(GrayForEachAsByte_final); //空洞填充 final = BinaryTools.HoleFilling_NewWithView(final, vec4B); //反色 final = final.CvtColor(ColorConversionCodes.BGR2GRAY); //膨胀 Cv2.Erode(final, final, null, null, 6); for (int h = 0; h < final.Height; h++) { for (int w = 0; w < final.Width; w++) { if (final.At(h, w) < 255) clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255)); } } return clone; } catch(Exception) { } finally { if(mat_er!=null && !mat_er.IsDisposed) { mat_er.Dispose(); mat_er = null; } if (final != null && !final.IsDisposed) { final.Dispose(); final = null; } if (gray != null && !gray.IsDisposed) { gray.Dispose(); gray = null; } rightV = 0; System.GC.Collect(); } return srcImage; } public unsafe static Mat RemoveCircle(Mat srcImage, out int mean0, out Scalar mean_rgb) { Mat gray = null; mean0 = 0; mean_rgb = new Scalar(); try { Mat clone = srcImage.Clone(); gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY); //计算灰度平均值 /*Scalar */mean_rgb = srcImage.Mean(); Scalar mean = gray.Mean(gray); //计算直方图 float[] hist_float = HistTools.CalcHist(gray); List contoursAll = new List(); mean0 = (int)mean[0]; //循环直方图数据 //for (int i = 0; i < mean[0]; i += 2) //{ // if (hist_float[i] > 0) // { // rightV = i; // ////进行二值 // //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0)); // //gray.ForEachAsByte(GrayForEachAsByte); // //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er); // ////去除边界对象 // ////mat_er = BinaryTools.DeleteContours_New(mat_er); // ////去碎屑 // //mat_er = BinaryTools.DebrisRemoval_New(mat_er); // ////空洞填充 // //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B); // //Cv2.Dilate(mat_er, mat_er, null, null, 4); // //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); // //mat_er1 = ~mat_er1; // ////然后寻找轮廓 // //OpenCvSharp.Point[][] contours; // //HierarchyIndex[] hierachy; // //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone); // ////然后找近似圆的 // //if (contours.Length > 0) // //{ // // int p = 0; // // foreach (OpenCvSharp.Point[] ps in contours) // // { // // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75) // // { // // contoursAll.Add(ps); // // } // // p++; // // } // //} // } //} //使用轮廓在空白图上绘制并填充,然后腐蚀 mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0)); Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4); //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er); mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); //对结果图进行二值提取和空洞填充 //进行二值 final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255)); mat_er.ForEachAsByte(GrayForEachAsByte_final); //空洞填充 final = BinaryTools.HoleFilling_NewWithView(final, vec4B); //反色 final = final.CvtColor(ColorConversionCodes.BGR2GRAY); //膨胀 Cv2.Erode(final, final, null, null, 6); for (int h = 0; h < final.Height; h++) { for (int w = 0; w < final.Width; w++) { if (final.At(h, w) < 255) clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255)); } } return clone; } catch (Exception) { } finally { if (mat_er != null && !mat_er.IsDisposed) { mat_er.Dispose(); mat_er = null; } if (final != null && !final.IsDisposed) { final.Dispose(); final = null; } if (gray != null && !gray.IsDisposed) { gray.Dispose(); gray = null; } rightV = 0; System.GC.Collect(); } return srcImage; } public unsafe static Mat RemoveCircle(Mat srcImage, int mean0, Scalar mean_rgb, out bool foundCircle) { Mat gray = null; foundCircle = false; //mean0 = 0; try { Mat clone = srcImage.Clone(); gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY); ////计算灰度平均值 //Scalar mean_rgb = srcImage.Mean(); //Scalar mean = gray.Mean(gray); //计算直方图 float[] hist_float = HistTools.CalcHist(gray); List contoursAll = new List(); //mean0 = (int)mean[0]; //循环直方图数据 for (int i = 0; i < mean0/*mean[0]*/; i += 2) { if (hist_float[i] > 0) { rightV = i; //进行二值 mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0)); gray.ForEachAsByte(GrayForEachAsByte); //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er); //去除边界对象 //mat_er = BinaryTools.DeleteContours_New(mat_er); //去碎屑 mat_er = BinaryTools.DebrisRemoval_New(mat_er); //空洞填充 mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B); Cv2.Dilate(mat_er, mat_er, null, null, 4); mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); mat_er1 = ~mat_er1; //然后寻找轮廓 OpenCvSharp.Point[][] contours; HierarchyIndex[] hierachy; Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone); //然后找近似圆的 if (contours.Length > 0) { int p = 0; foreach (OpenCvSharp.Point[] ps in contours) { if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75) { contoursAll.Add(ps); } p++; } } } } //使用轮廓在空白图上绘制并填充,然后腐蚀 mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0)); Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4); //Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er); mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY); //对结果图进行二值提取和空洞填充 //进行二值 final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255)); mat_er.ForEachAsByte(GrayForEachAsByte_final); //空洞填充 final = BinaryTools.HoleFilling_NewWithView(final, vec4B); //反色 final = final.CvtColor(ColorConversionCodes.BGR2GRAY); //膨胀 Cv2.Erode(final, final, null, null, 6); for (int h = 0; h < final.Height; h++) { for (int w = 0; w < final.Width; w++) { if (final.At(h, w) < 255) { if (!foundCircle) foundCircle = true; break; //clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255)); } } if (foundCircle) { break; } } return foundCircle ? final.Clone() : clone; } catch (Exception) { } finally { if (mat_er != null && !mat_er.IsDisposed) { mat_er.Dispose(); mat_er = null; } if (final != null && !final.IsDisposed) { final.Dispose(); final = null; } if (gray != null && !gray.IsDisposed) { gray.Dispose(); gray = null; } rightV = 0; System.GC.Collect(); } return srcImage; } private unsafe static void GrayForEachAsByte_final(byte* value, int* position) { int y = position[0]; int x = position[1]; byte v = *value; if (v > 0) { final.Set(y, x, vec4B); } } private unsafe static void GrayForEachAsByte(byte* value, int* position) { int y = position[0]; int x = position[1]; byte v = *value; if (v > 0 && v <= rightV) { mat_er.Set(y, x, vec4B); } /*else { mat_er.Set(y, x, new Vec4b(0,0,0,0)); }*/ } } }