點擊上方「AI算法與圖像處理」,選擇加"星標"或「置頂」算法
重磅乾貨,第一時間送達微信
來源 OpenCV學堂app
你們好,據說OpenCV4.4 已經把SIFT跟SURF特徵提取又從新get回來了,能夠不須要編譯OpenCV源碼,直接下載官方預編譯版本的就能夠直接使用了。若是你還不知道SIFT特徵是什麼,就看這裏的這篇文章就好啦。
函數
01ui
建立SIFT特徵提取器spa
下面就來驗證一下是否真的能夠了,請看步驟與過程,首先建立SIFT特徵提取器,實現特徵點跟描述子的提取,代碼實現以下:.net
// 建立SIFT特徵提取
auto detector = SIFT::create();
vector<KeyPoint> keypoints_obj, keypoints_sence;
Mat descriptors_box, descriptors_sence;
detector->detectAndCompute(box, Mat(), keypoints_obj, descriptors_box);
detector->detectAndCompute(scene, Mat(), keypoints_sence, descriptors_sence);
std::cout << "box keypoints:" << keypoints_obj.size() << std::endl;
std::cout << "scene keypoints:" << keypoints_sence.size() << std::endl;
運行打印出來的關鍵點數目分別以下:
3d
02code
特徵描述子匹配
從圖像到特徵,是特徵提取關鍵操做,特徵描述子本質上是一系列的向量數據,它能夠惟一表示一張圖像。對類似的特徵進行區域匹配或者搜索,找到高度類似數據特徵片斷是特徵匹配的主要工做。OpenCV中支持兩種特徵匹配方法,分別是暴力匹配與FLANN匹配,對浮點數的特徵描述子,FLANN匹配比暴力會明顯加快運算,建立FLANN實現匹配,並根據類似度排序,尋找最佳匹配得的代碼以下:
// 初始化flann匹配
vector<DMatch> matches;
Ptr<FlannBasedMatcher> matcher = FlannBasedMatcher::create();
matcher->match(descriptors_box, descriptors_sence, matches);
// 發現高質量匹配
std::cout << "total matches:" << matches.size() <<std::endl;
int numOfGood = matches.size() * 0.15;
std::sort(matches.begin(), matches.end());
matches.erase(matches.begin() + numOfGood, matches.end());
std::cout << "good matches:" << matches.size() << std::endl;
Mat dst;
drawMatches(box, keypoints_obj, scene, keypoints_sence, matches, dst);
imshow("output", dst);
imwrite("D:/matches.png", dst);
運行結果以下:
03
單應性矩陣求解與透視變換
對獲得的最佳匹配描述子對,取得對應的圖像關鍵點座標,完成單應性矩陣求解,實現透視變換,是重要的一步,關於單應性矩陣的求解與應用,建議看公衆號以前的幾篇相關文章便可:
這裏再也不贅述,這部分的代碼實現以下:
// 抽取匹配描述子對應的關鍵點
std::vector<Point2f> obj_pts;
std::vector<Point2f> scene_pts;
for (size_t i = 0; i < matches.size(); i++)
{
obj_pts.push_back(keypoints_obj[matches[i].queryIdx].pt);
scene_pts.push_back(keypoints_sence[matches[i].trainIdx].pt);
}
// 對象對齊與單應性矩陣求解
Mat H = findHomography(obj_pts, scene_pts, RANSAC);
std::vector<Point2f> obj_corners(4);
obj_corners[0] = Point(0, 0); obj_corners[1] = Point(box.cols, 0);
obj_corners[2] = Point(box.cols, box.rows); obj_corners[3] = Point(0, box.rows);
std::vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);
04
BOX矩形框繪製
求得最終的位置信息,根據獲得四個點座標經過多邊形繪製函數,完成繪製,這個其中有必要重點解釋一下多邊形繪製函數
void cv::polylines ( InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0)
參數解釋以下
img表示輸入圖像
pts表示繪製的多邊形頂點集合,必須是int類型CV_32SC
isClosed表示是否閉合
color表示多邊形顏色
thickness表示線寬,注意:必須大於等於零,若是想要填充它,請用drawContours
lineType表示對線的渲染方式
shift表示遷移,默認爲0。這個在ROI上繪製時候有用
實現代碼以下:
// 繪製發現的對象
std::vector<Point> pts;
for (int i = 0; i < scene_corners.size(); i++) {
pts.push_back(scene_corners[i]);
}
polylines(scene, pts, true, Scalar(0, 0, 255), 2, 8, 0);
// 顯示匹配對象
imshow("Good Matches & Object detection", scene);
imwrite("D:/findobject.png", scene);
運行結果以下:
此外我還注意到SURF貌似還不能直接使用,是否是仍是要編譯擴展模塊才能夠這個我真的要認真探索一波!歡迎你們留言反饋
下載1 在「AI算法與圖像處理」公衆號後臺回覆:yolov4, 便可下載 YOLOv4 trick相關論文
下載2 在「AI算法與圖像處理」公衆號後臺回覆: DL三件套 ,便可下載包括經典好書
我的微信(若是沒有備註不拉羣!) 請註明: 地區+學校/企業+研究方向+暱稱
本文分享自微信公衆號 - AI算法與圖像處理(AI_study)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。