js实现ostu
实现Otsu算法的JavaScript代码
Otsu算法是一种用于图像二值化的自动阈值选择方法,通过最大化类间方差来确定最佳分割阈值。以下是JavaScript实现:
function otsuThreshold(imageData) {
const pixels = imageData.data;
const histogram = new Array(256).fill(0);
// 计算灰度直方图
for (let i = 0; i < pixels.length; i += 4) {
const r = pixels[i];
const g = pixels[i + 1];
const b = pixels[i + 2];
const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
histogram[gray]++;
}
const totalPixels = pixels.length / 4;
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 * (mB - mF) * (mB - mF);
if (variance > maxVariance) {
maxVariance = variance;
threshold = t;
}
}
return threshold;
}
使用示例
// 从canvas获取图像数据
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// 计算Otsu阈值
const threshold = otsuThreshold(imageData);
// 应用阈值进行二值化
const binaryData = new ImageData(imageData.width, imageData.height);
for (let i = 0; i < imageData.data.length; i += 4) {
const gray = 0.299 * imageData.data[i] +
0.587 * imageData.data[i + 1] +
0.114 * imageData.data[i + 2];
const value = gray > threshold ? 255 : 0;
binaryData.data[i] = value;
binaryData.data[i + 1] = value;
binaryData.data[i + 2] = value;
binaryData.data[i + 3] = 255;
}
// 显示二值化结果
ctx.putImageData(binaryData, 0, 0);
算法说明
Otsu方法通过计算每个可能阈值的类间方差,选择使方差最大的阈值作为最佳分割点。类间方差计算公式为:

σ² = w₀ w₁ (μ₀ - μ₁)²

其中w₀和w₁分别是前景和背景像素的比例,μ₀和μ₁是前景和背景的平均灰度值。
性能优化
对于大图像,可以采样部分像素计算直方图以提高速度:
// 采样间隔
const step = 4;
for (let i = 0; i < pixels.length; i += 4 * step) {
// 计算灰度值并更新直方图
}
该方法适用于各种需要自动阈值分割的图像处理应用,如文档扫描、物体识别等场景。






