1.Qt安装opencv网上教程很多,不在重复。贴个地址
2. 试验的方法都是网上找的一些算法进行测试。有用的请自取
3. 原本是想弄从判断某个游戏是否在某个界面上,奈何这些算法实现好像有点出入
.pro 文件设置
OPENCV_SDK_DIR 为系统设置的安装完的opencv 路径
我的路径如下图,自己的路径自己修改
INCLUDEPATH += $$(OPENCV_SDK_DIR)/include
LIBS += -L$$(OPENCV_SDK_DIR)/x64/mingw/lib\
-lopencv_core411 \
-lopencv_highgui411 \
-lopencv_imgcodecs411 \
-lopencv_imgproc411 \
-lopencv_features2d411 \
-lopencv_calib3d411 \
-lopencv_xfeatures2d411
mainwindow.cpp的 代码如下
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString fileName,fileName2;
fileName = QCoreApplication::applicationDirPath();
fileName+="/images/";
fileName+="1.jpg";
fileName2 = QCoreApplication::applicationDirPath();
fileName2+="/images/";
fileName2+="2.jpg";
Mat image = imread(fileName.toStdString());
Mat image2 = imread(fileName2.toStdString());
//新建一个窗口,显示该图片
//imshow("My Image", image);
//double ok =getPSNR(image,image2);
// qDebug()<
// if(ok){
// qDebug()<<"一样";
// }else{
// qDebug()<<"不一样";
// }
}
bool MainWindow::matIsEqual(const cv::Mat mat1, const cv::Mat mat2) {
if (mat1.empty() && mat2.empty()) {
return true;
}
if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims||
mat1.channels()!=mat2.channels()) {
return false;
}
if (mat1.size() != mat2.size() || mat1.channels() != mat2.channels() || mat1.type() != mat2.type()) {
return false;
}
int nrOfElements1 = mat1.total()*mat1.elemSize();
if (nrOfElements1 != mat2.total()*mat2.elemSize()) return false;
bool lvRet = memcmp(mat1.data, mat2.data, nrOfElements1) == 0;
return lvRet;
}
double MainWindow::getPSNR(Mat matSrc1,Mat matSrc2)
{
Mat matDst1, matDst2;
// 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异;
cv::resize(matSrc1, matDst1, Size(8, 8));
cv::resize(matSrc2, matDst2, Size(8, 8));
//灰度化
//cvtColor(matSrc1, matDst1, CV_BGR2GRAY);
//cvtColor(matSrc2, matDst2, CV_BGR2GRAY);
cvtColor(matDst1, matDst1, CV_BGR2GRAY);
cvtColor(matDst2, matDst2, CV_BGR2GRAY);
//threshold(matDst1, matDst1, 100, 255, CV_THRESH_BINARY);
// threshold(matDst2, matDst2, 100, 255, CV_THRESH_BINARY);
imshow("Keypoints1", matDst1);
imshow("Keypoints2", matDst2);
int iAvg1 = 0, iAvg2 = 0;
int arr1[64], arr2[64];
for (int i = 0; i < 8; i++) {
//位置是第i行的头指针
uchar* data1 = matDst1.ptr<uchar>(i);
uchar* data2 = matDst2.ptr<uchar>(i);
int tmp = i * 8;
for (int j = 0; j < 8; j++) {
int tmp1 = tmp + j;
arr1[tmp1] = data1[j] / 4 ;
arr2[tmp1] = data2[j] / 4 ;
iAvg1 += arr1[tmp1];
iAvg2 += arr2[tmp1];
}
}
iAvg1 /= 64;
iAvg2 /= 64;
for (int i = 0; i < 64; i++) {
arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
}
int iDiffNum = 0;
for (int i = 0; i < 64; i++)
if (arr1[i] != arr2[i])
++iDiffNum;
return iDiffNum;
}
int MainWindow::getORB(Mat rgbd1,Mat rgbd2){
// Mat rgbd1 = imread("自己的图片Path");
// Mat rgbd2 = imread("自己的图片Path");
// Mat rgbd1 = imread(imagePatha);
// Mat rgbd2 = imread(imagePathb);
if (!rgbd1.data || !rgbd2.data)
{
cout << "error reading images " << endl; return -1;
}
Ptr<ORB> orb = ORB::create();
vector<KeyPoint> Keypoints1,Keypoints2;
Mat descriptors1,descriptors2;
orb->detectAndCompute(rgbd1, Mat(), Keypoints1, descriptors1);
orb->detectAndCompute(rgbd2, Mat(), Keypoints2, descriptors2);
//cout << "Key points of image" << Keypoints.size() << endl;
//可视化,显示关键点
Mat ShowKeypoints1, ShowKeypoints2;
drawKeypoints(rgbd1,Keypoints1,ShowKeypoints1);
drawKeypoints(rgbd2, Keypoints2, ShowKeypoints2);
imshow("Keypoints1", ShowKeypoints1);
imshow("Keypoints2", ShowKeypoints2);
waitKey(0);
//Matching
vector<DMatch> matches;
Ptr<DescriptorMatcher> matcher =DescriptorMatcher::create("BruteForce");
matcher->match(descriptors1, descriptors2, matches);
qDebug() << "find out total " << matches.size() << " matches" << endl;
//可视化
Mat ShowMatches;
drawMatches(rgbd1,Keypoints1,rgbd2,Keypoints2,matches,ShowMatches);
imshow("matches", ShowMatches);
waitKey(0);
return 0;
}
void MainWindow::imgSIFT(Mat img_1,Mat img_2)//SIFT算法
{
//sift算法不是开源的所以很多内容用起来很不方便
//Create SIFT class pointer
Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
//1、读入图片
// Mat img_1 = imread("D:/ImageTest/source.png");//模板图片
// Mat img_2 = imread("D:/ImageTest/222.JPG");//检测图片
//2、声明检测点;Detect the keypoints
vector<KeyPoint> keypoints_1, keypoints_2;
f2d->detect(img_1, keypoints_1);
f2d->detect(img_2, keypoints_2);
//3、计算描述符(特征向量);Calculate descriptors (feature vectors)
Mat descriptors_1, descriptors_2;
f2d->compute(img_1, keypoints_1, descriptors_1);
f2d->compute(img_2, keypoints_2, descriptors_2);
//4、使用BFMatcher匹配描述符向量;Matching descriptor vector using BFMatcher
BFMatcher matcher;
vector<DMatch> matches;
matcher.match(descriptors_1, descriptors_2, matches);
//5、绘制匹配出的关键点
Mat img_matches;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches);
imshow("match",img_matches);
//6、匹配结果筛选
nth_element(matches.begin(), matches.begin()+30, matches.end()); //提取出前最佳匹配结果
matches.erase(matches.begin()+30, matches.end()); //剔除掉其余的匹配结果
Mat img_matches2;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches2);
imshow("match2",img_matches2);
waitKey(0);
}
// Surf 特征检测与匹配:
int MainWindow::Surf(Mat img_1,Mat img_2)
{
//1、加载图片
// Mat img_1 = imread( "D:/ImageTest/source.png", IMREAD_GRAYSCALE );//模板图片
// Mat img_2 = imread("D:/ImageTest/222.JPG", IMREAD_GRAYSCALE );//被查找图片
//2、使用SURF检测器检测关键点,计算描述符;Detect the keypoints using SURF Detector, compute the descriptors
int minHessian = 400;
Ptr<Feature2D> detector = xfeatures2d::SURF::create();
// detector.setHessianThreshold(minHessian);
// detector.reset(minHessian);
std::vector<KeyPoint> keypoints_1, keypoints_2;
Mat descriptors_1, descriptors_2;
detector->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1 );
detector->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2 );
//3、匹配描述符向量与一个蛮力匹配;Matching descriptor vectors with a brute force matcher
BFMatcher matcher(NORM_L2);
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );
//4、绘制匹配结果;Draw matches
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2, matches, img_matches );
//5、显示检测到匹配; Show detected matches
imshow("SURF_Matches", img_matches );
//6、匹配结果筛选
nth_element(matches.begin(), matches.begin()+50, matches.end()); //提取出前最佳匹配结果
matches.erase(matches.begin()+50, matches.end()); //剔除掉其余的匹配结果
Mat img_matches2;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches2);
imshow("SURF_Matches2",img_matches2);
waitKey(0);
}
//滑动条回调函数
void MatchingMethod( int, void* )
{
// 将被显示的原图像
#if 0
Mat img_display;
img.copyTo( img_display );
//cvtColor(img_display,img_display,CV_GRAY2BGR);
// 创建输出结果的矩阵
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
// 进行匹配和标准化
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
// 通过函数 minMaxLoc 定位最匹配的位置
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
// 对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值代表更高的匹配结果. 而对于其他方法, 数值越大匹配越好
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }
//cvtColor(result,result,CV_GRAY2BGR);
// 绘制匹配结果
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
imshow( image_window, img_display );
imshow( result_window, result );
#endif
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked(bool checked)
{
QString filename = QFileDialog::getOpenFileName(this,
tr("选择图片"),
"",
tr("Images(*.png *.bmp *.jpg *.tif *.GIF)"));
if (filename.isEmpty())
{
return;
}
else
{
string str = filename.toStdString(); // 将filename转变为string类型;
image_1 = imread(str);
cvtColor(image_1, image_1, CV_BGR2RGB);
cv::resize(image_1, image_1, Size(300, 200));
QImage img_1 = QImage((const unsigned char*)(image_1.data), image_1.cols, image_1.rows, QImage::Format_RGB888);
label_1 = new QLabel();
label_1->setPixmap(QPixmap::fromImage(img_1));
label_1->resize(QSize(img_1.width(), img_1.height()));
ui->Picture1->setWidget(label_1);
//ui->Picture1->setWidget(label_1);
//ui->tableWidget.setWidget(label_1);
}
}
void MainWindow::on_pushButton_2_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,
tr("选择图片"),
"",
tr("Images(*.png *.bmp *.jpg *.tif *.GIF)"));
if (filename.isEmpty())
{
return;
}
else
{
string str = filename.toStdString(); // 将filename转变为string类型;
image_2 = imread(str);
//image=imread(fileName.toLatin1().data);
cvtColor(image_2, image_2, CV_BGR2RGB);
cv::resize(image_2, image_2, Size(300, 200));
QImage img_1 = QImage((const unsigned char*)(image_2.data), image_2.cols, image_2.rows, QImage::Format_RGB888);
label_1 = new QLabel();
label_1->setPixmap(QPixmap::fromImage(img_1));
label_1->resize(QSize(img_1.width(), img_1.height()));
ui->Picture2->setWidget(label_1);
}
}
void MainWindow::on_pushButton_3_clicked()
{
//progress *pro;
QString panduan;
int den=((getPSNR(image_1, image_2)));
if (den <= 5)
{
panduan = "They are too similar!";
}
else if (den > 10)
{
panduan = "They are two different pictures!";
}
else
{
panduan = "They are a litter similar.";
}
den = 100 - den;
QString str = QString::number(den);
QString buf = "相似度为: " + str +"% 我的判断为: " + panduan;
ui->Similar_text->setText(buf);
}
void MainWindow::on_pushButton_4_clicked()
{
QString panduan;
int den=((getORB(image_1, image_2)));
if (den <= 5)
{
panduan = "They are too similar!";
}
else if (den > 10)
{
panduan = "They are two different pictures!";
}
else
{
panduan = "They are a litter similar.";
}
den = 100 - den;
QString str = QString::number(den);
QString buf = "相似度为: " + str +"% 我的判断为: " + panduan;
ui->Similar_text->setText(buf);
}
void MainWindow::on_pushButton_5_clicked()
{
imgSIFT(image_1, image_2);
}
#if 0
/*Method
0: SQDIFF 平方差匹配
1: SQDIFF NORMED 标准平方差匹配
2: TM CCORR 相关匹配
3: TM CCORR NORMED 标准相关匹配
4: TM COEFF 相关匹配
5: TM COEFF NORMED" 标准相关匹配
*/
//滑动条回调函数
void MainWindow::MatchingMethod( int, void* )
{
// 将被显示的原图像
Mat img_display;
image_1.copyTo( img_display );
//cvtColor(img_display,img_display,CV_GRAY2BGR);
// 创建输出结果的矩阵
int result_cols = image_1.cols - templ.cols + 1;
int result_rows = image_1.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
// 进行匹配和标准化
matchTemplate( image_1, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
// 通过函数 minMaxLoc 定位最匹配的位置
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
// 对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值代表更高的匹配结果. 而对于其他方法, 数值越大匹配越好
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }
//cvtColor(result,result,CV_GRAY2BGR);
// 绘制匹配结果
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
imshow( image_window, img_display );
imshow( result_window, result );
}
#endif
void MainWindow::on_pushButton_6_clicked()
{
Surf(image_1, image_2);
}
mainwindow.h 的代码如下
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include //graphicsview类
#include
#include // Basic OpenCV structures
#include // Image processing methods for the CPU
#include // Read images
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2);
double getPSNR(Mat matSrc1,Mat matSrc2);
int getORB(Mat rgbd1,Mat rgbd2);
void imgSIFT(Mat img_1,Mat img_2);//SIFT算法
int Surf(Mat img_1,Mat img_2);
void MatchingMethod( int, void* );
private slots:
void on_pushButton_clicked(bool checked);
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void on_pushButton_5_clicked();
void on_pushButton_6_clicked();
private:
Ui::MainWindow *ui;
cv::Mat image_1,image_2,image1_kp,image2_kp; //图像
QLabel *label_1;
QLabel *label_2;
};
#endif // MAINWINDOW_H
预留贴个7积分的工程下载目录:-https://download.csdn.net/download/wangsenye/12537449