OpenCV.js 中如何进行特征检测和匹配?
OpenCV.js 中特征检测首选 ORB,因为它是免费的且速度快,通过 new cv.ORB() 创建检测器,调用 detectAndCompute() 同时提取关键点和描述子。特征匹配使用 cv.BFMatcher 配合 cv.NORM_HAMMING 距离(ORB 描述子是二进制的)。注意 SIFT 在 OpenCV.js 中支持有限,需确认编译时是否启用。匹配完成后用 cv.drawMatches() 可视化结果。对于形状检测,cv.findContours() 做轮廓提取,cv.HoughLinesP() 和 cv.HoughCircles() 分别做直线和圆检测。
追问
为什么 OpenCV.js 推荐 ORB 而不是 SIFT? ORB 不受专利限制,计算速度比 SIFT 快一个数量级,且描述子是二进制的,匹配用汉明距离更快。SIFT 在 JS 端性能开销大,且部分 OpenCV.js 构建不包含 SIFT 模块。
BFMatcher 的 crossCheck 参数有什么作用? crossCheck 为 true 时只保留双向匹配一致的对(A匹配B且B也匹配A),能有效过滤误匹配,代价是匹配点数量减少。
FLANN 匹配器在 OpenCV.js 中可用吗? cv.FlannBasedMatcher 在部分版本可用,但因其依赖 FLANN 库的完整构建,部分精简版 OpenCV.js 不包含。实际项目中 BFMatcher 更稳妥。
如何筛选优质匹配点? 对 knnMatch 返回的 k=2 邻近结果计算距离比值(Lowe's ratio test),若最近邻距离 / 次近邻距离 < 0.7 则保留,这是滤除误匹配的标准做法。
轮廓检测前为什么要先做二值化? cv.findContours() 要求输入为 8 位单通道二值图像,非零像素被视为前景。不二值化则轮廓提取结果不可预测,通常先灰度化再 threshold 或 Canny。
写段代码
javascriptlet orb = new cv.ORB(), kp = new cv.KeyPointVector(); let desc = new cv.Mat(); orb.detectAndCompute(gray, new cv.Mat(), kp, desc); let matcher = new cv.BFMatcher(cv.NORM_HAMMING, true); let matches = new cv.DMatchVector(); matcher.match(desc1, desc2, matches); kp.delete(); desc.delete(); matches.delete();