js实现ostu
使用JavaScript实现Otsu算法
Otsu算法是一种用于图像二值化的自动阈值选择方法,通过最大化类间方差来确定最佳阈值。以下为JavaScript实现步骤:
计算灰度直方图
function computeHistogram(imageData) {
const histogram = new Array(256).fill(0);
for (let i = 0; i < imageData.length; i += 4) {
const gray = Math.round(0.299 * imageData[i] + 0.587 * imageData[i + 1] + 0.114 * imageData[i + 2]);
histogram[gray]++;
}
return histogram;
}
计算Otsu阈值
function otsuThreshold(histogram, totalPixels) {
let sum = 0;
for (let t = 0; t < 256; t++) sum += t * histogram[t];
let sumB = 0;
let wB = 0;
let wF = 0;
let maxVariance = 0;
let threshold = 0;
for (let t = 0; t < 256; t++) {
wB += histogram[t];
if (wB === 0) continue;
wF = totalPixels - wB;
if (wF === 0) break;
sumB += t * histogram[t];
const mB = sumB / wB;
const mF = (sum - sumB) / wF;
const variance = wB * wF * Math.pow(mB - mF, 2);
if (variance > maxVariance) {
maxVariance = variance;
threshold = t;
}
}
return threshold;
}
应用阈值进行二值化
function applyThreshold(imageData, threshold) {
const newImageData = new Uint8ClampedArray(imageData.length);
for (let i = 0; i < imageData.length; i += 4) {
const gray = Math.round(0.299 * imageData[i] + 0.587 * imageData[i + 1] + 0.114 * imageData[i + 2]);
const value = gray > threshold ? 255 : 0;
newImageData[i] = newImageData[i + 1] = newImageData[i + 2] = value;
newImageData[i + 3] = 255; // Alpha通道
}
return newImageData;
}
完整调用示例
function otsuBinarization(imageData) {
const histogram = computeHistogram(imageData);
const totalPixels = imageData.length / 4;
const threshold = otsuThreshold(histogram, totalPixels);
return applyThreshold(imageData, threshold);
}
算法优化建议
内存优化 处理大图像时可分段计算直方图,避免内存峰值。
性能优化 使用Web Worker进行后台计算,防止UI线程阻塞。
颜色空间选择 对于特定场景可考虑使用HSL或YCbCr颜色空间替代RGB转换。
数学原理
Otsu算法的核心是最大化类间方差: $$ \sigma_b^2 = \omega_0(\mu_0 - \mu_T)^2 + \omega_1(\mu_1 - \mu_T)^2 $$ 其中$\omega$为类概率,$\mu$为类均值。

注意事项
- 输入图像需为灰度图或先转换为灰度
- 图像数据需为Uint8ClampedArray格式
- 阈值范围默认为0-255,可根据实际需求调整
- 透明像素需特殊处理避免影响计算结果






