乐闻世界logo
搜索文章和话题

OpenCV.js 如何进行机器学习任务?

3月6日 21:36

OpenCV.js 支持多种机器学习算法,虽然不如专门的机器学习库强大,但对于许多计算机视觉任务已经足够。以下是 OpenCV.js 中可用的机器学习功能:

1. 机器学习算法概述

OpenCV.js 提供的机器学习算法包括:

  • K-近邻(KNN):用于分类和回归
  • 支持向量机(SVM):用于分类和回归
  • 决策树:用于分类和回归
  • 随机森林:集成学习方法
  • Boosting:AdaBoost 等提升算法
  • 神经网络:基础的 MLP 神经网络

2. K-近邻(KNN)分类

javascript
function knnClassification() { // 准备训练数据 let trainData = cv.matFromArray(6, 2, cv.CV_32FC1, [ 1.0, 1.1, 1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 0.1, 0.0, 0.1, 0.1 ]); let labels = cv.matFromArray(6, 1, cv.CV_32SC1, [0, 0, 1, 1, 1, 1]); // 创建 KNN 模型 let knn = new cv.ml.KNearest(); knn.setDefaultK(3); knn.setIsClassifier(true); // 训练模型 knn.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测新样本 let newSample = cv.matFromArray(1, 2, cv.CV_32FC1, [0.5, 0.5]); let results = new cv.Mat(); let neighbors = new cv.Mat(); let dist = new cv.Mat(); knn.findNearest(newSample, 3, results, neighbors, dist); console.log('Predicted class:', results.data32S[0]); // 清理 trainData.delete(); labels.delete(); newSample.delete(); results.delete(); neighbors.delete(); dist.delete(); knn.clear(); }

3. 支持向量机(SVM)

javascript
function svmClassification() { // 准备训练数据 let trainData = cv.matFromArray(4, 2, cv.CV_32FC1, [ 1.0, 1.0, 2.0, 2.0, -1.0, -1.0, -2.0, -2.0 ]); let labels = cv.matFromArray(4, 1, cv.CV_32SC1, [1, 1, -1, -1]); // 创建 SVM 模型 let svm = cv.ml.SVM.create(); svm.setType(cv.ml.SVM_C_SVC); svm.setKernel(cv.ml.SVM_LINEAR); svm.setTermCriteria(new cv.TermCriteria(cv.TermCriteria_MAX_ITER, 100, 1e-6)); // 训练模型 svm.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测 let testSample = cv.matFromArray(1, 2, cv.CV_32FC1, [1.5, 1.5]); let response = svm.predict(testSample); console.log('Predicted class:', response); // 清理 trainData.delete(); labels.delete(); testSample.delete(); svm.clear(); }

4. 决策树

javascript
function decisionTreeClassification() { // 准备训练数据 let trainData = cv.matFromArray(10, 2, cv.CV_32FC1, [ 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 2.0, 3.0, 1.0, 3.0, 2.0, 1.0, 3.0, 2.0, 3.0, 3.0, 3.0, 4.0, 3.0 ]); let labels = cv.matFromArray(10, 1, cv.CV_32SC1, [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]); // 创建决策树 let dtree = cv.ml.DTrees.create(); dtree.setMaxDepth(5); dtree.setMinSampleCount(2); dtree.setCVFolds(0); // 训练 dtree.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测 let testSample = cv.matFromArray(1, 2, cv.CV_32FC1, [2.5, 2.5]); let response = dtree.predict(testSample); console.log('Predicted class:', response); // 清理 trainData.delete(); labels.delete(); testSample.delete(); dtree.clear(); }

5. 随机森林

javascript
function randomForestClassification() { // 准备训练数据 let trainData = cv.matFromArray(20, 2, cv.CV_32FC1, [ // 类别 0 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 2.0, 1.5, 1.5, 1.5, 2.5, 2.5, 1.5, 2.5, 2.5, // 类别 1 4.0, 4.0, 4.0, 5.0, 5.0, 4.0, 5.0, 5.0, 4.5, 4.5, 4.5, 5.5, 5.5, 4.5, 5.5, 5.5 ]); let labels = cv.matFromArray(20, 1, cv.CV_32SC1, [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ]); // 创建随机森林 let rf = cv.ml.RTrees.create(); rf.setMaxDepth(10); rf.setMinSampleCount(2); rf.setActiveVarCount(0); rf.setTermCriteria(new cv.TermCriteria(cv.TermCriteria_MAX_ITER, 100, 0.01)); // 训练 rf.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测 let testSample = cv.matFromArray(1, 2, cv.CV_32FC1, [3.0, 3.0]); let response = rf.predict(testSample); console.log('Predicted class:', response); // 清理 trainData.delete(); labels.delete(); testSample.delete(); rf.clear(); }

6. AdaBoost

javascript
function adaboostClassification() { // 准备训练数据 let trainData = cv.matFromArray(10, 2, cv.CV_32FC1, [ 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 4.0, 5.0, 5.0, 3.0, 3.0, 3.5, 3.5 ]); let labels = cv.matFromArray(10, 1, cv.CV_32SC1, [0, 0, 0, 0, 1, 1, 1, 1, 0, 0]); // 创建 AdaBoost let boost = cv.ml.Boost.create(); boost.setBoostType(cv.ml.DISCRETE); boost.setWeakCount(100); boost.setWeightTrimRate(0.95); boost.setMaxDepth(2); // 训练 boost.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测 let testSample = cv.matFromArray(1, 2, cv.CV_32FC1, [3.0, 3.0]); let response = boost.predict(testSample); console.log('Predicted class:', response); // 清理 trainData.delete(); labels.delete(); testSample.delete(); boost.clear(); }

7. 神经网络(MLP)

javascript
function mlpClassification() { // 准备训练数据(XOR 问题) let trainData = cv.matFromArray(4, 2, cv.CV_32FC1, [ 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0 ]); let labels = cv.matFromArray(4, 1, cv.CV_32FC1, [0.0, 1.0, 1.0, 0.0]); // 创建神经网络 let layers = new cv.Mat(); layers.push_back(new cv.Scalar(2)); // 输入层:2 个神经元 layers.push_back(new cv.Scalar(4)); // 隐藏层:4 个神经元 layers.push_back(new cv.Scalar(1)); // 输出层:1 个神经元 let mlp = cv.ml.ANN_MLP.create(); mlp.setLayerSizes(layers); mlp.setActivationFunction(cv.ml.ANN_MLP_SIGMOID_SYM, 1, 1); mlp.setTrainMethod(cv.ml.ANN_MLP_BACKPROP); mlp.setBackpropWeightScale(0.1); mlp.setBackpropMomentumScale(0.1); mlp.setTermCriteria(new cv.TermCriteria(cv.TermCriteria_MAX_ITER + cv.TermCriteria_EPS, 10000, 1e-6)); // 训练 mlp.train(trainData, cv.ml.ROW_SAMPLE, labels); // 预测 let testSample = cv.matFromArray(1, 2, cv.CV_32FC1, [0.0, 1.0]); let response = new cv.Mat(); mlp.predict(testSample, response); console.log('Predicted output:', response.data32F[0]); // 清理 trainData.delete(); labels.delete(); testSample.delete(); response.delete(); layers.delete(); mlp.clear(); }

8. 实际应用:图像分类

javascript
class ImageClassifier { constructor() { this.model = null; this.featureExtractor = null; } // 提取图像特征 extractFeatures(image) { let mat = cv.imread(image); let gray = new cv.Mat(); let features = new cv.Mat(); try { cv.cvtColor(mat, gray, cv.COLOR_RGBA2GRAY); // 计算直方图作为特征 let histSize = [16]; let ranges = [0, 256]; cv.calcHist([gray], [0], new cv.Mat(), features, histSize, ranges); // 归一化 cv.normalize(features, features, 0, 1, cv.NORM_MINMAX); return features; } finally { mat.delete(); gray.delete(); } } // 训练分类器 async trainClassifier(imagePaths, labels) { let trainData = new cv.Mat(); let trainLabels = new cv.Mat(); for (let i = 0; i < imagePaths.length; i++) { const img = document.getElementById(imagePaths[i]); const features = this.extractFeatures(img); if (i === 0) { features.copyTo(trainData); } else { trainData.push_back(features); } trainLabels.push_back(labels[i]); features.delete(); } // 使用 SVM 分类器 this.model = cv.ml.SVM.create(); this.model.setType(cv.ml.SVM_C_SVC); this.model.setKernel(cv.ml.SVM_RBF); this.model.setC(1); this.model.setGamma(0.5); this.model.train(trainData, cv.ml.ROW_SAMPLE, trainLabels); trainData.delete(); trainLabels.delete(); } // 预测图像类别 predict(image) { const features = this.extractFeatures(image); const response = this.model.predict(features); features.delete(); return response; } // 清理 cleanup() { if (this.model) { this.model.clear(); } } }

9. 性能优化建议

  1. 数据预处理:归一化输入数据,提高训练效率
  2. 特征选择:选择最具区分度的特征
  3. 模型选择:根据数据特点选择合适的算法
  4. 交叉验证:使用交叉验证评估模型性能
  5. 参数调优:调整超参数获得最佳性能

总结

OpenCV.js 提供的机器学习功能虽然不如专门的机器学习库(如 TensorFlow.js)强大,但对于许多传统的计算机视觉任务已经足够。在选择使用 OpenCV.js 的机器学习功能时,需要考虑:

  • 任务复杂度:简单分类任务适合,复杂深度学习任务建议使用 TensorFlow.js
  • 性能要求:实时性要求高的任务需要优化算法和数据
  • 数据规模:小规模数据集适合,大规模数据建议使用后端处理
  • 精度要求:高精度要求可能需要更强大的机器学习框架
标签:Opencv.js