簡體   English   中英

分析圖像並匹配最接近的調色板

[英]Analyse an image and match to the closest color palette

我有一定數量的調色板(8),每種都有5種顏色。 目的是使用畫布處理圖像並確定最接近的調色板。

當時,我正在從調色板獲取平均RGB值,然后在將其轉換為LAB並使用CIE1976計算色差之前,先對源圖像進行同樣的處理。 最接近的匹配是最小的距離。

這在一定程度上可行,但是我正在測試的許多圖像都匹配兩個特定的調色板。 有沒有更好的方法來計算與圖像最相關的調色板?

因此,我將其更改為可與直方圖一起使用。 我將一些代碼放在下面,但基本上我是:

  • 根據所選圖像創建3D RGB直方圖,將rgb值分成8個存儲區之一((8 * 8 * 8)這樣512。
  • 展平直方圖以創建單個512數組。
  • 通過除以圖像中的總像素對值進行歸一化。
  • 我對調色板也一樣,創建了一個平坦的512直方圖。
  • 計算兩個直方圖之間的卡方距離,以找到最接近的調色板。

我的調色板只有5種顏色,它們的直方圖非常空白。 將直方圖與卡方進行比較時是否會成為問題?

這就是我為要分析的圖像創建平面直方圖的方式。

            var canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d'),
                imgWidth = this.width,
                imgHeight = this.height,
                totalPixels = imgWidth * imgHeight;

            ctx.drawImage(this, 0, 0, this.width, this.height);

            var data = ctx.getImageData(0, 0, imgWidth, imgHeight).data;
            var x, y, z, histogram = new Float64Array(512);

            for(x=0; x<imgWidth; x++){
                for(y=0; y<imgHeight; y++){
                    var index = imgWidth * y + x;

                    var rgb = [data[index], data[index+1], data[index+2] ];

                    // put into relevant bank
                    var xbin = Math.floor((rgb[0]/255)*8)
                    var ybin = Math.floor((rgb[1]/255)*8)
                    var zbin = Math.floor((rgb[2]/255)*8)

                    histogram[ (ybin * 8 + xbin) * 8 + zbin ] ++;
                }
            }

            // normalize values.
            for(var i=0; i<512; i++) {
                histogram[i] /= totalPixels;
            }

這就是我為調色板創建直方圖的方式。 顏色僅存儲在RGB值數組中,每個調色板有5種顏色。

        var pals = [];

        palettes.forEach(function(palette){
            var paletteH = new Float64Array(512);
            palette.forEach(function(color){
                var xbin = Math.floor((color[0]/255)*8);
                var ybin = Math.floor((color[1]/255)*8);
                var zbin = Math.floor((color[2]/255)*8);
                paletteH[ (ybin * 8 + xbin) * 8 + zbin ] ++;
            });
            for(var i=0; i<512; i++) { paletteH[i] /= 5; }
            pals.push(paletteH);
        });

為了計算卡方距離,我遍歷每個調色板獲取與圖像直方圖的距離。 那么最小的應該是最相似的。

            for(var p = 0; p<pals.length; p++){
                var result = 0;
                for(var i=0; a = histogram[i], b = pals[p][i], i < 512; i++ ){
                    result += 0.5 * ( Math.pow(a-b,2) / (a + b + 1e-10));
                }
                console.log(result);
            }

這可行,但結果似乎不對。 例如,我將分析一個森林場景的圖像,期望它會導致綠色調色板,但是它將返回另一個。 我將不勝感激任何指導。

您需要在調色板顏色和樣本顏色之間使用最小二乘方差。

另外,您還需要為每個通道RGB(可能還有A)執行此操作。

看起來像這樣([...]中的偽代碼):

var min = 999999;
var paletteMatch;

[loop sample colors] {
  [loop palette colors] {

    float lsd = (Math.pow(paletteR - sampleR, 2) + [greed] + [blue]) / 3;

    if (lsd < min) {
      min = lsd;
      paletteMatch = currentPaletteInThisLoop;
    }
  }
  [award a point for paletteMatch for this sample Color
}

[which palette has the most points?]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM