You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于轮廓系数法的K-means聚类颜色应用中噪点与线条问题排查

问题:K-means聚类后颜色替换存在噪点与边界问题

我结合K-means聚类算法与轮廓系数法确定数据集的最优k值,目标是为生成的聚类分配不同颜色。但在颜色分配时,发现聚类内部存在噪点和淡线,推测是由数据集中占比极低的颜色导致。

已实现过滤占比低于特定阈值的聚类,但调整后输出仍存在噪点,尤其在聚类边界处更为明显。相关图片如下:

  • 原始图片:原始图片
  • 聚类后图片:聚类后图片
  • 颜色修改后图片:颜色修改后图片

聚类生成代码

def optimal_k_using_silhouette(image):
    lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2Lab)
    data = sample_pixels(lab_image)
    range_n_clusters = list(range(2, 7))
    silhouette_avgs = []
    
    for n_clusters in range_n_clusters:
        clusterer = KMeans(n_clusters=n_clusters, random_state=10, n_init=10)
        cluster_labels = clusterer.fit_predict(data)
        silhouette_avg = silhouette_score(data, cluster_labels)
        silhouette_avgs.append(silhouette_avg)

    best_k = range_n_clusters[np.argmax(silhouette_avgs)]
    best_clusterer = KMeans(n_clusters=best_k, random_state=10, n_init=10).fit(data)

    valid_clusters = get_valid_clusters(best_clusterer, lab_image.reshape(-1, 3))
    best_clusterer.cluster_centers_ = best_clusterer.cluster_centers_[valid_clusters]
    best_clusterer.n_clusters = len(valid_clusters)

    return best_clusterer

颜色修改实现代码

@app.route("/modify_colors", methods=["POST"])
def modify_colors():
    modified_colors = []
    for i in range(len(session['colors_bgr'])):
        r = int(request.form.get(f'color_{i}_r'))
        g = int(request.form.get(f'color_{i}_g'))
        b = int(request.form.get(f'color_{i}_b'))
        modified_colors.append((b, g, r))

    segmented_image_path = "static/segmented_image.png"
    segmented_img, alpha_channel = upscale_and_smooth(segmented_image_path, desired_width=1600)
    print("Segmented Image Shape:", segmented_img.shape)

    replaced_image = replace_colors(segmented_img, session['colors_bgr'], modified_colors)
    print("Replaced Image Shape:", replaced_image.shape)

    # Blend the images at the borders
    replaced_image = blend_at_borders(segmented_img, replaced_image)

    if alpha_channel is not None:
        replaced_image = cv2.merge([replaced_image, alpha_channel])
    cv2.imwrite('static/segmented_image_modified.png', replaced_image)
    session['segmented_image_path'] = 'static/segmented_image_modified.png'  # Update the path in session
    return render_template('result_modified.html', image_path=session['segmented_image_path'])

解决思路与优化建议

1. 聚类前的图像预处理

  • 对原始图像做高斯模糊(cv2.GaussianBlur),用3x3或5x5核过滤高频噪点,避免K-means将孤立噪点识别为独立聚类。
  • 结合HSV空间的饱和度通道,过滤低饱和度像素(如饱和度<20),这类像素多为灰度干扰或噪点,可减少无效聚类的生成。

2. 聚类后的后处理

  • 形态学操作:用cv2.morphologyEx执行闭运算(膨胀+腐蚀)填补聚类内部的小空洞,再执行开运算(腐蚀+膨胀)去除边界的孤立噪点,核大小选3x3或5x5矩形核。
  • 连通域分析:用cv2.connectedComponentsWithStats提取每个聚类的连通区域,过滤掉面积小于阈值的小区域,只保留主体聚类区域。

3. 颜色替换逻辑优化

  • 基于聚类标签图操作:聚类后保存每个像素的聚类标签矩阵(而非彩色分割图),颜色替换时直接根据标签映射新颜色,避免因颜色匹配误差产生噪点。
  • 边缘保留平滑:对替换后的图像用cv2.bilateralFilter做双边滤波,在保留聚类边界的同时平滑内部噪点,或使用导向滤波进一步优化边界过渡。

4. 聚类过程细节调整

  • 采样像素时采用均匀网格采样,避免随机采样导致的噪点像素占比过高,确保采样覆盖图像所有区域。
  • 过滤小聚类时,结合聚类的像素分布集中度(如计算聚类内像素的方差),避免误删边缘的有效小区域。

内容的提问来源于stack exchange,提问作者Osama Bin Shamim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:00:20