无人机图像中单点(角点)跟踪技术优化方案问询
无人机图像单角点跟踪问题
我正尝试在无人机(UAV)图像中跟踪单个角点,已知该点的粗略初始位置(与真实值偏差约30像素)。下图展示了基于初始位置获取的ROI,黄色标记为跟踪点,即便在简单场景下仍存在较多误差。
需求
- 处理速度需快于人工操作,越快越好;
- 无需返回全部100张图像的结果,仅需25-30张的结果,但需尽可能精准;
- 适配无人机图像特性:噪声、大旋转与平移等仿射变换。
现有思路
- 选取参考图像,手动选择角点作为跟踪点并提取特征描述子;
- 遍历所有图像:
- 以初始位置为中心获取ROI;
- 在ROI内进行角点检测并计算描述子;
- 将描述子与参考点描述子匹配,最相似的即为跟踪点。
实验情况
尝试OpenCV的ORB检测器搭配BFMatcher未获理想结果;采用SuperGlue提及的optimal transport匹配,因“dustbin”初始值与lambda参数问题效果一般;更换CSS、Phase Congruency等角点检测器也未改善。
疑问
- 该问题的正确研究方向是什么?
- 若初始点偏差达200像素,如何实现精准跟踪?
尝试方案
- ORB检测器/描述子 + BFMatcher
- ORB检测器/描述子 + Optimal Transport Match
void optimalTransportMatch(const cv::Mat &descriptors1, const cv::Mat &descriptors2, cv::Mat &matchMatrix) { //0.prepare int matchRows = descriptors1.rows + 1; int matchCols = descriptors2.rows + 1; matchMatrix = cv::Mat(matchRows, matchCols, CV_64FC1); cv::Mat costMatrix = cv::Mat(matchRows, matchCols, CV_64FC1); double binValue = 128*7; double lambda = 0.2; for (int i = 0; i < matchRows; i++) { for (int j = 0; j < matchCols; j++) { //last row if (i == matchRows - 1 && j != matchCols - 1) { double cost = binValue; //maybe change costMatrix.at<double>(i, j) = cost; //cost matchMatrix.at<double>(i, j) = exp(-lambda * cost); //initial value continue; } //last col if(j == matchCols - 1 && i!= matchRows - 1) { double cost = binValue; //maybe change costMatrix.at<double>(i, j) = cost; matchMatrix.at<double>(i, j) = exp(-lambda * cost); continue; } //binToBin if(i == matchRows - 1 && j == matchCols - 1) { double cost = binValue; //maybe change costMatrix.at<double>(i, j) = cost; matchMatrix.at<double>(i, j) = exp(-lambda * cost); continue; } //cost/match matrix cv::Mat descriptor1 = descriptors1.row(i); cv::Mat descriptor2 = descriptors2.row(j); double cost = cv::norm(descriptor1, descriptor2, cv::NORM_L2); costMatrix.at<double>(i, j) = cost; matchMatrix.at<double>(i, j) = exp(-lambda * cost); } } //1.Sinkhorn-Knopp algorithm double distEpsilon = 1e-8, iterMaxDist; int iterNum = 0; cv::Mat colsSumNext, colsSumCurrent, colsSumDiff, rowsSum; cv::Mat stdColsSum = cv::Mat::ones(matchRows, 1, CV_64FC1); cv::Mat stdRowsSum = cv::Mat::ones(1, matchCols, CV_64FC1); stdColsSum.at<double>(matchRows - 1, 0) = matchCols - 1; stdRowsSum.at<double>(0,matchCols - 1) = matchRows - 1; colsSumNext = cv::Mat::zeros(matchRows, 1, CV_64FC1); cv::reduce(matchMatrix, colsSumCurrent, 1, cv::REDUCE_SUM, CV_64FC1); colsSumDiff =cv::abs(colsSumCurrent - colsSumNext); cv::minMaxLoc(colsSumDiff, NULL, &iterMaxDist); while (iterMaxDist > distEpsilon || iterNum < 10) { iterNum++; cv::Mat rowsScale, colsScale; //scale rows cv::reduce(matchMatrix, colsSumNext, 1, cv::REDUCE_SUM, CV_64FC1); cv::divide(stdColsSum, colsSumNext, rowsScale); rowsScale = cv::repeat(rowsScale, 1, matchCols); cv::multiply(matchMatrix, rowsScale, matchMatrix); //scale cols cv::reduce(matchMatrix, rowsSum, 0, cv::REDUCE_SUM, CV_64FC1); cv::divide(stdRowsSum, rowsSum, colsScale); colsScale = cv::repeat(colsScale, matchRows, 1); cv::multiply(matchMatrix, colsScale, matchMatrix); //condition cv::reduce(matchMatrix, colsSumCurrent, 1, cv::REDUCE_SUM, CV_64FC1); colsSumDiff = cv::abs(colsSumCurrent - colsSumNext); cv::minMaxLoc(colsSumDiff, NULL, &iterMaxDist); } }
补充说明
本问题为无人机图像非标准化地面控制点(多为道路标志角点)的自动检测,现有文献方法在重投影误差大或场景复杂时失效。
参考文献
- [1] P.-E. Sarlin, D. DeTone, T. Malisiewicz, and A. Rabinovich, 《SuperGlue: Learning Feature Matching With Graph Neural Networks》, 2020 IEEE/CVF计算机视觉与模式识别会议(CVPR), 2020年6月, 第4937–4946页.
- [2] Z. Zhu, T. Bao, Y. Hu, and J. Gong, 《A Novel Method for Fast Positioning of Non-Standardized Ground Control Points in Drone Images》, Remote Sensing, 第13卷, 第15期, 2021年1月, doi: 10.3390/rs13152849.
内容的提问来源于stack exchange,提问作者Stoner Ling
相关产品推荐
相关产品推荐

