opencv kmeans (C++)

kmeans

函数原型

double cv::kmeans(
    InputArray  data,
    int     K,
    InputOutputArray    bestLabels,
    TermCriteria    criteria,
    int     attempts,
    int     flags,
    OutputArray     centers = noArray()
)

参数说明

  • Parametersdata待聚类的数据集,数据集的每一个样本是一个N维的点,点坐标都是float型的,例如:有m个样本,每个样本有n个维度,那data的格式就为cv::Mat dataSet(m,n,CV_32F)K聚类数,即要把数据集聚成k类.bestLabels存储data中每一个样本的标签,数据类型为int型criteriaopencv中迭代算法的终止条件,例如迭代的次数限制,或者迭代的精度达到要求时,算法迭代终止attempts使用不同的初始聚类中心执行算法的次数flagscv::KmeansFlags见下表,选择聚类中心的初始化方式centersOutput matrix of the cluster centers, one row per each cluster center.

  • cv::KmeansFlags

KMEANS_RANDOM_CENTERS Python: cv.KMEANS_RANDOM_CENTERSSelect random initial centers in each attempt.KMEANS_PP_CENTERS Python: cv.KMEANS_PP_CENTERSUse kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].KMEANS_USE_INITIAL_LABELS Python: cv.KMEANS_USE_INITIAL_LABELSDuring the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of KMEANS_*_CENTERS flag to specify the exact method.

示例

读取一张图片,把图片中每一个像素点的RGB值作为特征进行聚类(颜色量化),聚类数目根据需要进行调整。

#include "opencv.hpp"

int kmeansDemo(cv::Mat &srcImage, cv::Mat &dst, int clusterCount)
{
    if (srcImage.empty())
        return -1;
    if (clusterCount  0)
        return -1;

    int width = srcImage.cols;
    int height = srcImage.rows;

    int sampleCount = width * height;
    cv::Mat labels;
    cv::Mat centers;

    cv::Mat sampleData = srcImage.reshape(3, sampleCount);
    cv::Mat data;
    sampleData.convertTo(data, CV_32F);

    cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 5, 0.1);
    cv::kmeans(data, clusterCount, labels, criteria, clusterCount, cv::KMEANS_PP_CENTERS, centers);

    std::vector<cv::Scalar> colorMaps;
    uchar b, g, r;;

    for (int i = 0; i < centers.rows; i++)
    {
        b = (uchar)centers.at<float>(i, 0);
        g = (uchar)centers.at<float>(i, 1);
        r = (uchar)centers.at<float>(i, 2);
        colorMaps.push_back(cv::Scalar(b, g, r));
    }

    int index = 0;
    dst = cv::Mat::zeros(srcImage.size(), srcImage.type());
    uchar *ptr=NULL;
    int *label = NULL;
    for (int row = 0; row < height; row++) {
        ptr = dst.ptr<uchar>(row);
        for (int col = 0; col < width; col++) {
            index = row * width + col;
            label = labels.ptr<int>(index);
            *(ptr + col * 3) = colorMaps[*label][0];
            *(ptr + col * 3 + 1) = colorMaps[*label][1];
            *(ptr + col * 3 + 2) = colorMaps[*label][2];
        }
    }

    return 0;
}

int main()
{
    int clusterCount = 8;
    std::string path = "K:\\deepImage\\fruit.jpg";
    cv::Mat srcImage = cv::imread(path);
    cv::imshow("srcImage", srcImage);
    cv::Mat dst;

    kmeansDemo(srcImage,dst,clusterCount);

    std::string txt = "clusters:" + std::to_string(clusterCount);
    cv::putText(dst, txt, cv::Point(5, 35), 0, 1, cv::Scalar(0, 255, 250), 2);
    cv::imshow("result", dst);
    cv::waitKey(0);
    return 0;
}
  • 效果

opencv kmeans (C++)

opencv kmeans (C++)

opencv kmeans (C++)

Original: https://blog.csdn.net/qq_40622955/article/details/122853991
Author: 1037号森林里一段干木头
Title: opencv kmeans (C++)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/703407/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球