Created
June 22, 2020 12:31
-
-
Save linkgod/d0aa7766823fe5762484aa41580055a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getRGBCluster(k = 3, rRange = 255, gRange = 255, bRange = 255) { | |
function equal(means, newMeans) { | |
return means.every((mean, index) => | |
mean[0] === newMeans[index][0] | |
&& mean[1] === newMeans[index][1] | |
&& mean[2] === newMeans[index][2] | |
) | |
} | |
function assignment(data, means) { | |
const clusters = Array(means.length).fill().map(() => []) | |
// 对每个点进行分类 | |
data.forEach(point => { | |
let minIndex = 0; | |
means.reduce((prev, mean, index) => { | |
const distance = euclideanDistance(point, mean); | |
if (distance < prev) { | |
minIndex = index; | |
return distance | |
} | |
return prev; | |
}, Number.MAX_VALUE) | |
clusters[minIndex].push(point); | |
}); | |
const newMeans = clusters.map(cluster => average(cluster)) | |
return newMeans; | |
} | |
// 获取所有的颜色,调整步长可以减少样本集合的数量 | |
function getColors(rRange, gRange, bRange) { | |
const colors = []; | |
let [r, g, b] = []; | |
for (r = 0; r <= rRange; r += 1) { | |
for (g = 0; g <= gRange; g += 1) { | |
for (b = 0; b <= bRange; b += 1) { | |
colors.push([r, g, b]); | |
} | |
} | |
} | |
return colors; | |
} | |
function getMeans(k, originData) { | |
const means = []; | |
const data = [].concat(originData); | |
while(k--) { | |
const index = Math.floor(Math.random() * data.length); | |
means.push(data[index]); | |
data.splice(index, 1); | |
} | |
return means; | |
} | |
// 计算欧几里得距离 | |
function euclideanDistance(point1, point2) { | |
return Math.sqrt( | |
Math.pow(point1[0] - point2[0], 2) | |
+ Math.pow(point1[1] - point2[1], 2) | |
+ Math.pow(point1[2] - point2[2], 2) | |
) | |
} | |
// 计算平均点 | |
function average(colors) { | |
return colors | |
.reduce( | |
(sum, color) => [sum[0] + color[0], sum[1] + color[1], sum[2] + color[2]], | |
[0, 0, 0] | |
) | |
.map(sum => sum / colors.length) | |
} | |
const colors = getColors(rRange, gRange, bRange); | |
let means = getMeans(k, colors); | |
console.log(`means:`, means) | |
let newMeans = assignment(colors, means); | |
console.log(`newMeans:`, newMeans) | |
let count = 0; | |
while(!equal(means, newMeans)) { | |
means = newMeans; | |
newMeans = assignment(colors, means); | |
count += 1; | |
} | |
return newMeans; | |
} | |
console.log(getRGBCluster(3, 100, 100, 100)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment