OpenCV实践之路——Qt中用opencv提取和匹配SIFT特征点
本文由@星沉閣冰不語出品,轉載請注明作者和出處。
文章鏈接:http://blog.csdn.net/xingchenbingbuyu/article/details/50695399
微博:http://weibo.com/xingchenbing?
SIFT是我本科畢業設計就開始研究的一個算法,也是視覺領域極為經典的一個算法。SIFT算法的實質是在不同的尺度空間上查找關鍵點(特征點),并計算出關鍵點的方向。SIFT所查找到的關鍵點是一些十分突出,不會因光照,仿射變換和噪音等因素而變化的點,如角點、邊緣點、暗區的亮點及亮區的暗點等。?
Lowe將SIFT算法分解為如下四步:1. 尺度空間極值檢測:搜索所有尺度上的圖像位置。通過高斯微分函數來識別潛在的對于尺度和旋轉不變的興趣點。
2. 關鍵點定位:在每個候選的位置上,通過一個擬合精細的模型來確定位置和尺度。關鍵點的選擇依據于它們的穩定程度。
3. 方向確定:基于圖像局部的梯度方向,分配給每個關鍵點位置一個或多個方向。所有后面的對圖像數據的操作都相對于關鍵點的方向、尺度和位置進行變換,從而提供對于這些變換的不變性。
4. 關鍵點描述:在每個關鍵點周圍的鄰域內,在選定的尺度上測量圖像局部的梯度。這些梯度被變換成一種表示,這種表示允許比較大的局部形狀的變形和光照變化。
下面就來在Qt中調用Opencv來簡單實現一下吧。
mainwindow.cpp如下:
#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) {ui->setupUi(this);}MainWindow::~MainWindow() {delete ui; }void MainWindow::on_pushButton_clicked() { //打開一張圖片QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"),".",tr("Image File(*.png *.jpg *.jpeg *.bmp)"));image1 = cv::imread(fileName.toLatin1().data());if(image1.empty()){cout<<"Please open an image!" <<endl;}else{//把Mat轉換成QImagecv::cvtColor(image1,image1,CV_BGR2RGB);QImage img = QImage((const unsigned char*)(image1.data),image1.cols,image1.rows,QImage::Format_RGB888);//在QLabel中顯示圖片ui->label->setPixmap(QPixmap::fromImage(img));ui->label->resize(ui->label->pixmap()->size());} }void MainWindow::on_pushButton_2_clicked() {QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"),".",tr("Image File(*.png *.jpg *.jpeg *.bmp)"));image2 = cv::imread(fileName.toLatin1().data());if(image1.empty()){cout<<"Please open an image!" <<endl;}else{cv::cvtColor(image2,image2,CV_BGR2RGB);QImage img2 = QImage((const unsigned char*)(image2.data),image2.cols,image2.rows,QImage::Format_RGB888);ui->label_2->setPixmap(QPixmap::fromImage(img2));ui->label_2->resize(ui->label_2->pixmap()->size());} }void MainWindow::on_pushButton_3_clicked() {if(image1.empty()){cout<<"Please open an image!" <<endl;}else{ //特征點檢測SiftFeatureDetector featureDetector;featureDetector.detect(image1, image1_kp);//畫出特征點drawKeypoints(image1,image1_kp,image1,Scalar(0,255,0),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);QImage img1 = QImage((const unsigned char*)(image1.data),image1.cols,image1.rows,QImage::Format_RGB888);ui->label->setPixmap(QPixmap::fromImage(img1));ui->label->resize(QSize(img1.width(),img1.height()));}if(image2.empty()){cout<<"Please open an image!" <<endl;}else{SiftFeatureDetector featureDetector;featureDetector.detect(image2, image2_kp);drawKeypoints(image2,image2_kp,image2,Scalar(0,255,0),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);QImage img2 = QImage((const unsigned char*)(image2.data),image2.cols,image2.rows,QImage::Format_RGB888);ui->label_2->setPixmap(QPixmap::fromImage(img2));ui->label_2->resize(QSize(img2.width(),img2.height()));}}void MainWindow::on_pushButton_4_clicked() {Mat image1_desc,image2_desc;//特征點提取SiftDescriptorExtractor featureExtractor;featureExtractor.compute(image1, image1_kp, image1_desc);featureExtractor.compute(image2, image2_kp, image2_desc);//FLANN based descriptor matcher objectFlannBasedMatcher matcher;vector<Mat> image1_desc_collection(1, image1_desc);matcher.add(image1_desc_collection);matcher.train();//match image1 and image2 descriptor,getting 2 nearest neighbors for all test descriptorvector<vector<DMatch> > matches;matcher.knnMatch(image2_desc, matches, 2);//filter for good matches according to Lowe's algorithmvector<DMatch> good_matches;for (unsigned int i = 0; i < matches.size(); i++){if (matches[i][0].distance < 0.6*matches[i][1].distance)good_matches.push_back(matches[i][0]);}Mat img_show;drawMatches(image2, image2_kp, image1, image1_kp, good_matches, img_show);QImage img3 = QImage((const unsigned char*)(img_show.data),img_show.cols,img_show.rows,QImage::Format_RGB888);ui->label->setPixmap(QPixmap::fromImage(img3));ui->label->resize(QSize(img3.width(),img3.height()));ui->label_2->hide(); }
最后效果如下:
這里兩邊選擇了同一張照片,所以所有特征點都匹配了。可以換成相似的或者完全不同的照片看看結果。
值得一提的是
SiftFeatureDetector featureDetector;可以換成
本文由@星沉閣冰不語出品,轉載請注明作者和出處。
文章鏈接:http://blog.csdn.net/xingchenbingbuyu/article/details/51375078
微博:http://weibo.com/xingchenbing?
總結
以上是生活随笔為你收集整理的OpenCV实践之路——Qt中用opencv提取和匹配SIFT特征点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从用户场景来看,什么是推荐系统
- 下一篇: 初中女生学计算机好还是学医好,最好就业的