public static MeanShiftClusteringResult MeanShiftAccord(Image <Bgr, Byte> image, MeanShiftClusteringAcordParams msParams) { //Image<Bgr, byte> result = new Image<Bgr, byte>(image.Size); //int pixelSize = 3; // RGB color pixel //int kernel = 3; //double sigma = 0.06; // kernel bandwidth int pixelSize = 3; // RGB color pixel int kernel = msParams.Kernel; double sigma = msParams.Sigma; // kernel bandwidth // Load a test image (shown below) Bitmap msImage = image.Bitmap; // Create converters ImageToArray imageToArray = new ImageToArray(min: -1, max: +1); ArrayToImage arrayToImage = new ArrayToImage(msImage.Width, msImage.Height, min: -1, max: +1); // Transform the image into an array of pixel values double[][] pixels; imageToArray.Convert(msImage, out pixels); // Create a MeanShift algorithm using given bandwidth // and a Gaussian density kernel as kernel function. Accord.MachineLearning.MeanShift meanShift = new Accord.MachineLearning.MeanShift(pixelSize, new GaussianKernel(kernel), sigma); // We will compute the mean-shift algorithm until the means // change less than 0.5 between two iterations of the algorithm meanShift.Tolerance = 0.05; meanShift.MaxIterations = 10; // Learn the clusters in the data var clustering = meanShift.Learn(pixels); // Use clusters to decide class labels int[] labels = clustering.Decide(pixels); int regionCount = labels.DistinctCount(); // Replace every pixel with its corresponding centroid pixels.ApplyInPlace((x, i) => meanShift.Clusters.Modes[labels[i]]); // Retrieve the resulting image in a picture box Bitmap msResult; arrayToImage.Convert(pixels, out msResult); Image <Bgr, byte> result = new Image <Bgr, byte>(msResult); //EmguCvWindowManager.Display(result, "msResult"); return(new MeanShiftClusteringResult() { Image = result, Labels = labels, RegionCount = regionCount }); }
// Universal method for dust, mist, fog // Source: http://colorimaginglab.ugr.es/pages/pdfs/ao_2015_B222/! public BaseMethodResponse RecoveringOfWeatherDegradedImagesBasedOnRGBResponseRatioConstancyMethod( Image <Bgr, Byte> image, RGBResponseRatioConstancyMethodParams _params ) { var stopwatch = new Stopwatch(); stopwatch.Start(); Image <Bgr, Byte> result = new Image <Bgr, byte>(image.Size); Image <Bgr, Byte> resultToAll = new Image <Bgr, byte>(image.Size); //Apply mean shift clustering MeanShiftClusteringAcordParams msParams = new MeanShiftClusteringAcordParams() { Kernel = _params?.MeanShiftParams?.Kernel ?? 5, Sigma = _params?.MeanShiftParams?.Sigma ?? 0.13 }; var msResult = Clustering.MeanShiftAccord(image, msParams); var labels = msResult.Labels.Distinct().ToArray(); //regions numbers //Find regions pixels coordinates var regionPixelsCoordinates = Clustering.GetRegionsPixelsCoordinates(msResult); //Loop through regions for (int region = 0; region < msResult.RegionCount; region++) { //Find min and max values for each channel var regionPixels = regionPixelsCoordinates[region].Select(coordinates => image[coordinates.X, coordinates.Y]).ToArray(); var regionBValues = regionPixels.Select(p => p.Blue).ToArray(); var regionGValues = regionPixels.Select(p => p.Green).ToArray(); var regionRValues = regionPixels.Select(p => p.Red).ToArray(); double[] minValues = new double[3] { regionBValues.Min(), regionGValues.Min(), regionRValues.Min() }; double[] maxValues = new double[3] { regionBValues.Max(), regionGValues.Max(), regionRValues.Max() }; int pixelsCountInRegion = regionPixelsCoordinates[region].Count; double B_min = minValues[0]; double G_min = minValues[1]; double R_min = minValues[2]; double B_max = maxValues[0]; double G_max = maxValues[1]; double R_max = maxValues[2]; if (_params.Imin != null) { B_min = _params.Imin.Value; G_min = _params.Imin.Value; R_min = _params.Imin.Value; } if (_params.Imax != null) { B_max = _params.Imax.Value; G_max = _params.Imax.Value; R_max = _params.Imax.Value; } //Apply formula for (int i = 0; i < pixelsCountInRegion; i++) { var pixelCoordinates = regionPixelsCoordinates[region][i]; Bgr pixel = image[pixelCoordinates.X, pixelCoordinates.Y]; double B = (pixel.Blue - B_min) * (B_max / (B_max - B_min)); double G = (pixel.Green - G_min) * (G_max / (G_max - G_min)); double R = (pixel.Red - R_min) * (R_max / (R_max - R_min)); result[pixelCoordinates.X, pixelCoordinates.Y] = new Bgr(B, G, R); } } //apply for all image //Find min and max values for each channel double[] minValues2; double[] maxValues2; Point[] minLocations2; Point[] maxLocations2; image.MinMax(out minValues2, out maxValues2, out minLocations2, out maxLocations2); double B_min2 = minValues2[0]; double G_min2 = minValues2[1]; double R_min2 = minValues2[2]; double B_max2 = maxValues2[0]; double G_max2 = maxValues2[1]; double R_max2 = maxValues2[2]; if (_params.Imin != null) { B_min2 = _params.Imin.Value; G_min2 = _params.Imin.Value; R_min2 = _params.Imin.Value; } if (_params.Imax != null) { B_max2 = _params.Imax.Value; G_max2 = _params.Imax.Value; R_max2 = _params.Imax.Value; } for (int m = 0; m < image.Rows; m++) { for (int n = 0; n < image.Cols; n++) { Bgr pixel = image[m, n]; double B = (pixel.Blue - B_min2) * (B_max2 / (B_max2 - B_min2)); double G = (pixel.Green - G_min2) * (G_max2 / (G_max2 - G_min2)); double R = (pixel.Red - R_min2) * (R_max2 / (R_max2 - R_min2)); resultToAll[m, n] = new Bgr(B, G, R); } } if (_params.ShowWindows) { EmguCvWindowManager.Display(image, "1. image"); EmguCvWindowManager.Display(msResult.Image, "2. MS"); EmguCvWindowManager.Display(resultToAll, "3. resultToAll"); EmguCvWindowManager.Display(result, "4. result"); } stopwatch.Stop(); return(new BaseMethodResponse { EnhancementResult = result, DetectionResult = new Image <Gray, byte>(image.Size), DetailedResults = new List <IInputArray> { image, msResult.Image, resultToAll, result }, ExecutionTimeMs = stopwatch.ElapsedMilliseconds }); }