【问题标题】:Acces to centroid cluster color after K-means in C#在 C# 中的 K-means 之后访问质心簇颜色
【发布时间】:2019-10-03 15:03:47
【问题描述】:

我用过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值....如何获取?

【问题讨论】:

    标签: c# k-means opencvsharp


    【解决方案1】:

    提取“聚类图像”(https://kimcblog.com/2017/12/03/c-opencv-kmeans/) 的整个过程以及一些细节和修改:

        /// <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);
                            }
                        }
                    }
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 2016-05-05
      • 2019-05-14
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 2016-12-18
      • 2018-04-06
      相关资源
      最近更新 更多