使用Javascript实现中位数切割算法的问题



我正在尝试实现一个代码,从图像中挑选出颜色,然后从图像的所有颜色中获得某些颜色的托盘。我正在尝试使用中值切割算法来实现这一点。

目前,我正在遵循这里提到的中值切割算法的步骤:

下面是我的POC中的代码片段:

const getColor = () => {
const canvas = document.createElement('canvas');
canvas.width = displayImage.width;
canvas.height = displayImage.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(displayImage, 0, 0);
const pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
getPallete(pixelData);
};
const getPallete = (data) => {
// data contains image data (r,g,b,a)
if (data.length != 0) {
for (let i = 0; i < data.length; i += 4) {
let [red, green, blue] = [data[i], data[i + 1], data[i + 2]];
if (red < channelProperties.minRed) {
channelProperties.minRed = red;
}
if (red > channelProperties.maxRed) {
channelProperties.maxRed = red;
}
// Update minimum and maximum values for green channel
if (green < channelProperties.minGreen) {
channelProperties.minGreen = green;
}
if (green > channelProperties.maxGreen) {
channelProperties.maxGreen = green;
}
// Update minimum and maximum values for blue channel
if (blue < channelProperties.minBlue) {
channelProperties.minBlue = blue;
}
if (blue > channelProperties.maxBlue) {
channelProperties.maxBlue = blue;
}
}
// gets the channel with highest range
let highestChannel = getChannel();
//This sorts the image data based on highest channel
let sortedData = sortImageData(data, highestChannel);
//This gives back the middle index
let median = getMedian(sortedData);
//Here I break the array from median and resend it
const lowerPart = data.slice(0, median);
const upperPart = data.slice(median + 1);
getPallete(lowerPart);
getPallete(upperPart);
}
};

我已经实现了链接中提到的前4步。然而,我在最后一步搞砸了,或者更确切地说,我无法弄清楚如何得到我的最终托盘。谁能帮忙纠正这个代码/告诉我我错过了什么?

看起来你没有返回任何东西,你似乎没有打破递归。此外,在链接源中,它说您必须在桶上构建平均值。并且您需要指定要查找的颜色的数量,这对应于迭代的数量。

我认为你需要补充的是:

const getPallete = (data, iterations) => {
if (data.length === 0) {
return []
}

if(iterations <= 1){
return [getAverageColor(data)]  // <--- build bucket average
}
// build upper and lower bucket, same as before

return [ // <--- collect and return recursion result
...getPallete(lowerPart, iterations-1),
...getPallete(upperPart, iterations-1)
]
}
const getAverageColor = (data) => {
const sums = [0,0,0,0]
for (let i = 0; i < data.length; i += 4) {
for (let j = 0; j < 4; j++) {
sums[j] += data[i+j]
}
}
const numberOfPixels = data.length / 4
return sums.map(v => Math.round(v/numberOfPixels))
}

这是一个快速沙盒

最新更新