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

如何复刻Python主色调函数?求适配Rust的可配置KMeans库

Rust实现可自定义KMeans参数的主色调识别

针对你的需求,推荐使用linfa-kmeans crate(支持MiniBatchKMeans和标准KMeans,参数完全可配置)配合image crate处理图像,完美匹配你原Python代码的逻辑,且能避免color-thief-rs的结果偏差问题。

步骤与代码实现

首先在Cargo.toml中添加依赖:

[dependencies]
image = "0.24"
linfa = "0.7"
linfa-kmeans = "0.7"
ndarray = "0.15"
rand = "0.8"

然后实现对应功能的代码,完全对齐原Python逻辑:

use image::GenericImageView;
use linfa::traits::Fit;
use linfa_kmeans::{MiniBatchKMeans, KMeansParams};
use ndarray::{Array, Array2, Axis};
use rand::rngs::StdRng;
use rand::SeedableRng;

fn dominant_colors(image_path: &str) -> Vec<(u8, u8, u8)> {
    // 1. 读取图像并缩放到150x150
    let img = image::open(image_path).expect("Failed to open image");
    let resized_img = img.resize_exact(150, 150, image::imageops::FilterType::Nearest);

    // 2. 将像素转为扁平化的RGB浮点数组(形状:(150*150, 3))
    let mut pixels = Array2::zeros((150 * 150, 3));
    for (x, y, pixel) in resized_img.pixels() {
        let idx = y as usize * 150 + x as usize;
        pixels[[idx, 0]] = pixel[0] as f32;
        pixels[[idx, 1]] = pixel[1] as f32;
        pixels[[idx, 2]] = pixel[2] as f32;
    }

    // 3. 初始化MiniBatchKMeans,参数完全对应原Python代码
    let rng = StdRng::seed_from_u64(1000);
    let kmeans = MiniBatchKMeans::params_with_rng(10, rng)
        .init_strategy(linfa_kmeans::InitStrategy::KMeansPlusPlus)
        .max_n_iterations(20)
        .fit(&pixels)
        .expect("KMeans fitting failed");

    // 4. 计算每个聚类的像素数量
    let assignments = kmeans.predict(&pixels);
    let mut counts = vec![0; 10];
    for &assign in assignments.iter() {
        counts[assign] += 1;
    }

    // 5. 按出现次数降序排序,返回RGB颜色元组
    let mut color_indices: Vec<usize> = (0..10).collect();
    color_indices.sort_by(|&a, &b| counts[b].cmp(&counts[a]));

    color_indices.iter()
        .map(|&idx| {
            let center = kmeans.centroids().row(idx);
            (
                center[0].round() as u8,
                center[1].round() as u8,
                center[2].round() as u8,
            )
        })
        .collect()
}

fn main() {
    let colors = dominant_colors("test_image.jpg");
    println!("Dominant colors (from most to least):");
    for (i, color) in colors.iter().enumerate() {
        println!("{}: RGB({}, {}, {})", i+1, color.0, color.1, color.2);
    }
}

参数自定义说明

你可以根据需求调整MiniBatchKMeans的参数:

  • 修改n_clusters:调整聚类数量(对应原Python的n_clusters=10)
  • 切换为标准KMeans:将MiniBatchKMeans替换为KMeans,参数配置逻辑一致
  • 调整max_n_iterations:修改迭代次数(对应原Python的max_iter=20)
  • 更换初始化策略:支持KMeansPlusPlus、Random等
  • 修改随机种子:通过seed_from_u64调整,保证结果可复现(对应原Python的random_state=1000)

为什么选择linfa-kmeans?

  • 与scikit-learn的KMeans/MiniBatchKMeans逻辑对齐,结果一致性高
  • 参数完全开放自定义,满足你的灵活配置需求
  • 基于ndarray,处理高维像素数据效率高
  • 社区维护活跃,文档完善

内容的提问来源于stack exchange,提问作者Jacob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:16:17