算法2026-04-28·10 分钟
算法知识库:计算机视觉基础算法实现
JavaScript/TypeScript 实现计算机视觉基础算法,如图像处理、边缘检测、特征提取等。
计算机视觉基础算法实现
1. 图像类定义
ts
class Image {
width: number;
height: number;
data: number[][][]; // [y][x][channel]
constructor(width: number, height: number, data?: number[][][]) {
this.width = width;
this.height = height;
this.data = data || this.createEmptyData(width, height);
}
private createEmptyData(width: number, height: number): number[][][] {
return Array.from({ length: height }, () => Array.from({ length: width }, () => [0, 0, 0]));
}
getPixel(x: number, y: number): number[] {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
return [0, 0, 0];
}
return [...this.data[y][x]];
}
setPixel(x: number, y: number, color: number[]): void {
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
this.data[y][x] = [...color];
}
}
clone(): Image {
const newData = this.data.map((row) => row.map((pixel) => [...pixel]));
return new Image(this.width, this.height, newData);
}
}2. 灰度转换
ts
function toGrayscale(image: Image): Image {
const grayImage = new Image(image.width, image.height);
for (let y = 0; y < image.height; y += 1) {
for (let x = 0; x < image.width; x += 1) {
const [r, g, b] = image.getPixel(x, y);
const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
grayImage.setPixel(x, y, [gray, gray, gray]);
}
}
return grayImage;
}3. 高斯模糊
ts
function gaussianBlur(image: Image, sigma: number = 1): Image {
const kernel = createGaussianKernel(sigma);
return convolve(image, kernel);
}
function createGaussianKernel(sigma: number): number[][] {
const size = Math.ceil(6 * sigma);
if (size % 2 === 0) size += 1;
const center = Math.floor(size / 2);
const kernel: number[][] = [];
let sum = 0;
for (let y = 0; y < size; y += 1) {
kernel[y] = [];
for (let x = 0; x < size; x += 1) {
const dx = x - center;
const dy = y - center;
const value = Math.exp(-(dx * dx + dy * dy) / (2 * sigma * sigma));
kernel[y][x] = value;
sum += value;
}
}
// 归一化
for (let y = 0; y < size; y += 1) {
for (let x = 0; x < size; x += 1) {
kernel[y][x] /= sum;
}
}
return kernel;
}
function convolve(image: Image, kernel: number[][]): Image {
const result = new Image(image.width, image.height);
const kSize = kernel.length;
const kCenter = Math.floor(kSize / 2);
for (let y = 0; y < image.height; y += 1) {
for (let x = 0; x < image.width; x += 1) {
let r = 0,
g = 0,
b = 0;
for (let ky = 0; ky < kSize; ky += 1) {
for (let kx = 0; kx < kSize; kx += 1) {
const px = x + kx - kCenter;
const py = y + ky - kCenter;
const [pr, pg, pb] = image.getPixel(px, py);
const weight = kernel[ky][kx];
r += pr * weight;
g += pg * weight;
b += pb * weight;
}
}
result.setPixel(x, y, [Math.round(r), Math.round(g), Math.round(b)]);
}
}
return result;
}4. Sobel 边缘检测
ts
function sobelEdgeDetection(image: Image): Image {
const grayImage = toGrayscale(image);
const result = new Image(image.width, image.height);
const sobelX = [
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1],
];
const sobelY = [
[-1, -2, -1],
[0, 0, 0],
[1, 2, 1],
];
for (let y = 1; y < image.height - 1; y += 1) {
for (let x = 1; x < image.width - 1; x += 1) {
let gx = 0;
let gy = 0;
for (let ky = -1; ky <= 1; ky += 1) {
for (let kx = -1; kx <= 1; kx += 1) {
const pixel = grayImage.getPixel(x + kx, y + ky)[0];
gx += pixel * sobelX[ky + 1][kx + 1];
gy += pixel * sobelY[ky + 1][kx + 1];
}
}
const magnitude = Math.sqrt(gx * gx + gy * gy);
const edge = Math.min(255, Math.round(magnitude));
result.setPixel(x, y, [edge, edge, edge]);
}
}
return result;
}5. Canny 边缘检测 (简化版)
ts
function cannyEdgeDetection(image: Image, lowThreshold: number = 50, highThreshold: number = 150): Image {
// 1. 高斯模糊
const blurred = gaussianBlur(image, 1.4);
// 2. 梯度计算
const gradient = sobelEdgeDetection(blurred);
// 3. 非极大值抑制 (简化版)
const suppressed = nonMaxSuppression(gradient);
// 4. 双阈值处理
const thresholded = doubleThreshold(suppressed, lowThreshold, highThreshold);
// 5. 边缘连接 (简化版)
return hysteresis(thresholded);
}
function nonMaxSuppression(gradient: Image): Image {
// 简化实现
return gradient.clone();
}
function doubleThreshold(image: Image, low: number, high: number): Image {
const result = new Image(image.width, image.height);
for (let y = 0; y < image.height; y += 1) {
for (let x = 0; x < image.width; x += 1) {
const pixel = image.getPixel(x, y)[0];
let value = 0;
if (pixel >= high) {
value = 255;
} else if (pixel >= low) {
value = 128; // 弱边缘
}
result.setPixel(x, y, [value, value, value]);
}
}
return result;
}
function hysteresis(image: Image): Image {
const result = image.clone();
for (let y = 1; y < image.height - 1; y += 1) {
for (let x = 1; x < image.width - 1; x += 1) {
if (image.getPixel(x, y)[0] === 128) {
// 检查 8 邻域是否有强边缘
let hasStrongNeighbor = false;
for (let dy = -1; dy <= 1; dy += 1) {
for (let dx = -1; dx <= 1; dx += 1) {
if (image.getPixel(x + dx, y + dy)[0] === 255) {
hasStrongNeighbor = true;
break;
}
}
if (hasStrongNeighbor) break;
}
const value = hasStrongNeighbor ? 255 : 0;
result.setPixel(x, y, [value, value, value]);
}
}
}
return result;
}6. 直方图均衡化
ts
function histogramEqualization(image: Image): Image {
const grayImage = toGrayscale(image);
const histogram = new Array(256).fill(0);
const cdf = new Array(256).fill(0);
// 计算直方图
for (let y = 0; y < grayImage.height; y += 1) {
for (let x = 0; x < grayImage.width; x += 1) {
const pixel = grayImage.getPixel(x, y)[0];
histogram[pixel] += 1;
}
}
// 计算累积分布函数
cdf[0] = histogram[0];
for (let i = 1; i < 256; i += 1) {
cdf[i] = cdf[i - 1] + histogram[i];
}
// 归一化 CDF
const totalPixels = grayImage.width * grayImage.height;
const cdfMin = cdf.find((val) => val > 0) || 0;
const result = new Image(grayImage.width, grayImage.height);
for (let y = 0; y < grayImage.height; y += 1) {
for (let x = 0; x < grayImage.width; x += 1) {
const pixel = grayImage.getPixel(x, y)[0];
const equalized = Math.round(((cdf[pixel] - cdfMin) / (totalPixels - cdfMin)) * 255);
result.setPixel(x, y, [equalized, equalized, equalized]);
}
}
return result;
}7. 实现要点
- 图像处理基于像素操作。
- 卷积用于滤波和特征提取。
- 边缘检测结合梯度和阈值。
- 直方图均衡化改善对比度。
- 实际应用中应使用专门的图像处理库。
算法计算机视觉JavaScript