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

OpenCV.js 中如何进行特征检测和匹配?

3月6日 21:36

OpenCV.js 提供了强大的特征检测和描述功能,以下是常用的特征检测方法:

1. 角点检测

Harris 角点检测

javascript
let src = cv.imread('canvasInput'); let gray = new cv.Mat(); cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY); let corners = new cv.Mat(); let qualityLevel = 0.01; let minDistance = 10; let blockSize = 3; let k = 0.04; cv.goodFeaturesToTrack(gray, corners, 100, qualityLevel, minDistance, new cv.Mat(), blockSize, false, k);

2. 边缘检测

Canny 边缘检测

javascript
let edges = new cv.Mat(); cv.Canny(gray, edges, 50, 100, 3, false);

3. 特征点检测

ORB 特征检测

javascript
let orb = new cv.ORB(); let keypoints = new cv.KeyPointVector(); let descriptors = new cv.Mat(); orb.detectAndCompute(gray, new cv.Mat(), keypoints, descriptors);

SIFT 特征检测(需要额外模块)

javascript
let sift = cv.SIFT_create(); let keypoints = new cv.KeyPointVector(); let descriptors = new cv.Mat(); sift.detectAndCompute(gray, new cv.Mat(), keypoints, descriptors);

4. 特征匹配

暴力匹配器

javascript
let matcher = new cv.BFMatcher(cv.NORM_HAMMING, true); let matches = new cv.DMatchVector(); matcher.match(descriptors1, descriptors2, matches);

FLANN 匹配器

javascript
let matcher = new cv.FlannBasedMatcher(); let matches = new cv.DMatchVector(); matcher.knnMatch(descriptors1, descriptors2, matches, 2);

5. 轮廓检测

javascript
let contours = new cv.MatVector(); let hierarchy = new cv.Mat(); cv.findContours(binaryImage, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE); // 绘制轮廓 let drawing = src.clone(); cv.drawContours(drawing, contours, -1, new cv.Scalar(0, 255, 0), 2);

6. 直线检测

Hough 直线变换

javascript
let lines = new cv.Mat(); cv.HoughLinesP(edges, lines, 1, Math.PI / 180, 50, 50, 10); for (let i = 0; i < lines.rows; ++i) { let startPoint = new cv.Point(lines.data32S[i * 4], lines.data32S[i * 4 + 1]); let endPoint = new cv.Point(lines.data32S[i * 4 + 2], lines.data32S[i * 4 + 3]); cv.line(src, startPoint, endPoint, new cv.Scalar(0, 0, 255), 2); }

7. 圆形检测

Hough 圆形变换

javascript
let circles = new cv.Mat(); cv.HoughCircles(gray, circles, cv.HOUGH_GRADIENT, 1, 60, 30, 50, 0, 0); for (let i = 0; i < circles.cols; ++i) { let x = circles.data32F[i * 3]; let y = circles.data32F[i * 3 + 1]; let radius = circles.data32F[i * 3 + 2]; let center = new cv.Point(x, y); cv.circle(src, center, radius, new cv.Scalar(0, 255, 0), 2); }

8. 完整示例:图像特征匹配

javascript
function matchFeatures(img1, img2) { let gray1 = new cv.Mat(); let gray2 = new cv.Mat(); let keypoints1 = new cv.KeyPointVector(); let keypoints2 = new cv.KeyPointVector(); let descriptors1 = new cv.Mat(); let descriptors2 = new cv.Mat(); let matches = new cv.DMatchVector(); try { // 转灰度 cv.cvtColor(img1, gray1, cv.COLOR_RGBA2GRAY); cv.cvtColor(img2, gray2, cv.COLOR_RGBA2GRAY); // ORB 特征检测 let orb = new cv.ORB(); orb.detectAndCompute(gray1, new cv.Mat(), keypoints1, descriptors1); orb.detectAndCompute(gray2, new cv.Mat(), keypoints2, descriptors2); // 特征匹配 let matcher = new cv.BFMatcher(cv.NORM_HAMMING, true); matcher.match(descriptors1, descriptors2, matches); // 绘制匹配结果 let result = new cv.Mat(); cv.drawMatches(img1, keypoints1, img2, keypoints2, matches, result); cv.imshow('canvasOutput', result); } finally { gray1.delete(); gray2.delete(); descriptors1.delete(); descriptors2.delete(); matches.delete(); } }

性能优化建议

  1. 图像预处理:先缩放图像再检测特征,提高速度
  2. 选择合适的检测器:ORB 速度快,SIFT/SURF 精度高但慢
  3. 限制特征数量:设置合理的特征点数量上限
  4. 使用 Web Worker:将耗时操作放到后台线程
标签:Opencv.js