Episode Six:SIFT算法应用2
来源:互联网 发布:淘宝网非主流女装 编辑:程序博客网 时间:2024/06/05 05:53
通过SIFT算法找到两张图像(图A(染色前),图B(染色后))之间的特征,进行简单筛选之后,进行SIFT特征匹配,得到匹配好的点对。并应用findHomography()函数对图B求出变换矩阵H,应用变换矩阵对图B进行变换,得到和图A相同角度的图C。
code:
///SIFT特征点匹配#include "opencv2/opencv.hpp"#include "opencv2/nonfree/nonfree.hpp"//SIFT相关#include "opencv2/legacy/legacy.hpp"//匹配器相关#include <opencv2/nonfree/features2d.hpp>#include <iostream>using namespace std;using namespace cv;int main(){//1.SIFT特征点提取——detect()方法 Mat srcImg1 = imread("pic/c.jpg", CV_LOAD_IMAGE_COLOR);Mat srcImg2 = imread("pic/d.jpg", CV_LOAD_IMAGE_COLOR);Mat srcImg2_copy = srcImg2;Mat dstImg1, dstImg2;SiftFeatureDetector siftDetector;//SiftFeatureDetector是SIFT类的别名 vector<KeyPoint> keyPoints1;vector<KeyPoint> keyPoints2;siftDetector.detect(srcImg1, keyPoints1);siftDetector.detect(srcImg2, keyPoints2);drawKeypoints(srcImg1, keyPoints1, dstImg1);drawKeypoints(srcImg2, keyPoints2, dstImg2);imshow("dstImg1", dstImg1);imshow("dstImg2", dstImg2);//2.特征点描述符(特征向量)提取——compute()方法 SiftDescriptorExtractor descriptor;//SiftDescriptorExtractor是SIFT类的别名 Mat description1;Mat description2;descriptor.compute(srcImg1, keyPoints1, description1);//注意原图和特征点要对应,不要写错 descriptor.compute(srcImg2, keyPoints2, description2);imshow("description1", description1);imshow("description2", description2);//3.使用暴力匹配器进行暴力匹配——BruteForceMatcher类的match()方法 BruteForceMatcher<L2<float>> matcher;//实例化暴力匹配器 vector<DMatch> matches; //定义匹配结果变量 matcher.match(description1, description2, matches);//实现描述符之间的匹配 //4.对匹配结果进行筛选(依据DMatch结构体中的float类型变量distance进行筛选) float minDistance = 100;float maxDistance = 0;for (int i = 0; i < matches.size(); i++){if (matches[i].distance < minDistance)minDistance = matches[i].distance;if (matches[i].distance > maxDistance)maxDistance = matches[i].distance;}cout << "minDistance: " << minDistance << endl;cout << "maxDistance: " << maxDistance << endl;vector<DMatch> goodMatches;for (int i = 0; i < matches.size(); i++){if (matches[i].distance < 3 * minDistance){goodMatches.push_back(matches[i]);}}//5.绘制匹配结果——drawMatches() Mat dstImg3;drawMatches(srcImg1, keyPoints1, srcImg2, keyPoints2, goodMatches, dstImg3);namedWindow("dstImg3", WINDOW_NORMAL);//为防止图像太大,屏幕显示不下,采用可以手动拉伸的方法;或者可以采用提前把图片缩小的方法imshow("dstImg3", dstImg3);vector<Point2f> obj;vector<Point2f> scene;for (int i = 0; i < goodMatches.size(); i++){obj.push_back(keyPoints1[goodMatches[i].queryIdx].pt);scene.push_back(keyPoints2[goodMatches[i].trainIdx].pt);}/*//计算原图像和目的图像之间的Homography //用粗线标出要检测的物体Mat H = findHomography(obj , scene, CV_RANSAC);vector<Point2f>obj_corners(4);obj_corners[0] = cvPoint(0, 0);obj_corners[1] = cvPoint(srcImg1.cols, 0);obj_corners[2] = cvPoint(srcImg1.cols, srcImg1.rows);obj_corners[3] = cvPoint(0, srcImg1.rows);vector<Point2f>scene_corners(4);perspectiveTransform(obj_corners, scene_corners, H);line(dstImg3, scene_corners[0] + Point2f(static_cast<float>(srcImg1.cols), 0), scene_corners[1] + Point2f(static_cast<float>(srcImg1.cols), 0), Scalar(255, 0, 123), 4);line(dstImg3, scene_corners[1] + Point2f(static_cast<float>(srcImg1.cols), 0), scene_corners[2] + Point2f(static_cast<float>(srcImg1.cols), 0), Scalar(255, 0, 123), 4);line(dstImg3, scene_corners[2] + Point2f(static_cast<float>(srcImg1.cols), 0), scene_corners[3] + Point2f(static_cast<float>(srcImg1.cols), 0), Scalar(255, 0, 123), 4);line(dstImg3, scene_corners[3] + Point2f(static_cast<float>(srcImg1.cols), 0), scene_corners[0] + Point2f(static_cast<float>(srcImg1.cols), 0), Scalar(255, 0, 123), 4);namedWindow("lalal",WINDOW_NORMAL);imshow("lalal", dstImg3);*/Mat H = findHomography(scene,obj,CV_RANSAC);Mat srcImg3;//Size size(500, 500);//原图像变形 warpPerspective(srcImg2_copy, srcImg3, H, srcImg2_copy.size());namedWindow("2", WINDOW_NORMAL);imshow("2", srcImg2_copy);namedWindow("3",WINDOW_NORMAL);imshow("3", srcImg3);waitKey(0);return 0;}
Smart is the new sexy!
阅读全文
0 0
- Episode Six:SIFT算法应用2
- Episode Four:SIFT算法应用1
- Episode Seven:从SIFT算法到dense SIFT算法
- sift算法详解及应用
- SIFT算法详解与应用
- SIFT算法2
- sift算法2
- SIFT算法学习(2)
- sift算法
- SIFT算法
- sift算法
- SIFT 算法
- sift算法
- SIFT算法
- SIFT 算法
- SIFT算法
- SIFT算法
- SIFT算法
- linux定时任务
- stomp.min.js(stomp协议的客户端脚本)、sockjs.min.js(SockJS的客户端脚本)以及jQuery
- 编译的坑_1
- AMD/CMD/CommonJs的区别与使用
- openpyxl 处理 excel 文档学习之workbook及worksheet学习
- Episode Six:SIFT算法应用2
- 多线程例子:join
- Train_1:按钮组件
- 完成一个进度条的定义
- JSP和Servlet简单登陆页面
- lambda expressions are not supported at this language level解决方法
- 文档摘要平台---PKUSUMSUM
- mongodb 读写分离
- 互联网轻量级框架简介