记录一次c++实现图片颜色聚类的小需求

安装visual studio 2019

安装c++的IDE Visual Studio 2019安装与使用

配置opencv环境

VS配置OpenCV开发环境(c++):How & Why
windows下OpenCV的安装配置部署详细教程

代码

python实现的核心代码(这里读取的是四图层图片)

def image_process(img, o_path, p):
    # 图像二维像素转换为一维
    # 转换成3列
    data = img[:, :, :3].reshape((-1, 3))
    data = np.float32(data)

    # 定义终止条件 (type,max_iter,epsilon)
    criteria = (cv2.TERM_CRITERIA_EPS +
                cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

    # 设置初始中心的选择
    # flags = cv2.KMEANS_RANDOM_CENTERS
    flags = cv2.KMEANS_PP_CENTERS

    # K-Means聚类 聚集成4类
    compactness, labels, centers = cv2.kmeans(data, 9, None, criteria, 10, flags)

    # 图像转换回uint8二维类型
    # centers = np.uint8(centers)
	# new_colour 对中心点做了变换,可以直接使用聚类的中心点结果
    new_centers = new_colour(centers)
    # print(centers)
    # print(new_centers)
    res = new_centers[labels.flatten()]
    # res = centers[labels.flatten()]
    dst = res.reshape(img[:, :, :3].shape)
    dst = np.concatenate((dst, img[:, :, 3:]), axis=2)
    cv2.imwrite(os.path.join(o_path, p), dst)

c++

Mat colourProcess(Mat& img, int nums) {
    if (img.empty()) {
        return img;
    }

    int width = img.cols;
    int height = img.rows;
    int dims = img.channels();

    int sampleCount = width * height;
    Mat points(sampleCount, dims, CV_32F, Scalar());
    Mat labels;
    Mat centers(nums, 1, points.type());

    int index = 0;

    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            index = row * width + col;
            Vec3b bgr = img.at<Vec3b>(row, col);
            points.at<float>(index, 0) = static_cast<int>(bgr[0]);
            points.at<float>(index, 1) = static_cast<int>(bgr[1]);
            points.at<float>(index, 2) = static_cast<int>(bgr[2]);
        }
    }
    TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
    kmeans(points, nums, labels, criteria, 3, KMEANS_PP_CENTERS, centers);
    //cout << centers.at<Vec3f>(0) << endl;
    //cout << centers.rows << ' ' << centers.cols << endl;
    //cout << centers << endl;
    vector<int> vi = calNewCenters(centers, img);
    for (auto i : vi) {
        cout << colorTab[i] << endl;
    }

    Mat result = Mat::zeros(img.size(), img.type());
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            index = row * width + col;
            int label = labels.at<int>(index, 0);
            result.at<Vec3b>(row, col)[0] = colorTab[vi[label]][0];
            result.at<Vec3b>(row, col)[1] = colorTab[vi[label]][1];
            result.at<Vec3b>(row, col)[2] = colorTab[vi[label]][2];
        }
    }
    return result;
}

参考
Opencv之是什么东东
python OpenCV 中 Kmeans 函数详解
opencv kmeans聚类 图像色彩量化为例
opencv KMeans 图像分割实例
OpenCV如何实现透明(alpha channel)图像的读取和写入

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法。以下是DBSCAN聚类实现步骤: 1. 首先,需要确定两个参数,即邻域半径(ε)和最小点个数(MinPts)。邻域半径用于确定每个数据点的ε邻域范围,最小点个数用于确定核心对象。 2. 初始化一个标签数组,用于存储每个数据点的聚类结果,初始值为未分类(-1)。 3. 对数据集中每个未分类的数据点进行以下操作: a) 找到以该数据点为中心,在ε邻域内的所有数据点。 b) 如果ε邻域内的数据点的个数小于MinPts,则将该数据点标记为噪声点(-1)。 c) 否则,创建一个新的聚类,并将该数据点及其ε邻域内的所有数据点标记为该聚类的成员。 d) 对于新聚类中的每个数据点,如果其ε邻域内的数据点个数大于或等于MinPts,则将这些数据点添加为该聚类的成员。 e) 重复步骤d,直到新聚类不再增长。 4. 继续对未分类的数据点进行步骤3,直到所有数据点都被分类或标记为噪声点。 5. 最后,可以根据标签数组将数据点分配到不同的聚类中,同时噪声点也可以单独处理。 DBSCAN聚类算法的核心思想是通过密度可达的点来划分聚类,优势在于可以发现任意形状的聚类,并且能够自动识别和过滤噪声点。但是,DBSCAN算法的效果受到参数设定的影响,需要根据具体数据集和要达到的聚类效果进行调优。 ### 回答2: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它可以用于发现数据集中的高密度区域,并将其他低密度的数据点作为噪音进行标记。 DBSCAN算法的实现步骤如下: 1. 首先,选择一个未访问的数据点作为起始点,并计算其邻域中的所有数据点。 2. 接下来,检查该起始点是否满足核心点的条件。核心点至少需要一定数量的邻居数据点位于指定的半径内。 3. 如果起始点是一个核心点,则将其作为一个新的聚类簇,并将其所有密度可达的邻居数据点加入到该聚类簇中。 4. 重复上述步骤,直到所有的核心点及其密度可达的邻居都被访问到。 5. 如果起始点不满足核心点的条件,则将其标记为噪音。 6. 继续选择下一个未访问的数据点,并重复上述步骤,直到所有的数据点都被访问到。 在DBSCAN算法中,有几个关键的参数需要指定,包括: - 半径(epsilon):用于确定数据点的邻域范围。 - 邻居数量(min_samples):用于确定核心点的最小邻居数量。 除此之外,还可以根据具体的需求来选择其他参数,例如距离度量方法等。 总结起来,DBSCAN算法的实现需要经过选择起始点、计算邻居、判断核心点、聚类和标记噪音等步骤。这样可以实现对数据集中的高密度区域进行聚类,并对低密度的数据点进行噪音标记。 ### 回答3: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,可以对数据点进行聚类,并识别出噪声点。下面是DBSCAN聚类算法的步骤: 1. 确定两个参数:邻域半径ε和最小领域点个数MinPts。ε是表示邻域范围的半径,MinPts是一个点在邻域内应具有的最小数据点个数。 2. 随机选择一个未被访问的数据点P,然后找到其ε-邻域内的所有点。 3. 如果P的ε-邻域内的数据点个数大于等于MinPts,那么将这些点作为一个新的簇,并标记为已访问。 4. 针对P的ε-邻域内的每一个未被访问的数据点Q,重复2-3步骤,扩展当前簇的大小。 5. 当P的ε-邻域内的数据点个数小于MinPts时,将P标记为噪声点或边界点。 6. 重复2-5步骤,直到所有数据点都被访问。 7. 最后,将所有被标记为簇的数据点合并在一起,形成最终的聚类结果。 值得注意的是,DBSCAN聚类算法对于不同密度和形状的聚类可以有效地处理,并且相比于其他聚类算法可以自动发现聚类的个数。但它对于选择合适的参数值敏感,因此需要进行实验和调整来获取最佳的聚类结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值