QT+opencv
我推荐以下文章,他们都写得很详细:
- 只有qt+opencv:
https://blog.csdn.net/sinat_36264666/article/details/73200739 - 包含了opencv_contrib:
https://blog.csdn.net/xiaonuo911teamo/article/details/79934319
要使用SIFT算法,需要用到opencv_contrib。建议看第二篇,一步到位。
如果不想去下载cmake编译那么麻烦的话,可以直接去下载我已经编译好的文件:
https://download.csdn.net/download/qq_41544842/14934196
SIFT
- 头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <QString>
#include <QFileDialog>
#include <QLabel>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/core/types.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/features2d.hpp>
#include <vector>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
Mat image1,image2;
vector<KeyPoint>keyPoints1;
vector<KeyPoint>keyPoints2;
};
#endif // MAINWINDOW_H
- 打开图片1(图片2同理)
void MainWindow::on_pushButton_clicked()
{
QString fileName=QFileDialog::getOpenFileName(this,tr("Open Image"),tr(""));
image1=cv::imread(fileName.toLatin1().data());
cv::cvtColor(image1,image1,CV_BGR2RGB);
QImage img=QImage((const unsigned char*)(image1.data),image1.cols,image1.rows,QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(img));
ui->label->resize(ui->label->pixmap()->size());
}
- 画出特征点
void MainWindow::on_pushButton_3_clicked()
{
//SiftFeatureDetector siftDetector;
Ptr<xfeatures2d::SiftFeatureDetector> siftDetector = xfeatures2d::SiftFeatureDetector::create();
siftDetector->detect(image1,keyPoints1);
siftDetector->detect(image2,keyPoints2);
drawKeypoints(image1,keyPoints1,image1,Scalar(0, 0, 255));
drawKeypoints(image2,keyPoints2,image2,Scalar(0, 0, 255));
QImage img1=QImage((const unsigned char*)(image1.data),image1.cols,image1.rows,QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(img1));
ui->label->resize(ui->label->pixmap()->size());
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_4_clicked()
{
Mat image1_desc,image2_desc;
//SiftDescriptorExtractor featureExtractor;
Ptr<xfeatures2d::SiftDescriptorExtractor> featureExtractor = xfeatures2d::SiftDescriptorExtractor::create();
featureExtractor->compute(image1,keyPoints1,image1_desc);
featureExtractor->compute(image2,keyPoints2,image2_desc);
FlannBasedMatcher matcher;
vector<Mat> image1_desc_collection(1,image1_desc);
matcher.add(image1_desc_collection);
matcher.train();
vector<vector<DMatch>> matches;
matcher.knnMatch(image2_desc,matches,2);
vector<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,keyPoints2,image1,keyPoints1,good_matches,img_show);
QImage img=QImage((const unsigned char*)(img_show.data),img_show.cols,img_show.rows,QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(img));
ui->label->resize(ui->label->pixmap()->size());
ui->label_2->hide();
}
- 效果
我这里用的是一模一样的图片,所以效果很好。