1. 寻找匹配物体
1.1 mainwindow.h
cpp
复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include <QImage>
#include <QString>
#include <QPixmap>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void initMainWindow();
void imgproc();
void imgShow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
cv::Mat myImg; // 缓存图片:用于代码引用和处理
QImage myQImg; // 保存图片,可转为文件存盘或显示
};
#endif // MAINWINDOW_H
1.2 mainwindow.cpp
cpp
复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
initMainWindow();
}
MainWindow::~MainWindow() {
delete ui;
}
// 界面初始化
void MainWindow::initMainWindow() {
// 读取图片
cv::Mat imgData = cv::imread("D:\\BaiduNetdiskDownload\\search_pic\\search_pic\\mermaid.jpg");
// 图片格式转换
cv::cvtColor(imgData, imgData, cv::COLOR_BGR2RGB);
myImg = imgData;
myQImg = QImage((const unsigned char*)(imgData.data), imgData.cols, imgData.rows, QImage::Format_RGB888);
imgShow(); // 显示图片
}
// 处理图片
void MainWindow::imgproc() {
// CV_TM_CCOEFF 相关匹配,把原图像素对其均值的相对值与待匹配子图像素对其均值的相对值进行比较,计算数值越接近 1,表示匹配度越高
int METHOD = CV_TM_CCOEFF;
cv::Mat imgSrc = myImg; // 将被显示的原图
// 待匹配的子图
cv::Mat imgTmp = cv::imread("D:\\BaiduNetdiskDownload\\search_pic\\search_pic\\fish.jpg");
cv::cvtColor(imgTmp, imgTmp, cv::COLOR_BGR2RGB);
cv::Mat imgRes;
cv::Mat imgDisplay;
imgSrc.copyTo(imgDisplay);
int rescols = imgSrc.cols - imgTmp.cols + 1;
int resrows = imgSrc.rows - imgTmp.rows + 1;
imgRes.create(rescols, resrows, CV_32FC1); // 创建输出结果的矩阵
cv::matchTemplate(imgSrc, imgTmp, imgRes, METHOD); // 进行匹配
cv::normalize(imgRes, imgRes, 0, 1, cv::NORM_MINMAX, -1, cv::Mat()); // 进行标准化
double minVal;
double maxVal;
cv::Point minLoc;
cv::Point maxLoc;
cv::Point matchLoc;
// 通过函数 minMaxLoc 定位最匹配的位置
cv::minMaxLoc(imgRes, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
if (METHOD == CV_TM_SQDIFF || METHOD == CV_TM_SQDIFF_NORMED) {
matchLoc = minLoc;
} else {
matchLoc = maxLoc;
}
// 将匹配结果用举行框圈出来
cv::rectangle(imgDisplay, matchLoc, cv::Point(matchLoc.x + imgTmp.cols, matchLoc.y + imgTmp.rows), cv::Scalar::all(0), 2, 8, 0);
cv::rectangle(imgRes, matchLoc, cv::Point(matchLoc.x + imgTmp.cols, matchLoc.y + imgTmp.rows), cv::Scalar::all(0), 2, 8, 0);
myQImg = QImage((const unsigned char*)(imgDisplay.data), imgDisplay.cols, imgDisplay.rows, QImage::Format_RGB888);
imgShow();
}
// 显示图片
void MainWindow::imgShow() {
// 在 Qt 界面上显示图片
ui->label->setPixmap(QPixmap::fromImage(myQImg.scaled(ui->label->size(), Qt::KeepAspectRatio)));
}
void MainWindow::on_pushButton_clicked() {
imgproc();
}
2. 人脸识别实例
2.1 mainwindow.h
cpp
复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include <vector>
#include <QImage>
#include <QString>
#include <QPixmap>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void initMainWindow();
void imgProc();
void imgShow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
cv::Mat myImg;
QImage myQImg;
};
#endif // MAINWINDOW_H
2.2 mainwindow.cpp
cpp
复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
initMainWindow();
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::initMainWindow() {
cv::Mat imgData = cv::imread("D:\\download\\qt_test\\OpencvFace\\model.jpg");
cv::cvtColor(imgData, imgData, cv::COLOR_BGR2RGB);
myImg = imgData;
myQImg = QImage((const unsigned char*)(imgData.data), imgData.cols, imgData.rows, QImage::Format_RGB888);
imgShow();
}
void MainWindow::imgProc() {
cv::CascadeClassifier face_detector; // 定义人脸识别分类器类
cv::CascadeClassifier eyes_detector; // 定义人眼识别分类器类
// 加载视觉识别分类器
// 下述两个 xml 文件在 D:\OpenCV-MinGW-Build-OpenCV-3.4.9\etc\haarcascades
face_detector.load("D:\\download\\qt_test\\OpencvFace\\haarcascade_frontalface_alt.xml");
eyes_detector.load("D:\\download\\qt_test\\OpencvFace\\haarcascade_eye_tree_eyeglasses.xml");
std::vector<cv::Rect> faces;
cv::Mat imgSrc = myImg;
cv::Mat imgGray;
cv::cvtColor(imgSrc, imgGray, cv::COLOR_BGR2GRAY);
cv::equalizeHist(imgGray, imgGray);
// 多尺寸检测人脸
face_detector.detectMultiScale(imgGray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
for (uint64 i = 0; i < faces.size(); i++) {
cv::Point center(faces[i].x + faces[i].width * 0.5, faces[i].y + faces[i].height * 0.5);
cv::ellipse(imgSrc, center, cv::Size(faces[i].width * 0.5, faces[i].height * 0.5), 0, 0, 360, cv::Scalar(255, 0, 255), 4, 8, 0);
cv::Mat faceROI = imgGray(faces[i]);
std::vector<cv::Rect> eyes;
// 在每张人脸基础上多尺寸检测人眼
eyes_detector.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
for (uint64 j = 0; j < eyes.size(); j++) {
cv::Point center(faces[i].x + eyes[j].x + eyes[j].width * 0.5, faces[i].y + eyes[j].y + eyes[j].height * 0.5);
int radius = cvRound((eyes[j].width + eyes[j].height) * 0.25);
cv::circle(imgSrc, center, radius, cv::Scalar(255, 0, 0), 4, 8, 0);
}
}
cv::Mat imgDst = imgSrc;
myQImg = QImage((const unsigned char*)(imgDst.data), imgDst.cols, imgDst.rows, QImage::Format_RGB888);
imgShow();
}
void MainWindow::imgShow() {
ui->label->setScaledContents(true); // 当图像大于控件大小时,将自动缩放以适应控件的大小
// Qt::KeepAspectRatio:保持图像的纵横比例不变
ui->label->setPixmap(QPixmap::fromImage(myQImg.scaled(ui->label->size(), Qt::KeepAspectRatio)));
}
void MainWindow::on_pushButton_clicked() {
imgProc();
}