OpenCV.js 提供了强大的特征检测和描述功能,以下是常用的特征检测方法:
1. 角点检测
Harris 角点检测
javascriptlet 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 边缘检测
javascriptlet edges = new cv.Mat(); cv.Canny(gray, edges, 50, 100, 3, false);
3. 特征点检测
ORB 特征检测
javascriptlet orb = new cv.ORB(); let keypoints = new cv.KeyPointVector(); let descriptors = new cv.Mat(); orb.detectAndCompute(gray, new cv.Mat(), keypoints, descriptors);
SIFT 特征检测(需要额外模块)
javascriptlet sift = cv.SIFT_create(); let keypoints = new cv.KeyPointVector(); let descriptors = new cv.Mat(); sift.detectAndCompute(gray, new cv.Mat(), keypoints, descriptors);
4. 特征匹配
暴力匹配器
javascriptlet matcher = new cv.BFMatcher(cv.NORM_HAMMING, true); let matches = new cv.DMatchVector(); matcher.match(descriptors1, descriptors2, matches);
FLANN 匹配器
javascriptlet matcher = new cv.FlannBasedMatcher(); let matches = new cv.DMatchVector(); matcher.knnMatch(descriptors1, descriptors2, matches, 2);
5. 轮廓检测
javascriptlet 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 直线变换
javascriptlet 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 圆形变换
javascriptlet 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. 完整示例:图像特征匹配
javascriptfunction 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(); } }
性能优化建议
- 图像预处理:先缩放图像再检测特征,提高速度
- 选择合适的检测器:ORB 速度快,SIFT/SURF 精度高但慢
- 限制特征数量:设置合理的特征点数量上限
- 使用 Web Worker:将耗时操作放到后台线程