using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using OpenCvSharp; using Point = System.Drawing.Point; using Size = OpenCvSharp.Size; namespace PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass { internal class InParameter { public int iMethod; public Mat MGryImg; public Mat MHesOutImage; public Mat MValley; public int iDimA; public int iDimB; public int iXiHua; public int iLianJie; public Mat MEdgeOutImage; } public class NewSeg { private Mat m_MOrgImg; private Mat m_MOutImg; private double[] m_adOutParam; private InParameter m_InParam; public int DoSeg(Mat _MOrgImg, Mat _MOutImg, double[] _adOutParam, Vec4b value) { m_MOrgImg = _MOrgImg; m_MOutImg = _MOutImg; m_adOutParam = _adOutParam; PrepareParameter(); if (2 == m_InParam.iMethod) { DetectEdge(value); return 2; } ImgHessian(); FindValley(); FindShed(value); return 1; } private int DetectEdge(Vec4b value) { Mat mat = new Mat(); Cv2.Resize(m_InParam.MGryImg, mat, new Size((double)m_InParam.MGryImg.Cols * 0.2, (double)m_InParam.MGryImg.Rows * 0.2)); Cv2.Sobel(mat, m_InParam.MEdgeOutImage, -1, 1, 1); Cv2.Threshold(m_InParam.MEdgeOutImage, m_InParam.MEdgeOutImage, 20.0, 255.0, ThresholdTypes.Binary); Mat mat2 = new Mat(); Cv2.Canny(mat, mat2, 50.0, 50.0); m_InParam.MEdgeOutImage = (Mat)(m_InParam.MEdgeOutImage | mat2); Mat structuringElement = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(7, 7), new OpenCvSharp.Point(-1, -1)); Cv2.MorphologyEx(m_InParam.MEdgeOutImage, m_InParam.MEdgeOutImage, MorphTypes.Close, (InputArray)structuringElement); Mat mat3 = new Mat(); Cv2.Threshold(mat, mat3, 150.0, 255.0, ThresholdTypes.BinaryInv); m_InParam.MEdgeOutImage = (Mat)(m_InParam.MEdgeOutImage & mat3); ConnectionBoundary(m_InParam.MEdgeOutImage, 108); Mat mat4 = new Mat(); Cv2.BitwiseNot(m_InParam.MEdgeOutImage, mat4); structuringElement = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(7, 7), new OpenCvSharp.Point(-1, -1)); Cv2.MorphologyEx(mat4, mat4, MorphTypes.Erode, (InputArray)structuringElement); Mat mat5 = new Mat(); Cv2.Resize(m_MOrgImg, mat5, new Size(mat4.Cols, mat4.Rows)); Mat mat6 = new Mat(mat4.Size(), 4); Cv2.FindContours(mat4, out OpenCvSharp.Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple); for (int i = 0; i < hierarchy.Length; i++) { Cv2.DrawContours(mat6, contours, i, Scalar.All(i + 1), 1, LineTypes.Link8, hierarchy); } Cv2.Watershed(mat5, mat6); Mat mat7 = new Mat(mat5.Rows, mat5.Cols, MatType.CV_8UC1, Scalar.All(0.0)); int rows = mat6.Rows; int cols = mat6.Cols; int[] array = new int[2] { 0, 0 }; while (array[0] < rows) { array[1] = 0; while (array[1] < cols) { if (0 >= mat6.At(array[0], array[1])) { mat7.Set(array, byte.MaxValue); } array[1]++; } array[0]++; } Cv2.Resize(mat7, mat7, new Size(m_InParam.MGryImg.Cols, m_InParam.MGryImg.Rows)); Cv2.Resize(mat7, mat7, new Size(m_InParam.MGryImg.Cols, m_InParam.MGryImg.Rows)); //Vec3b value = new Vec3b(0, 0, byte.MaxValue); rows = m_MOutImg.Rows; cols = m_MOutImg.Cols; array[0] = 0; while (array[0] < rows) { array[1] = 0; while (array[1] < cols) { if (120 < mat7.At(array[0], array[1])) { m_MOutImg.Set(array, value); } array[1]++; } array[0]++; } return 1; } public int LTQY() { Mat mat = new Mat(); Mat mat2 = new Mat(); Mat mat3 = new Mat(); Mat mEdgeOutImage = m_InParam.MEdgeOutImage; int num = Cv2.ConnectedComponentsWithStats(mEdgeOutImage, mat, mat2, mat3); int[] array = new int[num]; for (int i = 1; i < num; i++) { array[i] = 255; if (mat2.At(i, 4) < 20) { array[i] = 0; } } Mat mat4 = new Mat(mEdgeOutImage.Rows, mEdgeOutImage.Cols, MatType.CV_8UC1, Scalar.All(0.0)); for (int j = 0; j < mat4.Rows; j++) { for (int k = 0; k < mEdgeOutImage.Cols; k++) { int num2 = mat.At(j, k); mat4.Set(j, k, (byte)array[num2]); } } return 0; } public void ImgThin(Mat src, int maxIterations = -1) { Cv2.Threshold(src, src, 100.0, 1.0, ThresholdTypes.Binary); int rows = src.Rows; int cols = src.Cols; int num = 0; while (true) { num++; if (maxIterations != -1 && num > maxIterations) { break; } List list = new List(); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { src.At(i, j); int num2 = (i != 0) ? src.At(i - 1, j) : 0; int num3 = (i != 0 && j != cols - 1) ? src.At(i - 1, j + 1) : 0; int num4 = (j != cols - 1) ? src.At(i, j + 1) : 0; int num5 = (i != rows - 1 && j != cols - 1) ? src.At(i + 1, j + 1) : 0; int num6 = (i != rows - 1) ? src.At(i + 1, j) : 0; int num7 = (i != rows - 1 && j != 0) ? src.At(i + 1, j - 1) : 0; int num8 = (j != 0) ? src.At(i, j - 1) : 0; int num9 = (i != 0 && j != 0) ? src.At(i - 1, j - 1) : 0; if (num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 >= 2 && num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 <= 6) { int num10 = 0; if (num2 == 0 && num3 == 1) { num10++; } if (num3 == 0 && num4 == 1) { num10++; } if (num4 == 0 && num5 == 1) { num10++; } if (num5 == 0 && num6 == 1) { num10++; } if (num6 == 0 && num7 == 1) { num10++; } if (num7 == 0 && num8 == 1) { num10++; } if (num8 == 0 && num9 == 1) { num10++; } if (num9 == 0 && num2 == 1) { num10++; } if (num10 == 1 && num2 * num4 * num6 == 0 && num4 * num6 * num8 == 0) { list.Add(new int[2] { i, j }); } } } } list.ForEach(delegate (int[] aiP) { src.Set(aiP, (byte)0); }); if (list.Count() == 0) { break; } list.Clear(); for (int k = 0; k < rows; k++) { for (int l = 0; l < cols; l++) { int num11 = src.At(k, l); if (num11 != 1) { continue; } int num12 = (k != 0) ? src.At(k - 1, l) : 0; int num13 = (k != 0 && l != cols - 1) ? src.At(k - 1, l + 1) : 0; int num14 = (l != cols - 1) ? src.At(k, l + 1) : 0; int num15 = (k != rows - 1 && l != cols - 1) ? src.At(k + 1, l + 1) : 0; int num16 = (k != rows - 1) ? src.At(k + 1, l) : 0; int num17 = (k != rows - 1 && l != 0) ? src.At(k + 1, l - 1) : 0; int num18 = (l != 0) ? src.At(k, l - 1) : 0; int num19 = (k != 0 && l != 0) ? src.At(k - 1, l - 1) : 0; if (num12 + num13 + num14 + num15 + num16 + num17 + num18 + num19 >= 2 && num12 + num13 + num14 + num15 + num16 + num17 + num18 + num19 <= 6) { int num20 = 0; if (num12 == 0 && num13 == 1) { num20++; } if (num13 == 0 && num14 == 1) { num20++; } if (num14 == 0 && num15 == 1) { num20++; } if (num15 == 0 && num16 == 1) { num20++; } if (num16 == 0 && num17 == 1) { num20++; } if (num17 == 0 && num18 == 1) { num20++; } if (num18 == 0 && num19 == 1) { num20++; } if (num19 == 0 && num12 == 1) { num20++; } if (num20 == 1 && num12 * num14 * num18 == 0 && num12 * num16 * num18 == 0) { list.Add(new int[2] { k, l }); } } } } list.ForEach(delegate (int[] aiP) { src.Set(aiP, (byte)0); }); if (list.Count() == 0) { break; } list.Clear(); } Cv2.Threshold(src, src, 0.0, 255.0, ThresholdTypes.Binary); } public void ConnectionBoundary(Mat Img, int iDistance) { Cv2.Threshold(Img, Img, 100.0, 1.0, ThresholdTypes.Binary); Mat mat = Connectivity(Img); List list = new List(); List list2 = new List(); int[] array = new int[2] { 1, 0 }; while (array[0] < Img.Rows - 1) { array[1] = 1; while (array[1] < Img.Cols - 1) { if (1 <= Img.At(array[0], array[1]) && mat.At(array[0], array[1]) == 0) { Img.Set(array, (byte)0); } if (1 <= Img.At(array[0], array[1]) && 1 == mat.At(array[0], array[1])) { list.Add(new int[2] { array[0], array[1] }); int num = 0; int i = 0; for (num = -1; num <= 1; num++) { bool flag = false; for (i = -1; i <= 1; i++) { if ((num != 0 || i != 0) && Img.At(array[0] + num, array[1] + i) >= 1) { flag = true; break; } } if (flag) { break; } } list2.Add(new int[2] { -num, -i }); } array[1]++; } array[0]++; } int num2 = list.Count(); List[] array2 = new List[num2]; List list3 = new List(); List list4 = new List(); for (int j = 0; j < num2; j++) { list3.Add(j); int[] array3 = list[j]; array2[j] = new List(); array2[j].Add(new int[2] { array3[0], array3[1] }); } Mat mat2 = new Mat(Img.Size(), MatType.CV_32SC1); array[0] = 0; while (array[0] < Img.Rows) { array[1] = 0; while (array[1] < Img.Cols) { int value = Img.At(array[0], array[1]); mat2.Set(array, value); array[1]++; } array[0]++; } int[,] array4 = new int[260, 2] { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, 1 }, { -1, 1 }, { 1, 1 }, { 1, -1 }, { -1, -1 }, { -2, 0 }, { 0, 2 }, { 2, 0 }, { 0, -2 }, { -2, 1 }, { -1, 2 }, { 1, 2 }, { 2, 1 }, { 2, -1 }, { 1, -2 }, { -1, -2 }, { -2, -1 }, { -2, 2 }, { 2, 2 }, { 2, -2 }, { -2, -2 }, { -3, 0 }, { 0, 3 }, { 3, 0 }, { 0, -3 }, { -3, 1 }, { -1, 3 }, { 1, 3 }, { 3, 1 }, { 3, -1 }, { 1, -3 }, { -1, -3 }, { -3, -1 }, { 2, 3 }, { -3, 2 }, { -2, -3 }, { -2, 3 }, { -3, -2 }, { 3, 2 }, { 3, -2 }, { 2, -3 }, { 4, 0 }, { 0, 4 }, { -4, 0 }, { 0, -4 }, { 1, 4 }, { 4, -1 }, { 4, 1 }, { -1, -4 }, { -4, 1 }, { -4, -1 }, { -1, 4 }, { 1, -4 }, { 3, 3 }, { 3, -3 }, { -3, 3 }, { -3, -3 }, { -4, -2 }, { -2, -4 }, { -4, 2 }, { 4, 2 }, { -2, 4 }, { 4, -2 }, { 2, -4 }, { 2, 4 }, { 4, -3 }, { -3, 4 }, { 4, 3 }, { 5, 0 }, { 0, 5 }, { 0, -5 }, { -5, 0 }, { 3, 4 }, { -3, -4 }, { -4, -3 }, { 3, -4 }, { -4, 3 }, { 5, -1 }, { -1, 5 }, { -1, -5 }, { 5, 1 }, { 1, -5 }, { -5, 1 }, { -5, -1 }, { 1, 5 }, { -2, 5 }, { 2, -5 }, { 2, 5 }, { 5, 2 }, { -5, 2 }, { -2, -5 }, { 5, -2 }, { -5, -2 }, { -4, 4 }, { 4, -4 }, { 4, 4 }, { -4, -4 }, { 3, -5 }, { -5, 3 }, { -3, 5 }, { 5, -3 }, { 5, 3 }, { -5, -3 }, { -3, -5 }, { 3, 5 }, { 0, 6 }, { 0, -6 }, { -6, 0 }, { 6, 0 }, { -6, 1 }, { 1, 6 }, { -6, -1 }, { 1, -6 }, { -1, 6 }, { -1, -6 }, { 6, -1 }, { 6, 1 }, { 2, 6 }, { -2, -6 }, { 6, 2 }, { -6, 2 }, { 2, -6 }, { -6, -2 }, { -2, 6 }, { 6, -2 }, { -5, -4 }, { 5, 4 }, { 4, 5 }, { -4, 5 }, { 4, -5 }, { -5, 4 }, { 5, -4 }, { -4, -5 }, { -3, 6 }, { -6, 3 }, { -3, -6 }, { -6, -3 }, { 3, -6 }, { 6, 3 }, { 3, 6 }, { 6, -3 }, { 0, 7 }, { 7, 0 }, { 0, -7 }, { -7, 0 }, { 5, -5 }, { 1, 7 }, { -1, 7 }, { -5, -5 }, { -7, -1 }, { -7, 1 }, { -1, -7 }, { 1, -7 }, { 7, 1 }, { -5, 5 }, { 5, 5 }, { 7, -1 }, { 6, 4 }, { -6, 4 }, { 6, -4 }, { -6, -4 }, { -4, -6 }, { 4, 6 }, { 4, -6 }, { -4, 6 }, { 7, -2 }, { 7, 2 }, { 2, 7 }, { -7, -2 }, { -2, -7 }, { -2, 7 }, { 2, -7 }, { -7, 2 }, { 7, -3 }, { -3, 7 }, { -3, -7 }, { 3, -7 }, { -7, 3 }, { 3, 7 }, { 7, 3 }, { -7, -3 }, { 6, -5 }, { 5, 6 }, { 5, -6 }, { 6, 5 }, { -5, 6 }, { -5, -6 }, { -6, 5 }, { -6, -5 }, { 8, 0 }, { 0, -8 }, { -8, 0 }, { 0, 8 }, { -4, 7 }, { 4, -7 }, { -8, -1 }, { -1, 8 }, { -7, 4 }, { -1, -8 }, { 7, 4 }, { 1, -8 }, { 1, 8 }, { 8, 1 }, { 8, -1 }, { -4, -7 }, { -7, -4 }, { 7, -4 }, { -8, 1 }, { 4, 7 }, { -2, 8 }, { 2, -8 }, { -2, -8 }, { 8, 2 }, { -8, 2 }, { -8, -2 }, { 2, 8 }, { 8, -2 }, { -6, 6 }, { 6, 6 }, { 6, -6 }, { -6, -6 }, { 3, -8 }, { -3, 8 }, { 8, 3 }, { 8, -3 }, { 3, 8 }, { -3, -8 }, { -8, 3 }, { -8, -3 }, { 7, -5 }, { -7, -5 }, { 5, 7 }, { 7, 5 }, { 5, -7 }, { -7, 5 }, { -5, -7 }, { -5, 7 }, { 8, -4 }, { -4, -8 }, { -8, -4 }, { 8, 4 }, { 4, 8 }, { -8, 4 }, { 4, -8 }, { -4, 8 }, { 0, -9 }, { 0, 9 }, { -9, 0 }, { 9, 0 }, { 9, -1 }, { -9, -1 }, { 1, -9 }, { -1, 9 }, { -1, -9 }, { -9, 1 }, { 1, 9 }, { 9, 1 } }; while (list3.Count() != 0) { int num3 = list3[0]; list3.RemoveAt(0); int index = array2[num3].Count() - 1; int[] array5 = array2[num3][index]; int[] pnt = new int[2] { array5[0], array5[1] }; int[] array6 = list2[num3]; bool flag2 = false; for (int k = 0; k < iDistance; k++) { if (0 > array6[0] * array4[k, 0] || 0 > array6[1] * array4[k, 1]) { continue; } pnt[0] = array5[0] + array4[k, 0]; pnt[1] = array5[1] + array4[k, 1]; if (0 > pnt[0] || Img.Rows <= pnt[0] || 0 > pnt[1] || Img.Cols <= pnt[1]) { continue; } int num4 = mat2.At(pnt[0], pnt[1]); if (1 < num4 && num3 != num4) { list3.Remove(num4); if (!list4.Contains(num4)) { int num5 = array2[num4].FindIndex((int[] t) => t[0] == pnt[0] && t[1] == pnt[1]); int num6 = array2[num4].Count() - 1; if (1 <= num6 - num5) { for (int l = num5 + 1; l <= num6; l++) { mat2.Set(array2[num4][l], 0); } array2[num4].RemoveRange(num5 + 1, num6 - num5); } list4.Add(num4); list4.Add(num3); } ConnectTwoPnt(array5, pnt, array2[num3]); flag2 = true; break; } if (1 == num4) { ConnectTwoPnt(array5, pnt, array2[num3]); flag2 = true; break; } } if (!flag2) { pnt[0] = array5[0] + array6[0]; pnt[1] = array5[1] + array6[1]; if (0 <= pnt[0] && Img.Rows > pnt[0] && 0 <= pnt[1] && Img.Cols > pnt[1]) { array2[num3].Add(pnt); mat2.Set(pnt, num3); list3.Add(num3); } } } for (int m = 0; m < num2; m++) { array2[m].ForEach(delegate (int[] aiP) { Img.Set(aiP, (byte)1); }); } Cv2.Threshold(Img, Img, 0.0, 255.0, ThresholdTypes.Binary); } public void ConnectTwoPnt(int[] pntA, int[] pntB, List DevelopmentA) { int num = pntA[0]; int num2 = pntA[1]; int num3 = pntB[0] - num; int num4 = pntB[1] - num2; int num5 = (num3 != 0) ? (num3 / Math.Abs(num3)) : 0; int num6 = (num4 != 0) ? (num4 / Math.Abs(num4)) : 0; while (num3 != 0 || num4 != 0) { if (Math.Abs(num3) > Math.Abs(num4)) { num += num5; } else { num2 += num6; } DevelopmentA.Add(new int[2] { num, num2 }); num3 = pntB[0] - num; num4 = pntB[1] - num2; } } public Mat Connectivity(Mat Img) { Mat mat = new Mat(Img.Size(), MatType.CV_8UC1); int[] array = new int[2] { 1, 0 }; while (array[0] < Img.Rows - 1) { array[1] = 0; while (array[1] < Img.Cols) { byte b = Img.At(array[0] - 1, array[1]); b = (byte)(b + Img.At(array[0], array[1])); b = (byte)(b + Img.At(array[0] + 1, array[1])); mat.Set(array, b); array[1]++; } array[0]++; } Mat mat2 = new Mat(Img.Size(), MatType.CV_8UC1); array[0] = 1; while (array[0] < Img.Rows - 1) { array[1] = 1; while (array[1] < Img.Cols - 1) { byte b2 = mat.At(array[0], array[1] - 1); b2 = (byte)(b2 + mat.At(array[0], array[1])); b2 = (byte)(b2 + mat.At(array[0], array[1] + 1)); b2 = (byte)(b2 - Img.At(array[0], array[1])); mat2.Set(array, b2); array[1]++; } array[0]++; } mat = null; return mat2; } private int FindShed(Vec4b value) { Mat mat = new Mat(m_InParam.MValley.Size(), 4); Cv2.FindContours(m_InParam.MValley, out OpenCvSharp.Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple); for (int i = 0; i < hierarchy.Length; i++)//# 相同的条件,这里比demo慢? { Cv2.DrawContours(mat, contours, i, Scalar.All(i + 1), 1, LineTypes.Link8, hierarchy); } Cv2.Watershed(m_MOrgImg, mat); int rows = mat.Rows; int cols = mat.Cols; int[] array = new int[2]; //Vec3b value = new Vec3b(0, 0, byte.MaxValue); array[0] = 0; while (array[0] < rows) { array[1] = 0; while (array[1] < cols) { if (0 >= mat.At(array[0], array[1])) { m_MOutImg.Set(array, value); } array[1]++; } array[0]++; } return 1; } private int FindValley() { Mat structuringElement = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(m_InParam.iDimA, m_InParam.iDimA), new OpenCvSharp.Point(-1, -1)); Cv2.MorphologyEx(m_InParam.MHesOutImage, m_InParam.MHesOutImage, MorphTypes.Close, (InputArray)structuringElement); Cv2.BitwiseNot(m_InParam.MHesOutImage, m_InParam.MValley); Size size = m_InParam.MValley.Size(); Mat mat = (Mat)Mat.Zeros(size.Height + 2, size.Width + 2, m_InParam.MValley.Type()); m_InParam.MValley.CopyTo(mat.SubMat(new Range(1, size.Height + 1), new Range(1, size.Width + 1))); Cv2.FloodFill(mat, new OpenCvSharp.Point(0, 0), new Scalar(255.0)); Mat mat2 = new Mat(); mat.SubMat(new Range(1, size.Height + 1), new Range(1, size.Width + 1)).CopyTo(mat2); Cv2.BitwiseNot(mat2, mat2); m_InParam.MValley = (Mat)(m_InParam.MValley | mat2); return 1; } private int PrepareParameter() { m_InParam = new InParameter(); m_InParam.MGryImg = new Mat(); if (3 == m_MOrgImg.Channels()) { Cv2.CvtColor(m_MOrgImg, m_InParam.MGryImg, ColorConversionCodes.BGR2GRAY/*RGB2GRAY*/); } else { if (1 != m_MOrgImg.Channels()) { return -1; } m_InParam.MGryImg = m_MOrgImg.Clone(); } m_InParam.iMethod = 1; m_InParam.iDimA = 3; m_InParam.iDimB = 1; bool flag = false; int num = 0; double num2 = 1.0; double num3 = 1.0; double num4 = 0.0; m_InParam.iXiHua = 0; m_InParam.iLianJie = 0; if (m_adOutParam != null) { if (m_adOutParam[0] > 1.5 && m_adOutParam[0] < 2.5) { m_InParam.iMethod = 2; } if (m_adOutParam[1] > 1.5 && m_adOutParam[1] < 2.5) { flag = true; } if (m_adOutParam[2] > 0.5 && m_adOutParam[2] < 100.5) { m_InParam.iDimA = (int)(m_adOutParam[2] + 0.5); } if (m_adOutParam[3] > 0.5 && m_adOutParam[3] < 100.5) { m_InParam.iDimB = (int)(m_adOutParam[3] + 0.5); } if (m_adOutParam[4] > 1.5 && m_adOutParam[4] < 2.5) { num = 2; num2 = Math.Max(m_adOutParam[5], 1.0); } else if (m_adOutParam[4] > 2.5 && m_adOutParam[4] < 3.5) { num = 3; num2 = Math.Max(m_adOutParam[5], 1.0); } else if (m_adOutParam[4] > 3.5 && m_adOutParam[4] < 4.5) { num = 4; num3 = m_adOutParam[6]; num4 = m_adOutParam[7]; } if (m_adOutParam[8] > 1.5 && m_adOutParam[8] < 2.5) { m_InParam.iXiHua = 2; } if (m_adOutParam[9] > 1.5 && m_adOutParam[9] < 2.5) { m_InParam.iLianJie = 2; } } if (flag || num > 1) { int rows = m_InParam.MGryImg.Rows; int cols = m_InParam.MGryImg.Cols; int[] array = new int[2] { 0, 0 }; while (array[0] < rows) { array[1] = 0; while (array[1] < cols) { byte b = m_InParam.MGryImg.At(array); if (flag) { b = (byte)(255 - b); } if (2 == num) { b = (byte)((double)(int)b / num2 + 0.5); } if (3 == num) { double num5 = 255.0 - (double)(int)b; num5 /= num2; b = (byte)(255.0 - num5 + 0.5); } if (4 == num) { double val = num3 * (double)(int)b + num4; val = Math.Min(Math.Max(val, 0.0), 255.0); b = (byte)(val + 0.5); } m_InParam.MGryImg.Set(array, b); array[1]++; } array[0]++; } } m_InParam.MHesOutImage = new Mat(); m_InParam.MValley = new Mat(); m_InParam.MEdgeOutImage = new Mat(); return 1; } private int ImgHessian() { Mat mat = new Mat(); m_InParam.MGryImg.ConvertTo(mat, 5); int rows = mat.Rows; int cols = mat.Cols; int num = 5; double num2 = 1.2; Mat mat2 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0)); Mat mat3 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0)); Mat mat4 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0)); for (int i = -num; i <= num; i++) { for (int j = -num; j <= num; j++) { double num3 = 1.0 - (double)(i * i) / (num2 * num2); double num4 = Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2)); double num5 = -1.0 / (Math.PI * 2.0 * Math.Pow(num2, 4.0)); double num6 = num3 * num4 * num5; float value = (float)num6; mat2.Set(i + num, j + num, value); mat4.Set(i + num, j + num, (float)((1.0 - (double)(j * j) / (num2 * num2)) * Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2)) * (-1.0 / (Math.PI * 2.0 * Math.Pow(num2, 4.0))))); mat3.Set(i + num, j + num, (float)((double)(i * j) * Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2)) * (1.0 / (Math.PI * 2.0 * Math.Pow(num2, 6.0))))); } } Mat mat5 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0)); Mat mat6 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0)); Mat mat7 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0)); Cv2.Filter2D(mat, mat5, mat5.Depth(), mat2);//# 相同的条件,这里比demo慢 Cv2.Filter2D(mat, mat6, mat6.Depth(), mat4); Cv2.Filter2D(mat, mat7, mat7.Depth(), mat3); byte[,] array = new byte[rows, cols]; float[] array2 = new float[rows * cols]; float[] array3 = new float[rows * cols]; float[] array4 = new float[rows * cols]; Marshal.Copy(mat5.Data, array2, 0, rows * cols); Marshal.Copy(mat6.Data, array3, 0, rows * cols); Marshal.Copy(mat7.Data, array4, 0, rows * cols); for (int k = 0; k < rows; k++) { for (int l = 0; l < cols; l++) { float num7 = array2[k * cols + l]; float num8 = array3[k * cols + l]; float num9 = array4[k * cols + l]; double num10 = (num7 + num8) * (num7 + num8) - 4f * (num7 * num8 - num9 * num9); if (!(num10 < 0.0)) { num10 = Math.Sqrt(num10); double num11 = ((double)(num7 + num8) + num10) / 2.0; double value2 = ((double)(num7 + num8) - num10) / 2.0; if (num11 > 0.0 && Math.Abs(num11) > 1.0 + Math.Abs(value2)) { array[k, l] = byte.MaxValue; } } } } m_InParam.MHesOutImage = new Mat(rows, cols, MatType.CV_8UC1, array, 0L); return 0; } } ///// ///// class OUTsegmsurf { public Mat cellbw; public Mat wat; public Mat imsegm; public Mat minima; public Mat minimacell; //kkkkk public NEW_TYPE_SegInf info; } class In5segmsurf { public string smoothim_method; public int filterridges; public double gaussian_stdev; public string LEVEL; public double classifycells_convexarea; public double classifycells_convexperim; public Mat OrgImg; public In5segmsurf Clone() { return this.MemberwiseClone() as In5segmsurf; } } class In6segmsurf { public string prmfile;//Path to parameter file public Mat minima;//All markers, for instance from manual drawings public Mat minimacell;//; for cells, for instance from manual drawings public Mat imnucl;//Nucleus image for defining markers } class PMergefragments//区域合并 { public int optlog; public int optint; public double intint; public double conv; public PMergefragments Clone() { return this.MemberwiseClone() as PMergefragments; } } class PSmoothim//平滑 { public string method; public double[] h; public int gpu; public int dim; public int ced_maxniter; public PSmoothim Clone() { return this.MemberwiseClone() as PSmoothim; } } class PClassifycells//区域分类 { public double convexarea; public double convexperim; public double[] h; public double minvolfull; public double maxvolfull; public string method; public PClassifycells Clone() { return this.MemberwiseClone() as PClassifycells; } } class In4smoothim { public int filterridges; public string LEVEL; public double gaussian_stdev; public double[] getminima_h; public double getminima_minvolfull; public double getminima_maxvolfull; public double getminima_level; //public string getminima_method; public PMergefragments mergefragments; public PSmoothim smoothim; public PClassifycells classifycells; public int[] dim; public double minvol; public double minvolvox; public double maxvol; public double maxvolvox; public double watminvolfull; public double watmaxvolfull; public double minvolfull; public double maxvolfull; public double[] h; public double just; public int gpu; public int illum; public double illumdiameter; public int merge; public int iInterpolationMethod;//zzzzz new, 1 for Cubic spline interpolation, 2 for Bilinear interpolation, 3 for Nearest neighbor interpolation } class OUTgetminima { public Mat minimacell; public Mat minima; } class OUTclassifycells { public Mat cellbw; public PClassifycells classifycells; } class OUTmaxfilt3 { public List[,] maxim; public float[,] sumim; public int numpoints; public float[][][] minim; } class MyFilter { public double[] x; public double[] y; public double[] z; } class OLDcellsegm { public const double m_PI = 3.1415926535897931; void mf_mergeinputpar(In4smoothim prm, In5segmsurf prmin) { prm.smoothim.method = prmin.smoothim_method; prm.filterridges = prmin.filterridges; prm.gaussian_stdev = prmin.gaussian_stdev; prm.LEVEL = (string)prmin.LEVEL.Clone(); prm.classifycells.convexarea = prmin.classifycells_convexarea; prm.classifycells.convexperim = prmin.classifycells_convexperim; } void mf_cellsize(double minvol, double maxvol, In4smoothim prm, int ThreeDimNO) { if (0 == prm.h[0] * prm.h[1] * prm.h[2]) { Console.WriteLine("There is zero voxel size"); } double minr = Math.Pow((3 * minvol) / (4 * m_PI), 1 / 3); //maxr = ((3*maxvol)/(4*pi))^(1/3); //maxz = maxr/h(3); double minz = minr / prm.h[2]; if (ThreeDimNO < minz) { //shrinink a sphere to a circle double r = Math.Pow((3 * maxvol) / (4 * m_PI), 1 / 3); maxvol = Math.Pow(ThreeDimNO, prm.just) * m_PI * r * r; r = Math.Pow((3 * minvol) / (4 * m_PI), 1 / 3); minvol = Math.Pow(ThreeDimNO, prm.just) * m_PI * r * r; } double voxelvol = prm.h[0] * prm.h[1] * prm.h[2]; double minvolvox = Math.Round(minvol / voxelvol, MidpointRounding.AwayFromZero); double maxvolvox = Math.Round(maxvol / voxelvol, MidpointRounding.AwayFromZero); prm.minvol = minvol; prm.minvolvox = minvolvox; prm.maxvol = maxvol; prm.maxvolvox = maxvolvox; } public OUTsegmsurf mf_segmsurf_progress_auto(Mat GryImg, Color phaseColor, int adOutParam0, int adOutParam1, int adOutParam2, int adOutParam3, int adOutParam4, double adOutParam5, int adOutParam6) { long start = Cv2.GetTickCount(); OUTsegmsurf rtn = new OUTsegmsurf(); //ttttt Cv2.FindContours(watermark, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null); rtn.wat = new Mat(GryImg.Size(), MatType.CV_8UC4, new Scalar(phaseColor.B, phaseColor.G, phaseColor.R, 0)); //Mat OutImg = new Mat(GryImg.Rows, GryImg.Cols, MatType.CV_8UC3, Scalar.All(0)); NewSeg NSeg = new NewSeg(); //转为为灰度? if (/*3 == GryImg.Channels() || */4 == GryImg.Channels()) { Cv2.CvtColor(GryImg, GryImg, ColorConversionCodes.BGRA2BGR); } else if (1 == GryImg.Channels()) { Cv2.CvtColor(GryImg, GryImg, ColorConversionCodes.GRAY2BGR); } //Cv2.ImShow("oriImg", GryImg); //Cv2.WaitKey(); double time_v2 = (Cv2.GetTickCount() - start) / Cv2.GetTickFrequency(); System.Console.WriteLine("晶界重现_V2_执行时间1:" + time_v2); double[] adOutParam = new double[10]; adOutParam[0] = adOutParam0;// 2;//方法1原方法,方法2模拟软件方法 adOutParam[1] = adOutParam1;// 0;//默认为暗晶界,为2时为亮晶界 adOutParam[2] = adOutParam2;// 3;//尺度系数,默认为3 adOutParam[3] = adOutParam3;// 1;//晶界宽度系数,默认为1 adOutParam[4] = adOutParam4;// 0;//亮度调整,为0不调整,为1自动调整,为2整体调暗,为3整体调亮,为4线性调整 adOutParam[5] = adOutParam5;// 1;//adOutParam[4]为2或3时adOutParam[5]有意义,表示调整强度,必须大于1,等于1无变化 adOutParam[6] = adOutParam6==0 ? 1 : 0;// 1;//adOutParam[4]为4时adOutParam[6]有意义,线性变换斜率。 adOutParam[7] = adOutParam6 == 1 ? 1 : 0;// 0;//adOutParam[4]为4时adOutParam[7]有意义,线性变换截距。 adOutParam[8] = 0;//为2时表示边界必须细化 adOutParam[9] = 0;//为2时表示边界必须连接 NSeg.DoSeg(GryImg.Clone()/*OrgImg*/, rtn.wat, adOutParam, new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255)); ////ttttt Cv2.DrawContours(rtn.wat, contour, -1, Scalar.Red); //int Rows = OutImg.Rows; //int Cols = OutImg/*watermark*/.Cols; //int[] point = new int[2]; //Vec4b redcol; //if (phaseColor != null) //{ // redcol = new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255); //} //else // redcol = new Vec4b(0, 0, 255/*255*/, 255); //for (point[0] = 0; point[0] < Rows; point[0]++) //{ // for (point[1] = 0; point[1] < Cols; point[1]++) // { // if (0 >= watermark.At(point[0], point[1])) // { // rtn.wat.Set(point[0], point[1], redcol);//### // } // } //} time_v2 = (Cv2.GetTickCount() - start) / Cv2.GetTickFrequency(); System.Console.WriteLine("晶界重现_V2_执行时间2:" + time_v2); ////Cv2.ImShow("contour", rtn.wat);//kkkkk ////Cv2.WaitKey(0);//kkkkk //control.Cursor = cursor;// System.Windows.Forms.Cursors.Default; return rtn; } OUTclassifycells classifycells(Mat watermark, Mat imsegmini, PClassifycells prmclf, Mat minimacell = null) { OUTclassifycells rtn = new OUTclassifycells(); return rtn; } OUTgetminima getminima(Mat imsegm, Mat minimacell, In5segmsurf prmin) { OUTgetminima rtn = new OUTgetminima(); rtn.minima = null; rtn.minimacell = null; if (null == minimacell) { rtn.minima = automated(imsegm, prmin); } return rtn; } Mat automated(Mat imsegm, In5segmsurf prmin) { Mat mat_mean = new Mat(), mat_stddev = new Mat(); double m, s, d; //Cv2.MeanStdDev(imsegm, mat_mean, mat_stddev); //m = mat_mean.At(0, 0); //s = mat_stddev.At(0, 0); //d = 0;//mmmmm double th; //th = Math.Min(Math.Max(m+d*s, m/2),1.5*m); Mat minima = new Mat(), minimacell = new Mat(imsegm.Size(), MatType.CV_8UC3); //Cv2.Threshold(imsegm, minimacell, th, 255, ThresholdTypes.Binary); int iRad = 39; Mat matTempA = new Mat(); Mat matTempB = new Mat(); Cv2.MedianBlur(imsegm, matTempA, iRad); Cv2.AddWeighted(imsegm, 1, matTempA, -1, 0, matTempB); Cv2.MeanStdDev(matTempB, mat_mean, mat_stddev); m = mat_mean.At(0, 0); s = mat_stddev.At(0, 0); d = 0;//mmmmm th = m + d * s; Cv2.Threshold(matTempB, minimacell, th, 255, ThresholdTypes.Binary); int diam;//mmmmm Mat kernel; diam = 9; kernel = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(diam, diam), new OpenCvSharp.Point(-1, -1)); Cv2.Dilate(minimacell, minimacell, kernel); diam = 3; kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(diam, diam), new OpenCvSharp.Point(-1, -1)); Cv2.Erode(minimacell, minimacell, kernel); Cv2.MorphologyEx(minimacell, minimacell, MorphTypes.Open, kernel); //zzzzz Cv2.ImShow("bianjie", minimacell); //zzzzz Cv2.WaitKey(0); Cv2.BitwiseNot(minimacell, minima); Size bianjieSize = minima.Size(); Mat Temp = Mat.Zeros(bianjieSize.Height + 2, bianjieSize.Width + 2, minimacell.Type());//延展图像 minima.CopyTo(Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1))); Cv2.FloodFill(Temp, new OpenCvSharp.Point(0, 0), new Scalar(255)); Mat cutImg = new Mat(); Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)).CopyTo(cutImg); Cv2.BitwiseNot(cutImg, cutImg); minima = minima | cutImg; diam = 9; kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(diam, diam), new OpenCvSharp.Point(-1, -1)); Cv2.MorphologyEx(minima, minima, MorphTypes.Open, kernel); //zzzzz Cv2.ImShow("neibu", minima);//kkkkk //zzzzz Cv2.WaitKey(0);//kkkkk return minima; } Mat smoothim(Mat im, string method, string prmflg, In4smoothim prm) { //diameter of filter int iPrmD = 13; Mat rst = new Mat(); Cv2.ConvertScaleAbs(dircohenh(im, iPrmD, prm.h, prm.iInterpolationMethod), rst); return rst; } Mat dircohenh(Mat im, int iPrmD, double[] adPrmH, int iInterpolationMethod) { int[] dim = new int[3] { im.Rows, im.Cols, 1 }; if (3 == im.Dims) { dim[2] = im.Height; } //number of elements to remove before one takes the Olympic average. Set to //1-->3 int numremele = 2; int stepxy = 30; int numdeghere = (180 - stepxy) / stepxy + 1; int[] deghere = new int[numdeghere]; deghere[0] = 0; for (int i = 1; i < numdeghere; i++) { deghere[i] = deghere[i - 1] + stepxy; } double[,] deg2D = new double[numdeghere, 2]; for (int i = 1; i < numdeghere; i++) { deg2D[i, 0] = (double)(deghere[i]); deg2D[i, 1] = 90; } double[,] deg; deg = deg2D; if (1 != dim[2]) { double[,] deg3D = new double[numdeghere + 1, 2]; for (int i = 1; i < numdeghere; i++) { deg3D[i, 0] = deg2D[i, 0]; deg3D[i, 1] = deg2D[i, 1]; } deg3D[numdeghere, 0] = 0; deg3D[numdeghere, 1] = 0; deg = deg3D; } //the half filter size int p = iPrmD / 2; //make filter MyFilter[] c = makefilter(deg, p); //number of directions int numdir = c.Length; //inisization Mat filtim = new Mat(im.Rows, im.Cols, MatType.CV_32F, 0.0); //zzzzz //201118 for Acceleration Mat imRs = new Mat(); Mat imRs = null; float[] afImRs = null; int iProportion = 5; if (1 == iInterpolationMethod) { imRs = new Mat();//201118 for Acceleration Mat imFt = new Mat(); im.ConvertTo(imFt, MatType.CV_32F); Cv2.Resize(imFt, imRs, new Size(imFt.Cols * iProportion, imFt.Rows * iProportion), 0, 0, InterpolationFlags.Cubic); //afImRs = new float[imRs.Rows, imRs.Cols]; afImRs = new float[imRs.Rows * imRs.Cols]; Marshal.Copy(imRs.Data, afImRs, 0, imRs.Rows * imRs.Cols); /* for (int i = 0; i < imRs.Rows; i++) { for (int j = 0; j < imRs.Cols; j++) { afImRs[i, j] = imRs.At(i, j); } */ imRs = null; } for (int i = 0; i < numdir; i++) { //coordinates of points in this direction after rotation of filter MyFilter chere = c[i]; //filter image for max value //zzzzz OUTmaxfilt3 fltrst; if (1 == iInterpolationMethod) { //201118 for Acceleration fltrst = maxfilt3ByCubicSpline(im, chere, numremele/*, dim*/, imRs, iProportion); fltrst = maxfilt3ByCubicSpline(im, chere, numremele/*, dim*/, afImRs, iProportion); } else if (2 == iInterpolationMethod) { fltrst = maxfilt3ByBilinear(im, chere, numremele/*, dim*/); } else { fltrst = maxfilt3ByNearest(im, chere, numremele/*, dim*/); } //structural filtering //filtim = max(filtim,(sumim - sum(maxim,4))/ (numpoints-numremele)); int[] point = new int[2]; for (point[0] = 0; point[0] < filtim.Rows; point[0]++) { for (point[1] = 0; point[1] < filtim.Cols; point[1]++) { float fTemp = filtim.At(point[0], point[1]); /*201118 for Acceleration fTemp = Math.Max(fTemp, (fltrst.sumim[point[0], point[1]] - (fltrst.maxim[point[0], point[1]]).Sum()) / (fltrst.numpoints - numremele) ); */ //(fltrst.minim[point[0], point[1]]).Sum() fTemp = fTemp = Math.Max(fTemp, (fltrst.minim[point[0]][point[1]].Take(fltrst.numpoints - numremele)).Sum() / (fltrst.numpoints - numremele)); filtim.Set(point, fTemp); } } } return filtim; } OUTmaxfilt3 maxfilt3ByNearest(Mat im, MyFilter chere, int numremele/*, int[] dim*/) { /////Mat imRs = new Mat(); /////im.ConvertTo(imRs, MatType.CV_32F); int BigRows = im.Rows; int BigCols = im.Cols; OUTmaxfilt3 rst = new OUTmaxfilt3(); rst.sumim = new float[im.Rows, im.Cols]; rst.maxim = new List[im.Rows, im.Cols]; for (int i = 0; i < im.Rows; i++) { for (int j = 0; j < im.Cols; j++) { (rst.sumim)[i, j] = 0; List lisTmp = new List(); for (int k = 0; k < numremele; k++) { lisTmp.Add(0); } (rst.maxim)[i, j] = lisTmp; } } rst.numpoints = chere.x.Length; for (int i = 0; i < rst.numpoints; i++) { double xhere; double yhere; int[] point = new int[2]; for (point[0] = 0; point[0] < im.Rows; point[0]++) { for (point[1] = 0; point[1] < im.Cols; point[1]++) { xhere = (point[0] + (chere.x)[i]); yhere = (point[1] + (chere.y)[i]); int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1); int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1); float fTemp = im.At(iX, iY); (rst.sumim)[point[0], point[1]] += fTemp; (rst.maxim)[point[0], point[1]].Add(fTemp); (rst.maxim)[point[0], point[1]].Sort(); (rst.maxim)[point[0], point[1]].RemoveAt(0); (rst.maxim)[point[0], point[1]].Reverse(); } } } return rst; } OUTmaxfilt3 maxfilt3ByBilinear(Mat im, MyFilter chere, int numremele/*, int[] dim*/) { /////Mat imRs = new Mat(); /////im.ConvertTo(imRs, MatType.CV_32F); int BigRows = im.Rows; int BigCols = im.Cols; OUTmaxfilt3 rst = new OUTmaxfilt3(); rst.sumim = new float[im.Rows, im.Cols]; rst.maxim = new List[im.Rows, im.Cols]; for (int i = 0; i < im.Rows; i++) { for (int j = 0; j < im.Cols; j++) { (rst.sumim)[i, j] = 0; List lisTmp = new List(); for (int k = 0; k < numremele; k++) { lisTmp.Add(0); } (rst.maxim)[i, j] = lisTmp; } } rst.numpoints = chere.x.Length; for (int i = 0; i < rst.numpoints; i++) { double xhere; double yhere; int[] point = new int[2]; for (point[0] = 0; point[0] < im.Rows; point[0]++) { for (point[1] = 0; point[1] < im.Cols; point[1]++) { xhere = point[0] + (chere.x)[i]; yhere = point[1] + (chere.y)[i]; int iXS = Math.Min(Math.Max((int)(xhere), 0), BigRows - 1); int iYS = Math.Min(Math.Max((int)(yhere), 0), BigCols - 1); int iXB = Math.Min(Math.Max((int)(xhere + 1.0), 0), BigRows - 1); int iYB = Math.Min(Math.Max((int)(yhere + 1.0), 0), BigCols - 1); double dWXB = Math.Min(Math.Max((xhere - (double)iXS), 0.0), 1.0); double dWXS = 1.0 - dWXB; double dWYB = Math.Min(Math.Max((yhere - (double)iYS), 0.0), 1.0); double dWYS = 1.0 - dWYB; double dTempA = im.At(iXS, iYS); double dTempB = im.At(iXS, iYB); double dTempC = im.At(iXB, iYS); double dTempD = im.At(iXB, iYB); double dTempAB = dTempA * dWYS + dTempB * dWYB; double dTempCD = dTempC * dWYS + dTempD * dWYB; float fTemp = (float)(dTempAB * dWXS + dTempCD * dWXB); (rst.sumim)[point[0], point[1]] += fTemp; (rst.maxim)[point[0], point[1]].Add(fTemp); (rst.maxim)[point[0], point[1]].Sort(); (rst.maxim)[point[0], point[1]].RemoveAt(0); (rst.maxim)[point[0], point[1]].Reverse(); } } } return rst; } //201118 for Acceleration OUTmaxfilt3 maxfilt3ByCubicSpline(Mat im, MyFilter chere, int numremele/*, int[] dim*/, Mat imRs, int iProportion) OUTmaxfilt3 maxfilt3ByCubicSpline(Mat im, MyFilter chere, int numremele, float[] afImRs, int iProportion) { /////Mat imFt = new Mat(); /////Mat imRs = new Mat(); /////im.ConvertTo(imFt, MatType.CV_32F); /////int iProportion = 5; /////Cv2.Resize(imFt, imRs, new Size(imFt.Cols * iProportion, imFt.Rows * iProportion), 0, 0, InterpolationFlags.Cubic); //201118 for Acceleration int BigRows = imRs.Rows; //201118 for Acceleration int BigCols = imRs.Cols; int BigRows = im.Rows * iProportion; int BigCols = im.Cols * iProportion; /* double[,] x = new double[dim[0], dim[1]]; double[,] y = new double[dim[0], dim[1]]; for (int i = 0; i < dim[0]; i++) { for (int j = 0; j < dim[1]; j++) { x[i, j] = (double)i; y[i, j] = (double)j; } } */ OUTmaxfilt3 rst = new OUTmaxfilt3(); //rst.maxim = new Mat[numremele]; //201118 for Acceleration rst.sumim = new float[im.Rows, im.Cols]; //201118 for Acceleration rst.maxim = new List[im.Rows, im.Cols]; rst.numpoints = chere.x.Length; rst.minim = new float[im.Rows][][]; for (int i = 0; i < im.Rows; i++) { rst.minim[i] = new float[im.Cols][]; for (int j = 0; j < im.Cols; j++) { rst.minim[i][j] = new float[rst.numpoints]; //201118 for Acceleration (rst.sumim)[i, j] = 0; //201118 for Acceleration List lisTmp = new List(); //201118 for Acceleration for (int k = 0; k < numremele; k++) //201118 for Acceleration { //201118 for Acceleration lisTmp.Add(0); //201118 for Acceleration } //201118 for Acceleration (rst.maxim)[i, j] = lisTmp; //201118 for Acceleration List lisTmpMin = new List(); //201118 for Acceleration (rst.minim)[i, j] = lisTmpMin; } } //Mat imhere = new Mat(imFt.Rows, imFt.Cols, MatType.CV_32F, 0.0); /* 201118 for Acceleration for (int i = 0; i < rst.numpoints; i++) { //the coordinate where we want to find the values //NB!!!!!!!!! //Must not do this for z direction, then it goes wrong. //Do NOOOOOT replacestr any Inf or NaN by image values, then the filter //does not work anymore!!!!!! //xhere(xhere < h(1)) = h(1);xhere(xhere > dim(1)*h(1)) = dim(1)*h(1); //yhere(yhere < h(1)) = h(1);yhere(yhere > dim(2)*h(1)) = dim(2)*h(2); //double[,] xhere = new double[dim[0], dim[1]]; //double[,] yhere = new double[dim[0], dim[1]]; double xhere; double yhere; int[] point = new int[2]; for (point[0] = 0; point[0] < im.Rows; point[0]++) { for (point[1] = 0; point[1] < im.Cols; point[1]++) { //xhere[i, j] = Math.Min(Math.Max(x[i, j]+(chere.x)[t],1),dim[0]); //yhere[i, j] = Math.Min(Math.Max(y[i, j]+(chere.y)[t],1),dim[1]); xhere = (point[0] + (chere.x)[i]) * iProportion; yhere = (point[1] + (chere.y)[i]) * iProportion; int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1); int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1); float fTemp = imRs.At(iX, iY); //imhere.Set(point, fTemp); (rst.sumim)[point[0], point[1]] += fTemp; (rst.maxim)[point[0], point[1]].Add(fTemp); (rst.maxim)[point[0], point[1]].Sort(); (rst.maxim)[point[0], point[1]].RemoveAt(0); (rst.maxim)[point[0], point[1]].Reverse(); } } } */ for (int ir = 0; ir < im.Rows; ir++) { for (int ic = 0; ic < im.Cols; ic++) { double xhere; double yhere; for (int ip = 0; ip < rst.numpoints; ip++) { xhere = (ir + (chere.x)[ip]) * iProportion; yhere = (ic + (chere.y)[ip]) * iProportion; int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1); int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1); //201118 for Acceleration float fTemp = imRs.At(iX, iY); float fTemp = afImRs[iX * BigCols + iY]; //201118 for Acceleration (rst.sumim)[ir, ic] += fTemp; //201118 for Acceleration (rst.maxim)[ir, ic].Add(fTemp); (rst.minim)[ir][ic][ip] = fTemp; } //201118 for Acceleration (rst.maxim)[ir, ic].Sort((x, y) => -x.CompareTo(y)); //201118 for Acceleration (rst.maxim)[ir, ic].RemoveRange(numremele, rst.numpoints - numremele); Array.Sort((rst.minim)[ir][ic]); //201118 for Acceleration (rst.minim)[ir, ic].Sort(); //201118 for Acceleration (rst.minim)[ir, ic].RemoveRange(rst.numpoints - numremele,numremele); } } return rst; } MyFilter[] makefilter(double[,] deg, int p) { int iNum = deg.GetLength(0); MyFilter[] c = new MyFilter[iNum]; //r = linspace(-p,p,7); int iArrLength = 7; double[] r = new double[iArrLength]; double dStep = p * 2.0 / (iArrLength - 1.0); for (int i = 0; i < 7; i++) { r[i] = -1.0 * p + i * dStep; } /* for i = 1 : size(deg,1) % the degrees theta = deg(i,1); phi = deg(i,2); % the positions c(i).x = r*sind(phi)*cosd(theta); c(i).y = r*sind(phi)*sind(theta); c(i).z = r*cosd(phi); end; */ for (int i = 0; i < iNum; i++) { double theta = deg[i, 0]; double phi = deg[i, 1]; c[i] = new MyFilter(); c[i].x = new double[iArrLength]; c[i].y = new double[iArrLength]; c[i].z = new double[iArrLength]; for (int j = 0; j < iArrLength; j++) { (c[i].x)[j] = r[j] * Math.Sin(phi) * Math.Cos(theta); ; (c[i].y)[j] = r[j] * Math.Sin(phi) * Math.Sin(theta); ; (c[i].z)[j] = r[j] * Math.Cos(phi); } } return c; } public Mat ProFroStandardImage(Mat GryImg, int iConnect, Color phaseColor) { //Mat GryImg = new Mat(); ////转为为灰度? //if (3 == OrgImg.Channels()) //{ // Cv2.CvtColor(OrgImg, GryImg, ColorConversionCodes.RGB2GRAY); //} //else //{ // if (1 == OrgImg.Channels()) // { // GryImg = OrgImg.Clone(); // } // else // { // return null; // } //} Mat CrystalImg = new Mat(); Mat BoundaryImg = new Mat(); Mat mat_mean = new Mat(), mat_stddev = new Mat(); double m, s, d = 0.5; Cv2.MeanStdDev(GryImg, mat_mean, mat_stddev); m = mat_mean.At(0, 0); s = mat_stddev.At(0, 0); //Cv2.Threshold(GryImg, CrystalImg, (int)Math.Min(m+d*s,230), 255, ThresholdTypes.Binary); //Cv2.Threshold(GryImg, CrystalImg, 0, 1, ThresholdTypes.Otsu); Cv2.Threshold(GryImg, CrystalImg, m, 255, ThresholdTypes.Binary); //Cv2.ImShow("src", CrystalImg);//kkkkk //Cv2.WaitKey(0);//kkkkk int diam = 3;//mmmmm Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(diam, diam), new OpenCvSharp.Point(-1, -1)); //Cv2.Erode(CrystalImg, CrystalImg, kernel); Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Open, kernel); Cv2.BitwiseNot(CrystalImg, BoundaryImg); //kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(diam, diam), new Point(-1, -1)); //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Open, kernel); //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Close, kernel); //Cv2.Dilate(BoundaryImg, BoundaryImg, kernel); Class12 TCAlgo = new Class12(); TCAlgo.ImgThin(BoundaryImg); //string filename = "D:\\temp.jpg"; //Cv2.ImWrite(filename, BoundaryImg); if (1 == iConnect) { TCAlgo.ConnectionBoundary(BoundaryImg, 108); } //Cv2.ImShow("wai", BoundaryImg);//kkkkk //Cv2.WaitKey(0);//kkkkk //Cv2.BitwiseNot(BoundaryImg, CrystalImg); //diam = 9; //kernel = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(diam, diam), new Point(-1, -1)); //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Close, kernel); //Cv2.Erode(CrystalImg, CrystalImg, kernel); //Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Open, kernel); //Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Close, kernel); //Cv2.ImShow("nei", CrystalImg);//kkkkk //Cv2.WaitKey(0);//kkkkk /* Mat watermark = new Mat(CrystalImg.Size(), MatType.CV_32S); Point[][] contour; HierarchyIndex[] hier; Cv2.FindContours(CrystalImg, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null); for (int i = 0; i < hier.Length; i++) { Cv2.DrawContours(watermark, contour, i, Scalar.All(i + 1), 1, LineTypes.Link8, hier); } Cv2.Watershed(OrgImg, watermark); BoundaryImg = new Mat(watermark.Size(), MatType.CV_8UC3); //ttttt Cv2.DrawContours(rtn.wat, contour, -1, Scalar.Red); */ /* Mat NewWat = new Mat(); Cv2.BitwiseNot(CrystalImg, NewWat); Cv2.ImShow("bian", NewWat);//kkkkk Cv2.WaitKey(0);//kkkkk ImgThin(NewWat); int Rows = NewWat.Rows; int Cols = NewWat.Cols; */ int[] point = new int[2]; Vec4b redcol; if (phaseColor != null) { redcol = new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255); } else redcol = new Vec4b(0, 0, 255/*255*/, 255); Mat WAT = new Mat(BoundaryImg.Size(), MatType.CV_8UC4); for (point[0] = 0; point[0] < WAT.Rows; point[0]++) { for (point[1] = 0; point[1] < WAT.Cols; point[1]++) { if (0 < BoundaryImg.At(point[0], point[1])) { WAT.Set(point, redcol); } } } return WAT; } } }