图像拼接的一般步骤
? 最近一直在做視頻實時拼接,然后就一步步來,先做了圖像拼接,然后簡單總結了下圖像拼接的一般步驟。
1.特征點提取
? 主要算法:FAST、ORB、SURF、SIFT等算法。
? SURF受SIFT啟發,比SIFT快,健壯性比較好
? ORB,基于FAST特征點和BREIF特征描述子,比SURF快10倍左右,比SIFT快100倍左右,綜合效果最佳。
? FAST主要做邊角點檢測,速度最快,但是進行特征描述,計算特征向量需要用SURF或者ORB的方法。
? 主要通過以下兩個小的步驟來完成特征點提取的工作。
? ? ?1).特征點描述,計算特征向量
//提取特征點 int minHessian = 700;//設置閾值Ptr<SURF>detector = SURF::create(minHessian);vector<KeyPoint> keyPoint1, keyPoint2;detector->detect(image1, keyPoint1);detector->detect(image2, keyPoint2);//特征點描述,為下邊的特征點匹配做準備 Ptr<SURF>extractor = SURF::create();Mat descriptors1, descriptors2;extractor->compute(image1, keyPoint1, descriptors1);extractor->compute(image2, keyPoint2, descriptors2);? ? ? 2).特征匹配(FlannBasedMatcher/knnMatch)
? ? Opencv提供了兩種匹配方法:BFMatcher和FlannBasedMatcher兩種Matching方式。
? ? 區別在于BFMatcher總是嘗試所有可能的匹配,從而使得它總能夠找到最佳匹配,而FlannBasedMatcher算法更快但是找到的? ? ?是最近鄰近似匹配,所以當我們需要找到一個相對好的匹配但是不需要最佳匹配的時候往往使用FlannBasedMatcher。
? ?BFMatcher有match,knnMatch
? ?FlannBasedMatcher有match,knnMatch,radiusMatch
FlannBasedMatcher matcher;vector<vector<DMatch> > matchePoints;vector<DMatch> GoodMatchePoints;vector<Mat> train_desc(1, descriptors1);matcher.add(train_desc);matcher.train();matcher.knnMatch(descriptors2, matchePoints, 2);? ?然后剔除篩選匹配點,獲取優秀匹配點
// Lowe's algorithm,獲取優秀匹配點for (int i = 0; i < matchePoints.size(); i++){//設置篩選的條件,即匹配點的距離if (matchePoints[i][0].distance < 0.4 * matchePoints[i][1].distance){GoodMatchePoints.push_back(matchePoints[i][0]);}}vector<Point2f> imagePoints1, imagePoints2;for (int i = 0; i<GoodMatchePoints.size(); i++){imagePoints2.push_back(keyPoint2[GoodMatchePoints[i].queryIdx].pt);imagePoints1.push_back(keyPoint1[GoodMatchePoints[i].trainIdx].pt);}2.圖像配準
? ?Findhomography() 單應矩陣:?Method(RANSAC/0/LMEDS/RHO)
? findFundamentalMat() 基礎矩陣:? Method(CV_FM_7POINT/CV_FM_8POINT/CV_FM_RANSAC/CV_FM_LMEDS)
對于一組圖像數據集中的兩幅圖像,通過尋找一種空間變換把一幅圖像映射到另一幅圖像,使得兩圖中對應于空間同一位置的點一一對應起來,從而達到信息融合的目的
//獲取圖像1到圖像2的投影映射矩陣 尺寸為3*3 Mat homo = findHomography(imagePoints1, imagePoints2, CV_RANSAC);也可以使用getPerspectiveTransform方法獲得透視變換矩陣,不過要求只能有4個點,效果稍差 //Mat homo=getPerspectiveTransform(imagePoints1,imagePoints2); cout << "變換矩陣為:\n" << homo << endl << endl; //輸出映射矩陣 CalcCorners(homo, newright, corners2);//圖像配準 //warpPerspective 函數 對圖像進行透視變換,就是變形Mat imageTransform1, imageTransform2;warpPerspective(newright, imageTransform1, homo, Size(MAX(corners2.right_top.x, corners2.right_bottom.x), newleft.rows));imshow("warp", imageTransform1);3.將圖像拷貝到另一幅圖像的特定位置
imageTransform1.copyTo(dst(Rect(0, 0, imageTransform1.cols, imageTransform1.rows)));newleft.copyTo(dst(Rect(0, 0, newleft.cols, newleft.rows)));4.進行圖像融合邊界處理
//優化圖像融合邊界函數 OptimizeSeam(newleft, imageTransform1, dst);總體上,圖像拼接的基本步驟就是這樣。通過做好這幾步,可以完成圖像的一般拼接工作的。如果大家需要圖形拼接示例代碼的話可以評論,看到了會給大家發代碼的。
?
總結
- 上一篇: node-media-server wi
- 下一篇: zabbix yum安装