Qt OpenCV 学习(二):两个简单图片识别案例

1. 寻找匹配物体

在这里插入图片描述

1.1 mainwindow.h

#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

#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

#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

#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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224688.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

配置OSS后如何将服务器已有文件上传至OSS,推荐使用ossutil使用

1.下载安装ossutil sudo -v ; curl https://gosspublic.alicdn.com/ossutil/install.sh | sudo bash2.交互式配置生成配置文件 ossutil config 根据提示分别设置配置文件路径、设置工具的语言、Endpoint、AccessKey ID、AccessKey Secret和STSToken参数&#xff0c;STSToken留…

【QT】容器类的迭代

迭代器(iterator)为访问容器类里的数据项提供了统一的方法&#xff0c;Qt有两种迭代器类&#xff1a;Java类型的迭代器和STL类型的迭代器。 Java类型的迭代器更易于使用&#xff0c;且提供一些高级功能&#xff0c;而STL类型的迭代器效率更高。 Qt还提供一个关键字foreach&…

Self-supervised Graph Learning for Recommendation 详解

目录 摘要 引言 预备知识 方法 3.1 图结构数据增强 3.2 对比学习 3.3 多任务学习 3.4 理论分析 摘要 基于用户-物品图的推荐表示学习已经从使用单一 ID 或交互历史发展到利用高阶邻居。这导致了图卷积网络(GCNs)在推荐方面的成功&#xff0c;如 PinSage 和 LightGCN。尽管具…

[Firefly-Linux] RK3568 pca9555芯片驱动详解

文章目录 一、PAC9555 介绍二、ITX-3568JQ PAC9555 使用2.1 原理图2.2 设备树三、RK3568 I2C 介绍四、PAC9555 驱动4.1 介绍4.2 数据结构4.3 驱动分析一、PAC9555 介绍 PAC9555 是一种高性能、低功耗 I/O 扩展芯片,能够提供 16 个 GPIO 通道,每个通道可以单独配置为输入或输…

C语言再学习 -- 单精度(float)和双精度(double)浮点数 与 十六进制(HEX) 之间转换(转载))

之前讲过浮点数部分&#xff0c;参看&#xff1a;C语言再学习 – 浮点数 现在程序中要将浮点数&#xff0c;通过TCP发送。那得先将其转换为十六进制才行呀。 那么问题就来了。 参看&#xff1a;C语言&#xff1a;单精度(float)和双精度(double)浮点数 与 十六进制(HEX) 之间…

完数的C语言实现xdoj30

时间限制: 2 S 内存限制: 10000 Kb 问题描述: 请写一个程序&#xff0c;给出指定整数范围[a&#xff0c;b]内的所有完数&#xff0c;0 < a < b < 10000。 一个数如果恰好等于除它本身外的所有因子之和&#xff0c;这个数就称为"完数"。 例如6是…

git 关于分支、merge、commit提交

最近开始用git终端提交代码&#xff0c;梳理了一些知识点 一 关于分支 关于分支&#xff0c;git的分支分为本地分支远程分支两种分支&#xff0c;在上传代码时&#xff0c;我们要确保当前本地分支连接了一个远程分支。 我们可以通过下面代码查看当前的本地分支&#xff1a; g…

mybatis的分页插件

在mybatis核心配置文件中&#xff1a; 这时已经用了SSM整合&#xff0c;好多像是mapper或者数据源等都移出去了 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""…

nodejs微信小程序+python+PHP新闻发布系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

这些Java并发容器,你都了解吗?

文章目录 前言并发容器1.ConcurrentHashMap 并发版 HashMap示例 2.CopyOnWriteArrayList 并发版 ArrayList示例 3.CopyOnWriteArraySet 并发 Set示例 4.ConcurrentLinkedQueue 并发队列 (基于链表)示例 5.ConcurrentLinkedDeque 并发队列 (基于双向链表)示例 6.ConcurrentSkipL…

【LLM_05】使用fastgpt搭建本地离线大语言模型(Chatglm3)问答+知识库平台

1、FastGPT 的知识库逻辑1.1 基础概念1.2 FastGPT知识库的导入1.3 FastGPT新建应用&#xff08;1&#xff09;创建一个知识库助手&#xff08;2&#xff09;创建一个python开发小助手 2、词向量比较测试2.1 开启词向量模型2.2 词向量模型性能比较 3、配置好之后的运行3.1 运行大…

Redis ziplist源码解析

area |<---- ziplist header ---->|<----------- entries ------------->|<-end->|size 4 bytes 4 bytes 2 bytes ? ? ? ? 1 byte--------------------------------------------------------------- comp…

多人聊天UDP

服务端 package 多人聊天;import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;…

第十六届山东省职业院校技能大赛中职组网络安全赛项竞赛正式试题

第十六届山东省职业院校技能大赛中职组网络安全"赛项竞赛试题 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段任务阶段竞赛任务竞赛时间分值A、B模块A-1登录安全加固180分钟200分A-2本地安全策略设置A-3流量完整性保护A-4事件监控A-5服务加固A-6防火墙策…

Error: Could not create the Java Virtual Machine(Linux启动tomcat成功后找不到进程8080端口)

文章目录 问题解决问题过程Tomcat版本要求 问题解决 版本冲突&#xff0c;我的jdk是1.8.x&#xff0c; tomcat 是 10.1.x的&#xff0c;要求jdk是11。 问题过程 运行 ./startup.sh 显示如下&#xff1a; 还以为运行成功呢&#xff0c; 使用命令一查&#xff0c;根本查不到进…

C语言进阶之路之内存镜像与字符操作函数篇

目录 一、学习目标&#xff1a; 二、内存镜像 什么是进程 C进程内存布局 栈内存 静态数据 数据段&#xff08;存储静态数据&#xff09;与代码段 堆内存 三、字符操作函数 函数strstr 函数strlen strlen与sizeof的区别 函数strtok 函数strcat与strncat 函数strc…

记录 | python向上取整和向下取整

python 向上取整和向下取整 向上取整 使用 ceil()&#xff1a; import mathx 0.55 x0 math.ceil(x)向下取整 使用 floor()&#xff1a; import mathx 0.55 x1 math.floor(x)如下&#xff1a;

群聊Java

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

VR远程带看,助力线下门店线上化转型“自救”

VR远程带看&#xff0c;因自身高效的沉浸式在线沟通功能&#xff0c;逐渐走进了大众的视野。身临其境的线上漫游体验以及实时同屏互联的新型交互模式&#xff0c;提升了商家同用户之间的沟通效率&#xff0c;进一步实现了远程线上一对一、一对多的同屏带看&#xff0c;用户足不…

封装校验-----Vue3+ts项目

登录校验页面 <script setup lang"ts"> import { ref } from vue import { mobileRules, passwordRules } from /utils/rules const mobile ref() const password ref() </script><!-- 表单 --><van-form autocomplete"off">&l…