C# C中K均值后的质心簇颜色

C# C中K均值后的质心簇颜色,c#,k-means,opencvsharp,C#,K Means,Opencvsharp,我以这种方式使用了集成在OpencvSharp中的Kmeans函数: Cv2.Kmeans( data: samples, k: clustersCount, bestLabels: bestLabels, criteria: new TermCrit

我以这种方式使用了集成在OpencvSharp中的Kmeans函数:

                    Cv2.Kmeans(
                    data: samples,
                    k: clustersCount,
                    bestLabels: bestLabels,
                    criteria:
                        new TermCriteria(type: CriteriaType.Eps | 
                     CriteriaType.MaxIter, maxCount: 10, epsilon: 1.0),
                    attempts: 3, flags: KMeansFlags.PpCenters, centers: centers);

                var clusteredImage = new Mat(preprocessedImage.Rows, preprocessedImage.Cols, preprocessedImage.Type());
                for (var size = 0; size < preprocessedImage.Cols * preprocessedImage.Rows; size++)
                {
                    var clusterIndex = bestLabels.At<int>(0, size);
                    var newPixel = new Vec3b
                    {
                        Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B
                        Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G
                        Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R
                    };
                    clusteredImage.Set(size / preprocessedImage.Cols, size % preprocessedImage.Cols, newPixel);
                }

现在我需要获得每个中心的BGR值……我如何获得它?

通过一些细节和修改提取聚集图像的整个过程:

    /// <summary>
    /// Color Quantization using K-Means Clustering in OpenCVSharp.
    /// The process of Color Quantization is used for reducing the number of colors in an image.
    /// </summary>
    /// <param name="input">Input image.</param>
    /// <param name="output">Output image applying the number of colors defined for required clusters.</param>
    /// <param name="k">Number of clusters required.</param>
    public static void Kmeans(Mat input, Mat output, int k)
    {
        using (Mat points = new Mat())
        {
            using (Mat labels = new Mat())
            {
                using (Mat centers = new Mat())
                {
                    int width = input.Cols;
                    int height = input.Rows;

                    points.Create(width * height, 1, MatType.CV_32FC3);
                    centers.Create(k, 1, points.Type());
                    output.Create(height, width, input.Type());

                    // Input Image Data
                    int i = 0;
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++, i++)
                        {
                            Vec3f vec3f = new Vec3f
                            {
                                Item0 = input.At<Vec3b>(y, x).Item0,
                                Item1 = input.At<Vec3b>(y, x).Item1,
                                Item2 = input.At<Vec3b>(y, x).Item2
                            };

                            points.Set<Vec3f>(i, vec3f);
                        }
                    }

                    // Criteria:
                    // – Stop the algorithm iteration if specified accuracy, epsilon, is reached.
                    // – Stop the algorithm after the specified number of iterations, MaxIter.
                    var criteria = new TermCriteria(type: CriteriaType.Eps | CriteriaType.MaxIter, maxCount: 10, epsilon: 1.0);

                    // Finds centers of clusters and groups input samples around the clusters.
                    Cv2.Kmeans(data: points, k: k, bestLabels: labels, criteria: criteria, attempts: 3, flags: KMeansFlags.PpCenters, centers: centers);

                    // Output Image Data
                    i = 0;
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++, i++)
                        {
                            int index = labels.Get<int>(i);

                            Vec3b vec3b = new Vec3b();

                            int firstComponent = Convert.ToInt32(Math.Round(centers.At<Vec3f>(index).Item0));
                            firstComponent = firstComponent > 255 ? 255 : firstComponent < 0 ? 0 : firstComponent;
                            vec3b.Item0 = Convert.ToByte(firstComponent);

                            int secondComponent = Convert.ToInt32(Math.Round(centers.At<Vec3f>(index).Item1));
                            secondComponent = secondComponent > 255 ? 255 : secondComponent < 0 ? 0 : secondComponent;
                            vec3b.Item1 = Convert.ToByte(secondComponent);

                            int thirdComponent = Convert.ToInt32(Math.Round(centers.At<Vec3f>(index).Item2));
                            thirdComponent = thirdComponent > 255 ? 255 : thirdComponent < 0 ? 0 : thirdComponent;
                            vec3b.Item2 = Convert.ToByte(thirdComponent);

                            output.Set<Vec3b>(y, x, vec3b);
                        }
                    }
                }
            }
        }
    }