static void Main(string[] args) { //! Create directories for output images if (!Directory.Exists(Settings.Images.Output)) { Directory.CreateDirectory(Settings.Images.Output); } //! create list of images var listOfImages = Directory.GetFiles(Settings.Images.Source, "*.jpg") .Where(x => x.Contains("940")) .Where(x => x.Contains("_l_")) // .Take (6) // take one palm to test .ToList(); //! variables for ROI double radius, a, xx, yy, predictX, predictY, angle; Point centerOfPalm; Point2f centerOfImage; Rect rect; //! variables for extracting file parameters PalmModel[] Palms = new PalmModel[listOfImages.Count]; //! matherials Mat sourceHandle, thresholdHandle, roiHandle, skel, rotatedSource, eroded, thr, matrix = new Mat(); Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, Settings.ElementSize); Mat[] RGB; for (int i = 0; i != listOfImages.Count; i++) { Palms[i] = new PalmModel(); Palms[i].Filename = listOfImages[i].Remove(0, listOfImages[i].LastIndexOf('/') + 1).Replace(".jpg", ""); Palms[i].Owner = Palms[i].Filename.Substring(0, Palms[i].Filename.IndexOf('_')); Palms[i].Id = Palms[i].Filename.Substring(Palms[i].Filename.LastIndexOf('_') + 2); Palms[i].Type = (Palms[i].Filename.IndexOf('r') == -1 ? 'l' : 'r'); Palms[i].Directory = $"{Settings.Images.Output}{Palms[i].Type}/{Palms[i].Owner}"; Palms[i].Path = $"{Settings.Images.Source}/{Palms[i].Filename}.jpg"; if (Directory.Exists(Palms[i].Directory) && Directory.GetFiles(Palms[i].Directory).Length > 0) { Directory.Delete(Palms[i].Directory, true); // recursive } Directory.CreateDirectory(Palms[i].Directory); } Console.WriteLine($"[{DateTime.Now}] Transform started"); var workerTime = new Stopwatch(); workerTime.Start(); for (int i = 0; i != listOfImages.Count; i++) { if (i % 10 == 0) { Console.WriteLine($"{i}.{listOfImages.Count}"); } // Read sample image sourceHandle = Cv2.ImRead(Palms[i].Path, ImreadModes.AnyColor); // Get center of image centerOfImage = new Point2f(sourceHandle.Width / 2, sourceHandle.Height / 2); // Start loop by rotations for (int j = 0; j != 180; j++) { // change rotation angle angle = j * 2; rotatedSource = new Mat(); // get and apply image rotation matrix by angle matrix = Cv2.GetRotationMatrix2D(centerOfImage, angle, 1.0); Cv2.WarpAffine(sourceHandle, rotatedSource, matrix, new Size(sourceHandle.Width, sourceHandle.Height)); // apply threshold thresholdHandle = rotatedSource.Threshold(0, 255, ThresholdTypes.Otsu); /*// apply transform distance and convert to cv_8u * thresholdHandle.DistanceTransform (DistanceTypes.L2, DistanceMaskSize.Precise); * thresholdHandle.ConvertTo (thresholdHandle, MatType.CV_8U); * * // get center of palm * centerOfPalm = GetHandCenter (thresholdHandle, out radius);*/ double radius1; Cv2.DistanceTransform(thresholdHandle, matrix, DistanceTypes.L2, DistanceMaskSize.Mask5); matrix.ImWrite($"{Palms[i].Directory}/002_distance-transform.jpg"); int[] maxIdx = new int[2]; int[] minIdx = new int[2]; Cv2.MinMaxIdx(matrix, out radius1, out radius, minIdx, maxIdx, thresholdHandle); centerOfPalm = new OpenCvSharp.Point(maxIdx[1], maxIdx[0]); // calculate ROI a = (2 * radius) / Math.Sqrt(2); xx = centerOfPalm.X - radius * Math.Cos(45 * Math.PI / 180); yy = centerOfPalm.Y - radius * Math.Sin(45 * Math.PI / 180); if (xx < 0) { a += xx; // 200 + -2 -> 200 - 2 = 198 xx = 0; } if (yy < 0) { a += yy; // 120 + -10 -> 120 - 10 = 110 yy = 0; } predictX = xx + a; predictY = yy + a; if (predictX > rotatedSource.Width) // if more { xx -= predictX - rotatedSource.Width; // (590 - 580) = 10 } if (predictY > rotatedSource.Height) { yy -= predictY - rotatedSource.Height; // 800 - 640 = 160 } /* * rect = new Rect(new Point(xx + 20, yy + 20), new Size(a, a)); * rect = new Rect(new Point(xx - 20, yy - 20), new Size(a, a)); * rect = new Rect(new Point(xx - 20, yy + 20), new Size(a, a)); * rect = new Rect(new Point(xx + 20, yy - 20), new Size(a, a)); */ rect = new Rect(new Point(xx, yy), new Size(a, a)); roiHandle = new Mat(rotatedSource, rect) .Resize(Const.ResizeValue); //! apply filters Cv2.MedianBlur(roiHandle, roiHandle, 5); // Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY); Cv2.FastNlMeansDenoising(roiHandle, roiHandle); Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.GRAY2BGR); //! Equalize hist Cv2.MorphologyEx(roiHandle, roiHandle, MorphTypes.Open, element); Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2YUV); RGB = Cv2.Split(roiHandle); RGB[0] = RGB[0].EqualizeHist(); RGB[1] = RGB[1].EqualizeHist(); RGB[2] = RGB[2].EqualizeHist(); Cv2.Merge(RGB, roiHandle); Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.YUV2BGR); //! Invert image Cv2.BitwiseNot(roiHandle, roiHandle); //! Erode image Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY); Cv2.Erode(roiHandle, roiHandle, element); //! Skeletonize skel = new Mat(roiHandle.Size(), MatType.CV_8UC1, Const.ZeroScalar); rotatedSource = new Mat(); eroded = new Mat(); thr = new Mat(); do { Cv2.MorphologyEx(roiHandle, eroded, MorphTypes.Erode, element); Cv2.MorphologyEx(eroded, rotatedSource, MorphTypes.Dilate, element); Cv2.Subtract(roiHandle, rotatedSource, rotatedSource); Cv2.BitwiseOr(skel, rotatedSource, skel); eroded.CopyTo(roiHandle); } while (Cv2.CountNonZero(roiHandle) != 0); //! Threshold skeletonized image thr = skel.Threshold(0, 255, ThresholdTypes.Binary); //! Remove contours thr.Line(Const.Zero, new Point(0, thr.Height), Scalar.Black, 2); // rm left contour thr.Line(Const.Zero, new Point(thr.Width, 0), Scalar.Black, 2); // rm top contour thr.Line(new Point(thr.Width, thr.Height), new Point(thr.Width, 0), Scalar.Black, 2); // rm right contour thr.Line(new Point(thr.Width, thr.Height), new Point(0, thr.Height), Scalar.Black, 2); // rm bot contour //! Partion lines if (Const.MODE_TYPE) { Cv2.GaussianBlur(thr, thr, new Size(7, 7), sigmaX: 5); Cv2.MorphologyEx(thr, thr, MorphTypes.Gradient, element); Cv2.BitwiseNot(thr, thr); } thr.ImWrite($"{Palms[i].Directory}/{Palms[i].Id}-{angle}.jpg"); } } workerTime.Stop(); Console.WriteLine($"[{DateTime.Now}] Elapsed time: {workerTime.Elapsed}"); }
private void Form1_Load(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Image Files(*.PNG;*.JPG)|*.PNG;*.JPG|All Files(*.*)|*.*"; if (openFileDialog.ShowDialog() == DialogResult.OK) { inputImage = new Mat(openFileDialog.FileName); pictureBox1.Image = BitmapConverter.ToBitmap(inputImage); } Cv2.CvtColor(inputImage, grayscaleImage, ColorConversionCodes.BGRA2GRAY); pictureBox2.Image = BitmapConverter.ToBitmap(grayscaleImage); Cv2.Sobel(grayscaleImage, gradientXImage, MatType.CV_16S, 1, 0); Cv2.Sobel(grayscaleImage, gradientYImage, MatType.CV_16S, 0, 1); Cv2.ConvertScaleAbs(gradientXImage, gradientXImage); Cv2.ConvertScaleAbs(gradientYImage, gradientYImage); Cv2.AddWeighted(gradientXImage, 1.0, gradientYImage, 1.0, 0, gradientImage); Cv2.Canny(grayscaleImage, cannyImage, 50, 200); pictureBox3.Image = BitmapConverter.ToBitmap(cannyImage); Cv2.DistanceTransform(1 - cannyImage, distance, DistanceTypes.L2, DistanceMaskSize.Mask3); Cv2.Normalize(distance, distance, 0, 1.0, NormTypes.MinMax); pictureBox4.Image = BitmapConverter.ToBitmap(distance); Cv2.Integral(inputImage, integrateImage, MatType.CV_32F); for (int i = 0; i < filterImage.Width; i++) { for (int j = 0; j < filterImage.Height; j++) { float tets = distance.Get <float>(i, j); int size = (int)(10 * distance.Get <float>(i, j)); if (size >= 1) { int pixelsCount = ((Clamp(i + size, 0, integrateImage.Width - 1) - Clamp(i - size, 0, integrateImage.Width - 1)) * (Clamp(j + size, 0, integrateImage.Height - 1) - Clamp(j - size, 0, integrateImage.Height - 1))); var p0 = new OpenCvSharp.Point(Clamp(i - size, 0, integrateImage.Width - 1), Clamp(j - size, 0, integrateImage.Height - 1)); var p1 = new OpenCvSharp.Point(Clamp(i + size, 0, integrateImage.Width - 1), Clamp(j + size, 0, integrateImage.Height - 1)); var p2 = new OpenCvSharp.Point(Clamp(i - size, 0, integrateImage.Width - 1), Clamp(j + size, 0, integrateImage.Height - 1)); var p3 = new OpenCvSharp.Point(Clamp(i + size, 0, integrateImage.Width - 1), Clamp(j - size, 0, integrateImage.Height - 1)); filterImage.Set <Vec3b>(i, j, new Vec3b((byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item0 + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item0 - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item0 - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item0) / pixelsCount), (byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item1 + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item1 - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item1 - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item1) / pixelsCount), (byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item2 + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item2 - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item2 - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item2) / pixelsCount))); } else { filterImage.Set <Vec3b>(i, j, inputImage.Get <Vec3b>(i, j)); } } } pictureBox5.Image = BitmapConverter.ToBitmap(filterImage); }
static void Main() { Mat mat = new Mat("lenna.png"); Mat result = mat.EmptyClone(); Mat matGray = new Mat(); Cv2.CvtColor(mat, matGray, ColorConversionCodes.BGRA2GRAY); Mat edges = new Mat(); Mat gradX = new Mat(); Mat gradY = new Mat(); Mat absGradX = new Mat(); Mat absGradY = new Mat(); Cv2.Sobel(matGray, gradX, MatType.CV_16S, 1, 0); Cv2.Sobel(matGray, gradY, MatType.CV_16S, 0, 1); Cv2.ConvertScaleAbs(gradX, absGradX); Cv2.ConvertScaleAbs(gradY, absGradY); Mat grad = new Mat(); Cv2.AddWeighted(absGradX, 1.0, absGradY, 1.0, 0, grad); Mat dist = new Mat(); Cv2.Canny(matGray, edges, 50, 200); Cv2.DistanceTransform(1 - edges, dist, DistanceTypes.L2, DistanceMaskSize.Mask3); Mat normDist = new Mat(); Cv2.Normalize(dist, normDist, 0, 1.0, NormTypes.MinMax); Mat integralImage = new Mat(); Cv2.Integral(mat, integralImage, MatType.CV_32F); for (int i = 0; i < result.Width; i++) { for (int j = 0; j < result.Height; j++) { int size = (int)(10 * dist.Get <float>(i, j)); if (size >= 1) { int pixelsCount = ((Clamp(i + size, 0, integralImage.Width - 1) - Clamp(i - size, 0, integralImage.Width - 1)) * (Clamp(j + size, 0, integralImage.Height - 1) - Clamp(j - size, 0, integralImage.Height - 1))); var p0 = new Point(Clamp(i - size, 0, integralImage.Width - 1), Clamp(j - size, 0, integralImage.Height - 1)); var p1 = new Point(Clamp(i + size, 0, integralImage.Width - 1), Clamp(j + size, 0, integralImage.Height - 1)); var p2 = new Point(Clamp(i - size, 0, integralImage.Width - 1), Clamp(j + size, 0, integralImage.Height - 1)); var p3 = new Point(Clamp(i + size, 0, integralImage.Width - 1), Clamp(j - size, 0, integralImage.Height - 1)); result.Set <Vec3b>(i, j, new Vec3b( (byte)(( integralImage.Get <Vec3f>(p0.X, p0.Y).Item0 + integralImage.Get <Vec3f>(p1.X, p1.Y).Item0 - integralImage.Get <Vec3f>(p2.X, p2.Y).Item0 - integralImage.Get <Vec3f>(p3.X, p3.Y).Item0 ) / pixelsCount), (byte)(( integralImage.Get <Vec3f>(p0.X, p0.Y).Item1 + integralImage.Get <Vec3f>(p1.X, p1.Y).Item1 - integralImage.Get <Vec3f>(p2.X, p2.Y).Item1 - integralImage.Get <Vec3f>(p3.X, p3.Y).Item1 ) / pixelsCount), (byte)(( integralImage.Get <Vec3f>(p0.X, p0.Y).Item2 + integralImage.Get <Vec3f>(p1.X, p1.Y).Item2 - integralImage.Get <Vec3f>(p2.X, p2.Y).Item2 - integralImage.Get <Vec3f>(p3.X, p3.Y).Item2 ) / pixelsCount))); } else { result.Set <Vec3b>(i, j, mat.Get <Vec3b>(i, j)); } } } using (new Window("src image", mat)) using (new Window("matGray image", matGray)) using (new Window("grad image", grad)) using (new Window("edges image", edges)) using (new Window("normDist image", normDist)) using (new Window("result image", result)) { Cv2.WaitKey(); } }
private void ProcessFrame(VideoFrame frame) { if (HasTextureConflict(frame)) { if (texture != null) { Destroy(texture); } using (var p = frame.Profile) { bool linear = (QualitySettings.activeColorSpace != ColorSpace.Linear) || (p.Stream != Stream.Color && p.Stream != Stream.Infrared); texture = new Texture2D(frame.Width, frame.Height, Convert(p.Format), false, linear) { wrapMode = TextureWrapMode.Clamp, filterMode = filterMode }; } textureBinding.Invoke(texture); } texture.LoadRawTextureData(frame.Data, frame.Stride * frame.Height); //Mat mat = OpenCvSharp.Unity.TextureToMat(texture); //for (int yi = 0; yi < mat.Height; yi++) //{ // for (int xi = 0; xi < mat.Width; xi++) // { // Vec3b v = mat.At<Vec3b>(yi, xi); // float gr = 0.2126f * v[2] + 0.7152f * v[1] + 0.0722f * v[0]; // v[0] = (byte)gr; // v[1] = (byte)gr; // v[2] = (byte)gr; // mat.Set<Vec3b>(yi, xi, v); // } //} //texture = OpenCvSharp.Unity.MatToTexture(mat); //Debug.Log(texture.GetPixels32()[0]); // //Gray Scalse // //Mat mat = OpenCvSharp.Unity.TextureToMat(texture); //Mat changedMat = new Mat(); //Cv2.CvtColor(mat, changedMat, ColorConversionCodes.BGR2GRAY); //texture = OpenCvSharp.Unity.MatToTexture(changedMat); //Gray Scale Mat mat = OpenCvSharp.Unity.TextureToMat(texture); Mat gray = new Mat(); Cv2.CvtColor(mat, gray, ColorConversionCodes.BGR2GRAY); //Threshold Mat thresh = new Mat(); Mat bin_img = new Mat(); Cv2.Threshold(gray, thresh, 0, 255, ThresholdTypes.Otsu); bin_img = thresh; //morphologyEx Mat morphology = new Mat(); Cv2.MorphologyEx(bin_img, morphology, MorphTypes.Open, new InputArray(1), null, 2); //Dilate Mat dilate = new Mat(); Cv2.Dilate(morphology, dilate, new InputArray(1), null, 2, BorderTypes.Constant); //thresh.Dilate(dilate, null, 1, BorderTypes.Constant, null); //Distance Transform Mat distance_transform = new Mat(); Cv2.DistanceTransform(morphology, distance_transform, DistanceTypes.L2, DistanceMaskSize.Mask5); //sure foreground Mat sure_fg = new Mat(); Cv2.Threshold(distance_transform, sure_fg, 11, 255, ThresholdTypes.Binary); //SubStract //Mat subtract = new Mat(); //Cv2.Subtract(dilate, sure_fg, subtract); //Contours Point[][] contours; HierarchyIndex[] h_index; Cv2.FindContours(dilate, out contours, out h_index, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS, null); // // draw max area // //double max_area = 0; //int max_area_contour = -1; //for (int j = 0; j < contours.Length; j++) //{ // double area = Cv2.ContourArea(contours[j]); // if (max_area < area) // { // max_area = area; // max_area_contour = j; // } //} //int count = contours[max_area_contour].Length; //double x = 0; //double y = 0; //for (int k = 0; k < count; k++) //{ // x += contours[max_area_contour][k].X; // y += contours[max_area_contour][k].Y; //} //x /= count; //y /= count; //Cv2.Circle(mat, (int)x, (int)y, 50, new Scalar(0, 0, 255), 3, LineTypes.Link4); /// draw segment Cv2.Polylines(mat, contours, true, new Scalar(0, 0, 255), 5); texture = OpenCvSharp.Unity.MatToTexture(mat); textureBinding.Invoke(texture); texture.Apply(); //texture.Apply(); }
public static void CalculoMatrizBinariaYRelleno(Mat imagen, out Mat imagenBinaria, out Mat imagenAberturaRelleno) { imagenBinaria = new Mat(); imagenAberturaRelleno = new Mat(); imagenBinaria = 255 - imagen; Mat imagenBinariaProc = new Mat(); imagenBinaria.CopyTo(imagenBinariaProc); Mat kernelMorfologicoElipse = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3)); Mat kernelMorfologicoCruz = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(3, 3)); Cv2.Erode(imagenBinariaProc, imagenBinariaProc, kernelMorfologicoElipse, iterations: 3); Cv2.Dilate(imagenBinariaProc, imagenBinariaProc, kernelMorfologicoCruz, iterations: 2); imagenBinariaProc = 255 - imagenBinariaProc; Mat imagenTransfDistancia = new Mat(); Mat imagenTransfDistanciaBinaria = new Mat(); Cv2.DistanceTransform(imagenBinariaProc, imagenTransfDistancia, DistanceTypes.C, DistanceMaskSize.Mask5); imagenTransfDistancia.ConvertTo(imagenTransfDistancia, MatType.CV_8U); imagenTransfDistancia.CopyTo(imagenTransfDistanciaBinaria); double maxDist, minDist, rangoDist; imagenTransfDistanciaBinaria.MinMaxIdx(out minDist, out maxDist); rangoDist = maxDist - minDist; var indexadorImgDistancia = imagenTransfDistanciaBinaria.GetGenericIndexer <byte>(); for (int i = 0; i < imagenTransfDistancia.Rows; i++) { for (int j = 0; j < imagenTransfDistancia.Cols; j++) { if (indexadorImgDistancia[i, j] >= maxDist - rangoDist * 0.35 || indexadorImgDistancia[i, j] <= minDist + rangoDist * 0.15) { indexadorImgDistancia[i, j] = (byte)255; } else { indexadorImgDistancia[i, j] = (byte)0; } } } Mat marcadores = new Mat(); int numMarcadores = Cv2.ConnectedComponents(imagenTransfDistanciaBinaria, marcadores, PixelConnectivity.Connectivity8, MatType.CV_16UC1); Dictionary <int, int> cantidadMarcador = new Dictionary <int, int>(); for (int i = 0; i < marcadores.Rows; i++) { for (int j = 0; j < marcadores.Cols; j++) { int areaMarcador = 0; int m = marcadores.At <int>(i, j); cantidadMarcador.TryGetValue(m, out areaMarcador); if (areaMarcador > 0) { cantidadMarcador[m] += 1; } else { cantidadMarcador[m] = 1; } //try //{ // cantidadMarcador[m] += 1; //} //catch //{ // cantidadMarcador[m] = 1; //} } } int indiceMarcadorMax = cantidadMarcador.Select(v => new Tuple <int, int>(v.Key, v.Value)) .OrderByDescending(x => x.Item1).First().Item2; Mat fondoMarcadores = new Mat(); marcadores.CopyTo(fondoMarcadores); var indexador = fondoMarcadores.GetGenericIndexer <int>(); for (int i = 0; i < fondoMarcadores.Rows; i++) { for (int j = 0; j < fondoMarcadores.Cols; j++) { indexador[i, j] = (indexador[i, j] == indiceMarcadorMax) ? 255 : 0; } } fondoMarcadores.ConvertTo(fondoMarcadores, imagenBinaria.Type()); Mat imagenBinariaSinFondo = new Mat(); Mat imagenRellenoHuecos = new Mat(); Cv2.Subtract(imagenBinaria, fondoMarcadores, imagenBinariaSinFondo); Cv2.Add(imagenBinaria, imagenBinariaSinFondo, imagenRellenoHuecos); Mat kernelMorfologicoApertura = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3)); Cv2.MorphologyEx(imagenRellenoHuecos, imagenAberturaRelleno, MorphTypes.Open, kernelMorfologicoApertura, iterations: 2); /* liberar memoria */ imagenBinariaProc.Release(); imagenBinariaSinFondo.Release(); imagenRellenoHuecos.Release(); kernelMorfologicoElipse.Release(); kernelMorfologicoCruz.Release(); kernelMorfologicoApertura.Release(); }
static void Main(string[] args) { //Thread capturaVideoThread = new Thread(new ThreadStart(Program.CapturarVideo)); //capturaVideoThread.Start(); VideoCapture captura = new VideoCapture("D:\\Dictuc\\out1.avi"); VideoWriter salida = new VideoWriter("D:\\Dictuc\\outSegmentado.avi", FourCC.XVID, 10.0, new Size(captura.FrameWidth, captura.FrameHeight), true); Mat imagenProcesada = new Mat(); int numImg = 0; while (true) { //captura.Read(imagen); imagen = Cv2.ImRead("D:\\uvas2.jpg"); mutex.WaitOne(); imagen.CopyTo(imagenProcesada); mutex.ReleaseMutex(); Mat imagenRuidoFiltrado = FiltradoRuido(imagenProcesada); Mat imagenGrisContraste = EscalaGrisesEqualizada(imagenRuidoFiltrado); Mat imagenGrisFrecAltasProc = FrecuenciasAltasPotenciadasContraste(imagenGrisContraste); EdgeDetector edgeDetector = new EdgeDetector() { Threshold = (byte)18, SparseDistance = 3, WeightPreviousPoint = (float)2.0, WeightCurrentPoint = (float)1.0, WeightAfterPoint = (float)2.0, }; EdgeDetector edgeDetector2 = new EdgeDetector() { Threshold = (byte)20, SparseDistance = 5, WeightPreviousPoint = (float)0.5, WeightCurrentPoint = (float)1.0, WeightAfterPoint = (float)0.5, }; Mat imagenBordes = edgeDetector.EdgeImage(imagenGrisContraste); Mat imagenBordes2 = edgeDetector2.EdgeImage(imagenGrisContraste); Mat imagenBinaria, imagenAberturaRelleno; CalculoMatrizBinariaYRelleno(imagenBordes2, out imagenBinaria, out imagenAberturaRelleno); Mat mascaraInv = 255 - imagenAberturaRelleno; Mat DistSureFg = new Mat(); Mat AreasSureFg = new Mat(); Mat Unknown = new Mat(); AreasSureFg += 1; Cv2.DistanceTransform(imagenAberturaRelleno, DistSureFg, DistanceTypes.L1, DistanceMaskSize.Mask5); int numAreas = Cv2.ConnectedComponents(imagenAberturaRelleno, AreasSureFg, PixelConnectivity.Connectivity8); float[,] distValues = new float[DistSureFg.Rows, DistSureFg.Cols]; for (int i = 0; i < DistSureFg.Rows; i++) { for (int j = 0; j < DistSureFg.Cols; j++) { distValues[i, j] = DistSureFg.At <float>(i, j); } } Segment[] segments = new Segment[numAreas]; for (int i = 0; i < AreasSureFg.Rows; i++) { for (int j = 0; j < AreasSureFg.Cols; j++) { int m = AreasSureFg.At <Int32>(i, j); byte pixelSurrounding = 0; float distance = (float)0; //if (i >= 1) //{ // distance = distValues[i - 1, j]; // if (distance == 2) // { // pixelSurrounding |= Segment.PIXEL_SURROUNDED_LEFT; // } //} //if (i < AreasSureFg.Rows - 1) //{ // distance = distValues[i + 1, j]; // if (distance == 2) // { // pixelSurrounding |= Segment.PIXEL_SURROUNDED_RIGHT; // } //} //if (j >= 1) //{ // distance = distValues[i, j - 1]; // if (distance == 2) // { // pixelSurrounding |= Segment.PIXEL_SURROUNDED_DOWN; // } //} //if (j < AreasSureFg.Cols - 1) //{ // distance = distValues[i, j + 1]; // if (distance == 2) // { // pixelSurrounding |= Segment.PIXEL_SURROUNDED_UP; // } //} SegmentPixelData newPixel = new SegmentPixelData() { Distance = distValues[i, j], CoordsXY = new int[] { i, j }, Concave = 0, Indexes = new int[] { -1, -1 }, PixelsSurrounding = pixelSurrounding, SubsegmentLabel = 0, }; if (segments[m] == null) { segments[m] = new Segment() { SegmentId = m, PixelData = new List <SegmentPixelData>(), }; } else { segments[m].MaxDistance = (segments[m].MaxDistance > newPixel.Distance) ? (int)segments[m].MaxDistance : (int)newPixel.Distance; segments[m].PixelData.Add(newPixel); } } } Mat Centroides = new Mat(); imagenAberturaRelleno.CopyTo(Centroides); var indexadorCentroides = Centroides.GetGenericIndexer <byte>(); var indexadorFiguras = AreasSureFg.GetGenericIndexer <Int32>(); foreach (var s in segments.Where(s => s.Circularity <= 0.9)) { int distancia = 0; if (s.Circularity > 0.7) { distancia = 5; } else if (s.Circularity > 0.5) { distancia = 5; } else if (s.Circularity > 0.25) { distancia = 6; } else { distancia = 6; } distancia = (distancia < s.MaxDistance) ? distancia : s.MaxDistance - 1; foreach (var p in s.PixelData.Where(p => p.Distance <= distancia)) { if (imagenAberturaRelleno.At <byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0) { indexadorCentroides[p.CoordsXY[0], p.CoordsXY[1]] = 0; } } } Cv2.Subtract(imagenAberturaRelleno + 255, Centroides, Unknown); #region segmentStuff //List<int> indexConcavos = segments.Where(s => s.Circularity > 1).Select(s => s.SegmentId).ToList(); //foreach (var s in segments.Where(s => s.Circularity < 1.1 && s.Circularity > 0.9)) //{ // foreach (var p in s.PixelData/*.Where(p => p.Distance == 1)*/) // { // if (imagenAberturaRelleno.At<byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0) // { // indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255; // } // } //} //foreach (var s in segments.Where(s => s.Circularity >= 1.1)) //{ // foreach (var p in s.PixelData/*.Where(p => p.Distance == 1)*/) // { // if (imagenAberturaRelleno.At<byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0) // { // indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255; // } // } //} //foreach (var s in segments) //{ // s.SetPixelConcavity(); // s.Segmentation(); // foreach (var p in s.PixelData.Where(p => p.Distance == 1)) // { // if (p.Concave == 1) // { // indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255; // } // if (p.Concave == -1) // { // indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255; // } // } //} //foreach (var s in segments) //{ // //s.SetPixelConcavity(); // //s.Segmentation(); // foreach (var p in s.PixelData.Where(p => p.Distance == 2)) // { // indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 230; // } //} //imagenAberturaRelleno.CopyTo(SureFg); #endregion Mat colormap = new Mat(); Mat Marcadores = new Mat(); Cv2.ConnectedComponents(Centroides, Marcadores); Marcadores = Marcadores + 1; var indexador2 = Marcadores.GetGenericIndexer <Int32>(); for (int i = 0; i < Unknown.Rows; i++) { for (int j = 0; j < Unknown.Cols; j++) { if (Unknown.At <byte>(i, j) == 255) { indexador2[i, j] = 0; } } } Marcadores.CopyTo(colormap); colormap.ConvertTo(colormap, MatType.CV_8UC3); Cv2.ApplyColorMap(colormap, colormap, ColormapTypes.Rainbow); Cv2.ImWrite("D:\\Dictuc\\marcadores.png", Marcadores); //Mat img1 = new Mat(); //imagen.CopyTo(img1); Mat DistColor = new Mat(); //imagenGrisContraste = 255 - imagenGrisContraste; Cv2.CvtColor(imagenAberturaRelleno, DistColor, ColorConversionCodes.GRAY2BGR); DistColor.ConvertTo(DistColor, MatType.CV_8U); Cv2.Watershed(DistColor, Marcadores); Cv2.ImWrite("D:\\Dictuc\\watersheedIn.png", DistColor); var indexador4 = imagen.GetGenericIndexer <Vec3i>(); //for (int i = 0; i < imagen.Rows; i++) //{ // for (int j = 0; j < imagen.Cols; j++) // { // //if (Centroides.At<byte>(i, j) > 0) // // indexador4[i, j] = new Vec3i(0, 0, 255); // if (Marcadores.At<Int32>(i, j) == -1) // indexador4[i, j] = new Vec3i(255, 20, 20); // } //} for (int i = 0; i < imagen.Rows; i++) { for (int j = 0; j < imagen.Cols; j++) { //if (Centroides.At<byte>(i, j) > 0) // indexador4[i, j] = new Vec3i(0, 0, 255); if (imagenBordes.At <char>(i, j) > 0) { indexador4[i, j] = new Vec3i(255, 20, 20); } } } Mat seg = new Mat(); Marcadores.CopyTo(seg); var indexador5 = seg.GetGenericIndexer <int>(); for (int i = 0; i < Marcadores.Rows; i++) { for (int j = 0; j < Marcadores.Cols; j++) { indexador5[i, j] = (Math.Abs(indexador5[i, j]) > 1) ? 255 : 0; } } Mat kE1 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 1)); Cv2.Erode(seg, seg, kE1, iterations: 3); int thrs1 = 1500; int thrs2 = 1800; Mat edge1 = new Mat(); seg.ConvertTo(seg, MatType.CV_8U); Cv2.Canny(seg, edge1, thrs1, thrs2, apertureSize: 5); SimpleBlobDetector.Params params1 = new SimpleBlobDetector.Params() { MinThreshold = 0, MaxThreshold = 255, FilterByArea = true, MinArea = 15, FilterByCircularity = false, MinCircularity = (float)0.01, FilterByConvexity = false, MinConvexity = (float)0.1, FilterByInertia = false, MinInertiaRatio = (float)0.01, }; SimpleBlobDetector detectorBlobs = SimpleBlobDetector.Create(params1); KeyPoint[] segmentosBlob = detectorBlobs.Detect(edge1); Mat segmentosBlobMat = new Mat(1, segmentosBlob.Count(), MatType.CV_32FC1); var indexador6 = segmentosBlobMat.GetGenericIndexer <float>(); for (int i = 0; i < segmentosBlob.Count(); i++) { indexador6[0, i] = segmentosBlob[i].Size; } Mat hist = new Mat(); Rangef[] ranges = { new Rangef(0, (float)segmentosBlob.Max(x => x.Size)) }; Cv2.CalcHist(new Mat[] { segmentosBlobMat }, new int[] { 0 }, null, hist, 1, new int[] { 100 }, ranges, uniform: true, accumulate: true); float[] histAcumulado = new float[hist.Rows]; float[] histAcumuladoPorcentaje = new float[11]; histAcumulado[0] = hist.At <float>(0, 0); for (int i = 1; i < hist.Rows; i++) { histAcumulado[i] = hist.At <float>(i, 0) + histAcumulado[i - 1]; } int k = 1; for (int i = 1; i < histAcumuladoPorcentaje.Count(); i++) { for (; k < hist.Rows; k++) { float porcentajeActual = histAcumulado[k] / segmentosBlob.Count() * 100; float porcentajeAnterior = histAcumulado[k - 1] / segmentosBlob.Count() * 100; float porcentajeRequerido = (float)((i < 10) ? i * 10 : 99.3); if (porcentajeRequerido <= porcentajeActual) { float tamañoPorcentajeActual = (float)(k * (float)segmentosBlob.Max(x => x.Size) / 100.0); float tamañoPorcentajeAnterior = (float)((k - 1) * (float)segmentosBlob.Max(x => x.Size) / 100.0); float tasaVariacionTamañoPorcentaje = (tamañoPorcentajeActual - tamañoPorcentajeAnterior) / (porcentajeActual - porcentajeAnterior); histAcumuladoPorcentaje[i] = tamañoPorcentajeAnterior + tasaVariacionTamañoPorcentaje * (i * 10 - porcentajeAnterior); break; } } } for (int i = 0; i < histAcumuladoPorcentaje.Count(); i++) { Console.Write(histAcumuladoPorcentaje[i] + ","); } Console.WriteLine(""); // data1 = []; // for i in range(0, len(keypoints1)): // data1.append(keypoints1[i].size * coefTamano) // #tamano.write(str(i)+'\t'+str(keypoints1[i].size*2*0.3)+'\n') // cv2.line(im_with_keypoints1, (int(float(keypoints1[i].pt[0] - keypoints1[i].size)), int(float(keypoints1[i].pt[1]))), (int(float(keypoints1[i].pt[0] + keypoints1[i].size)), int(float(keypoints1[i].pt[1]))), (255, 0, 0), 1) // cv2.line(im_with_keypoints1, (int(float(keypoints1[i].pt[0])), int(float(keypoints1[i].pt[1] - keypoints1[i].size))), (int(float(keypoints1[i].pt[0])), int(float(keypoints1[i].pt[1] + keypoints1[i].size))), (255, 0, 0), 1) //# print(data1) //n1, bins1, patches1 = hist(data1, 200,[0, max(data1)], normed = 100, cumulative = True, bottom = True, histtype = 'stepfilled', align = 'mid', orientation = 'vertical', rwidth = 1, log = False, color = "r") // tamano = open(temp + "instancia_" + instancia + ".txt", "w") // x = np.array(bins1) // y = np.append([0], n1) // xnew = [x[1], x[21], x[36], x[45], x[53], x[60], x[69], x[78], x[88], x[97], x[200]] //ynew = [y[1], y[21], y[36], y[45], y[53], y[60], y[69], y[78], y[88], y[97], y[200]] //tamano.write('INSERT INTO [dbo].[Granulometria](Cod_Instancia,Fecha,P_10,P_20,P_30,P_40,P_50,P_60,P_70,P_80,P_90,P_100, Filename) values (') //tamano.write(instancia + ",CONVERT(datetime, '" + sys.argv[1][0:4] + "-" + sys.argv[1][4:6] + "-" + sys.argv[1][6:8] + ' ' + sys.argv[1][9:11] + ':' + sys.argv[1][11:13] + ':' + sys.argv[1][13:15] + "', 120)") //for j in range(1, len(xnew)): // #tamano.write (str(j)+'\t'+str(round(xnew[j],1))+'\t'+str(round(ynew[j]*100,2))+'\n') // tamano.write(',' + str(round(xnew[j], 1))) //tamano.write(",'" + sys.argv[1] + " - Resultado.jpg'") //tamano.write(')') //CvXImgProc.Thinning(mascaraInv, mascaraInv, ThinningTypes.ZHANGSUEN); Mat imWithKeypoints1 = new Mat(); Cv2.DrawKeypoints(imagen, segmentosBlob, imWithKeypoints1, new Scalar(0, 0, 255), DrawMatchesFlags.DrawRichKeypoints); var dataTamaños = segmentosBlob.Select(s => s.Size).ToArray(); Cv2.ImWrite("D:\\Dictuc\\output0" + numImg + ".png", imagen); Cv2.ImWrite("D:\\Dictuc\\output1" + numImg++ + ".png", imWithKeypoints1); Cv2.ImShow("Segmentado", imagen); Cv2.ImShow("GrisContraste", imagenGrisContraste); Cv2.ImShow("bordes90", imagenBordes); Cv2.ImShow("bordes50", imagenBordes2); salida.Write(imagen); //System.Threading.Thread.Sleep(10); Cv2.WaitKey(10); imagenRuidoFiltrado.Release(); imagenGrisContraste.Release(); imagenGrisFrecAltasProc.Release(); imagenBordes.Release(); imagenBinaria.Release(); imagenAberturaRelleno.Release(); } }
public override object Find() { initialize(); CircleSegment[] circles = null; Point[][] points = Cv2.FindContoursAsArray(gray, RetrievalModes.List, ContourApproximationModes.ApproxTC89L1); for (int i = 0; i < points.Length; i++) { Mat black = new Mat(gray.Rows, gray.Cols, gray.Type(), new Scalar(0)); Cv2.DrawContours(black, points, i, new Scalar(255), Cv2.FILLED); Cv2.ImShow("contour", black); //for more info https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=houghcircles circles = Cv2.HoughCircles(black, HoughMethods.Gradient, dp, minDist, cannyThreshold, param2, minRadius, maxRadius); // draw the circle detected foreach (CircleSegment element in circles) { Point center = new Point(Math.Round(element.Center.X), Math.Round(element.Center.Y)); Cv2.Circle(outputimg, center, 3, new Scalar(0, 255, 255), 1); Cv2.Circle(outputimg, center, (int)element.Radius, new Scalar(0, 0, 255), 1); } //compute distance transorm Mat dt = new Mat(); Cv2.Canny(black, canny, cannyThreshold, cannyThreshold / 2); Mat wh = new Mat(canny.Rows, canny.Cols, MatType.CV_8UC1, new Scalar(255)); Cv2.DistanceTransform(wh - canny.GreaterThan(0.0), dt, DistanceTypes.L2, DistanceMaskSize.Mask3); //Cv2.ImShow("dt", wh - canny.GreaterThan(0.0)); //Cv2.WaitKey(0); //test for semi-circle foreach (CircleSegment element in circles) { //test inlier percentage //sample the circle and check for distance to next edge uint counter = 0; uint inlier = 0; //maximal distance of inlier might depend on the size of the circle //the more close edge the lower distance transform value double maxInlierDist = element.Radius / maxInlierDistRatio; if (maxInlierDist < minInlierDist) { maxInlierDist = minInlierDist; } MatOfFloat mf = new MatOfFloat(dt); var indexer = mf.GetIndexer(); //TODO maybe parameter incrementation might depend on circle size for (float t = 0; t < 2 * Math.PI; t += 0.1f) { counter++; int cx = (int)(element.Radius * Math.Cos(t) + element.Center.X); int cy = (int)(element.Radius * Math.Sin(t) + element.Center.Y); if (cx < 0 || cy < 0 || cx > dt.Cols || cy >= dt.Rows) { continue; } if (indexer[cy, cx] < maxInlierDist) //carefor the image coordinate { inlier++; Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 255, 255)); } else { Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 0, 0)); } } Console.WriteLine("{0}% of a circle with radius {1} detected", 100 * inlier / counter, element.Radius); } } return(circles); }