首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分析图像并与最近的调色板匹配。

分析图像并与最近的调色板匹配。
EN

Stack Overflow用户
提问于 2014-09-01 09:16:51
回答 1查看 636关注 0票数 0

我有一个固定数量的调色板(8),每个有5种颜色。目标是用画布处理图像,并确定哪个调色板最接近匹配。

从调色板获得平均RGB值的那一刻,在将源图像转换到实验室并使用CIE1976计算色差之前,对其进行相同的处理。最接近的匹配是最小的距离。

这在一定程度上是可行的,但我正在测试的许多图像都匹配两个特定的调色板。是否有更好的方法来计算图像中最相关的调色板?

所以我把它改成了直方图。我会把一些代码放在下面,但基本上我是:

  • 从选定的图像创建一个3D RGB直方图,将rgb值分割成8个组中的一个,(8*8*8)所以512。
  • 将直方图扁平化以创建单个512数组。
  • 通过除以图像中的总像素来规范这些值。
  • 我对调色板也这样做,创建了一个平坦的512直方图。
  • 计算两个直方图之间的x平方距离以找到最接近的调色板。

我的调色板只有5种颜色,它们的直方图是空的。在比较直方图和x-平方时,这是否是一个问题。

这就是我如何创建平面直方图的图像,以进行分析。

代码语言:javascript
复制
            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种颜色。

代码语言:javascript
复制
        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);
        });

为了计算x平方距离,我在每个调色板上循环,得到图像直方图的距离。那么最小的应该是最相似的。

代码语言:javascript
复制
            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);
            }

这是可行的,但结果似乎是错误的。例如,我将分析一个森林场景的图像,期望它产生绿色调色板,但它将返回另一个。我希望你能提供任何指导。

EN

回答 1

Stack Overflow用户

发布于 2014-09-03 20:43:16

您需要在调色板颜色和样本颜色之间使用最小二乘的差异。

另外,您还需要对每个频道R和可能的A进行此操作。

它看起来像这样(伪代码在.中):

代码语言:javascript
复制
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?]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25602532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档