calibration後續
我又試了兩組不同焦距的校正影像,而各自組的校正誤差都有些許不同
焦距變化蠻大的,但再投影誤差都在1附近。
而同一組相機參數,不同組影像也會校正出不同焦距,
推測應該是函式優化收斂的地方,可能落入局部最佳,
但是在自訂相機參數的情況下,再投影誤差都穩定在2以下,
此模式獲得的影像應該相對有較高的可信度。
接下來就是定位專案的開發,
接著前面的作業,我想讓讀入的影像以vector的形式儲存,
同樣的Keypoints 跟 descript也是
在型別的部分
std::vector<cv::Mat>descript_img;
std::vector<std::vector<cv::KeyPoint>>list_of_keypoints;
原先的一組影像的descript就是以一個mat儲存,
因此在讀入影像的時候就接著將影像丟入偵測子運算
並將其結果塞入vector儲存
for (size_t i = 0; i < imagelist.size(); i++)
{
cv::Mat result;
result = cv::imread(imagelist[i], cv::IMREAD_COLOR);
cv::resize(result, result, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
std::vector<cv::KeyPoint>tmp_keypoints;
cv::Mat tmp_descript;
detector->detectAndCompute(result, cv::noArray(), tmp_keypoints, tmp_descript);
descript_img.push_back(tmp_descript);
list_of_keypoints.push_back(tmp_keypoints);
}
而在影像定位的時候,輸入的影像是連續影像還是不連續影像會有不同的處理流程,
通常輸入的影像都會是有序的,
而在無序的情況下要先對影像的匹配結果做排序,比較相似的影像其成功匹配的數量也會比較高。
這邊暫時以無序的基本流程做開發,但如果你確定你輸入的影像是連續的,
基本上只要匹配相鄰的兩張相片的匹配情況,
所以假設我輸入的影像有6張
我的第1張照片會依序跟2~6張做匹配,
第2張照片會跟3~6張做匹配,
依此類推,
直到第4張照片跟第5張照片匹配結束。
cv::Ptr < cv::BFMatcher> match_description = cv::BFMatcher::create(cv::NORM_L2, false);
const float ratio_thresh = 0.7f;
std::vector<std::vector<std::vector<cv::DMatch>>> ALL_good_matches;
for (size_t i = 0; i < imagelist.size()-1; i++)
{
std::vector<std::vector<cv::DMatch>>tmp_ith_img_match;
for (size_t j = i+1; j < imagelist.size(); j++)
{
std::vector < std::vector< cv::DMatch >> knn_match_result;
match_description->knnMatch(descript_img[i], descript_img[j], knn_match_result, 2);
std::vector<cv::DMatch> good_matches;
for (size_t k = 0; k < knn_match_result.size(); k++)
{
if (knn_match_result[k][0].distance < ratio_thresh * knn_match_result[k][1].distance)
{
good_matches.push_back(knn_match_result[k][0]);
}
}
tmp_ith_img_match.push_back(good_matches);
std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << good_matches.size() << std::endl;
}
ALL_good_matches.push_back(tmp_ith_img_match);
}
而每組的匹配的結果會先做一次ratio_test過濾,未來也可以做其他過濾方法,
std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << good_matches.size() << std::endl;
我在這邊先輸出各組匹配的影像id跟影像之間的匹配數量。
為了驗證結果之後為將匹配結果以drawMatches的方式表現出來。
for (size_t i = 0; i < imagelist.size() - 1; i++)
{
int count = 0;
for (size_t j = i+1; j < imagelist.size(); j++)
{
cv::Mat imgL,imgR;
imgL = cv::imread(imagelist[i], cv::IMREAD_COLOR);
cv::resize(imgL, imgL, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
imgR = cv::imread(imagelist[j], cv::IMREAD_COLOR);
cv::resize(imgR, imgR, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
cv::Mat img_Match_Knn_ratio;
if (ALL_good_matches[i][count].empty()) {
continue;
}
std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << ALL_good_matches[i][count].size() << std::endl;
cv::drawMatches(imgL, list_of_keypoints[i], imgR, list_of_keypoints[j], ALL_good_matches[i][count], img_Match_Knn_ratio, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
cv::imshow("img_Match_Knn_ratio", img_Match_Knn_ratio);
cv::waitKey();
count++;
}
}
std::vector<std::vector<std::vector<cv::DMatch>>> ALL_good_matches;
這邊我還沒想號ALL_good_matches的資料型別,感覺應該還有其他比較適合的儲存型態,
第一層我放的是左邊image的id第二層則是右邊image的id
如果是六張影像的情況
第1層會是0~5其對應的第二層的size()應該會是5,4,3,2,1。