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

基于已提取像素集的图像颜色空间压缩实现方案问询

Alright, let's tackle color space compression for your already processed small image. You've got width, height, a unique colors array, and a pixels index matrix—perfect setup to dive right in. Here's how to pull this off effectively:

1. Pick Your Compression Strategy

The most common approach for this scenario is color quantization—reducing the number of unique colors in the image while preserving visual fidelity. Two reliable methods are:

  • K-Means clustering (adaptive to your image's specific colors)
  • Fixed palette mapping (using pre-defined color sets like web-safe colors)
2. Implement K-Means Clustering (Adaptive Compression)

This method creates a custom palette tailored to your image, which usually gives better visual results than fixed palettes. Here's a step-by-step implementation (using JavaScript as an example):

Step 1: Prep Your Color Data

First, convert your colors objects into a format suitable for clustering—simple RGB arrays:

// Convert {r,g,b} objects to [r,g,b] arrays
const colorPoints = colors.map(color => [color.r, color.g, color.b]);

Step 2: Run K-Means Clustering

Define a K-Means function to group similar colors into k clusters (where k is your target number of colors, e.g., 16, 32):

function kMeans(points, k, maxIterations = 100) {
  // Initialize centroids by picking random points from the color set
  let centroids = points.sort(() => Math.random() - 0.5).slice(0, k);

  for (let iter = 0; iter < maxIterations; iter++) {
    // Assign each color to its closest centroid
    const clusters = Array.from({ length: k }, () => []);
    points.forEach(point => {
      const distances = centroids.map(centroid => 
        Math.sqrt(
          Math.pow(point[0] - centroid[0], 2) +
          Math.pow(point[1] - centroid[1], 2) +
          Math.pow(point[2] - centroid[2], 2)
        )
      );
      const closestIdx = distances.indexOf(Math.min(...distances));
      clusters[closestIdx].push(point);
    });

    // Update centroids to the average of their cluster
    const newCentroids = clusters.map(cluster => {
      if (cluster.length === 0) return centroids[clusters.indexOf(cluster)];
      const sum = cluster.reduce((acc, p) => [
        acc[0] + p[0],
        acc[1] + p[1],
        acc[2] + p[2]
      ], [0, 0, 0]);
      // Round to integer RGB values
      return sum.map(val => Math.round(val / cluster.length));
    });

    // Stop early if centroids stop changing
    if (JSON.stringify(centroids) === JSON.stringify(newCentroids)) break;
    centroids = newCentroids;
  }

  return centroids;
}

Step 3: Update Your Image Variables

Run the clustering and rebuild your colors and pixels arrays with the compressed palette:

// Set your target number of colors (adjust based on your needs)
const targetColorCount = 16;
const compressedColorCentroids = kMeans(colorPoints, targetColorCount);

// New colors array: convert centroids back to {r,g,b} objects
const newColors = compressedColorCentroids.map(([r, g, b]) => ({ r, g, b }));

// New pixels array: map original color indices to new palette indices
const newPixels = pixels.map(row => 
  row.map(pixelIdx => {
    const originalColor = colorPoints[pixelIdx];
    const distances = compressedColorCentroids.map(centroid => 
      Math.sqrt(
        Math.pow(originalColor[0] - centroid[0], 2) +
        Math.pow(originalColor[1] - centroid[1], 2) +
        Math.pow(originalColor[2] - centroid[2], 2)
      )
    );
    return distances.indexOf(Math.min(...distances));
  })
);
3. Alternative: Fixed Palette Compression

If you want a simpler, faster approach, use a pre-defined palette (like the 216 web-safe colors). For each color in your original colors array, find the closest match in the fixed palette, then update your variables accordingly.

4. Validate & Tweak
  • Check quality: Calculate the mean squared error (MSE) between original and compressed colors to measure fidelity.
  • Adjust k: Balance between compression ratio (smaller k = more compression) and visual quality (larger k = better quality).
  • Performance: Since your image is under 100x100, even K-Means will run almost instantly—no need to worry about slowdowns.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:35:16