我有一定数量的调色板(8),每个调色板有5种颜色。目标是使用画布处理图像并确定哪个调色板最接近匹配。
当我从调色板获得平均RGB值时,在将光源转换为LAB并使用CIE1976计算色差之前对源图像执行相同操作。最接近的匹配是最小距离。
这在一定程度上起作用,但我测试的许多图像都匹配两个特定的调色板。有没有更好的方法来计算图像最相关的调色板?
所以我改变它以使用直方图。我将下面的一些代码放在下面,但基本上我是
:我的调色板只有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);
}
这样可行,但结果似乎不对。例如,我将分析森林场景的图像,期望它产生绿色调色板,但它将返回另一个。我非常感谢任何指导。
答案 0 :(得分:0)
您需要在调色板颜色和样本颜色之间使用最小二乘差异。
您还需要为每个频道R G B和可能的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?]