(五)Qt 动态手势识别“左右滑动”以及实现翻页效果

news/2024/4/15 14:12:03

系列文章目录

通过Qt实现手势识别控制软件操作相关系列技术方案

(一)Qt 将某控件、图案绘制在最前面的方法,通过QGraphicsScene模块实现
(二)Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方,实现圆点的“彩色拖尾”效果以及“选中方框”效果
(三)Qt 动态手势识别“握拳”
(四)Qt 动态手势识别“手掌随动”+“握拳选择”
(五)Qt 动态手势识别“左右滑动”以及实现翻页效果

文章目录

  • 系列文章目录
  • 1、前言
    • 1.1 目标
  • 2、效果
  • 2、代码实现
    • 2.1 动态手势识别“左右滑动”
    • 2.2 屏幕滑动效果的实现
  • 总结


1、前言

  本系列博客为Qt实现动态手势识别以及实现一些特定效果的工程性记录博客。

1.1 目标

  本篇博客主要记录了动态手势识别实现“左右滑动翻页”的效果的过程。


2、效果

  为了实现对“左右滑动手势”现象的监测,首先设计好UI相关内容,即在Widget背景内实现“变色”的效果,且每当监测到“右移”或是“左移”的动作时,背景内的数字产生变化,每次“右移”发生时,背景的数字将会+1,每次“左移”发生时,背景的数字将会-1。
  数字右侧的窗口是摄像头的实时画面情况,用于验证效果。

  先看演示效果视频:

动态手势识别_左移页面_视角1

动态手势识别_右移页面_视角1

动态手势识别_右移页面_视角2

  效果演示动态图如下图所示:
在这里插入图片描述

图1 “右移”效果gif图

在这里插入图片描述

图2 “左移”效果gif图

2、代码实现

2.1 动态手势识别“左右滑动”

  判断动态手势的“左右滑动”,与本系列里第(三)篇文章里所说的“检测握拳动作”类似,均为实现判断某一特定系列内各帧静态手势的具体类别、相对位置、运动速度等具体参数内容。
  能判断手势是否存在“左右滑动”现象的手法很多,这里只介绍一种简单的方法步骤:
  (1)判定动作初始帧的位置,如果想右移,那么初始帧的位置必然位于监测画面的左半边,如果想左移,那么初始帧的位置必然位于监测画面的右半边(当然了,这里没什么必然,看个人对动态手势的具体定义吧);
  (2)检测该动作序列中,后一帧对前一帧在横坐标方向上的偏移量,若是右移,那么偏移量均应该为正值,若为左移,偏移量均应该为负值;
  (3)该序列每帧数据的纵坐标方向上的偏差应该小于某一特定的阈值,用于判断该动作是水平方向上的运动;
  (4)手势的速度问题,在上述第(2)点的偏移量,需要检测每个偏移量的数值大小,其绝对值应该大于某一特定的数值(这个自行确定);
  (5)最后一帧的位置问题,判断最后一帧的具体位置是否出现在其应该出现的位置,对于左移而言,其最后一帧的位置应该在监测画面的右半边。
  下面是识别“左右滑动”的算法的C++/Qt代码实现。

QString HandPostureDetect::dynamic_gesture_recognize_leftSlide(const QQueue<QPointF>* historyPoints)
{int countLeftMove = 0; int countTotalPoints = historyPoints->size(); const QPointF& startPoint = (*historyPoints).front();const QPointF& endPoint = (*historyPoints).back();double distance = qSqrt(qPow(endPoint.x() - startPoint.x(), 2) + qPow(endPoint.y() - startPoint.y(), 2));if (distance < 0.3 || startPoint.x() < 0.5){pre_left_slide_condition = 0;return ""; }for (int i = 1; i < countTotalPoints; ++i){const QPointF& currentPoint = (*historyPoints)[i];const QPointF& previousPoint = (*historyPoints)[i - 1];double deltaX = currentPoint.x() - previousPoint.x();double deltaY = currentPoint.y() - previousPoint.y();if (deltaX < 0 && qAbs(deltaY) < 0.1) {countLeftMove++;}}double ratioLeftMove = static_cast<double>(countLeftMove) / countTotalPoints;if (ratioLeftMove >= 0.3) {if (pre_left_slide_condition == 0){qDebug() << "Left Slide_" << left_slide_count;left_slide_count++;emit send_result(3);}pre_left_slide_condition = 1;return "Left Slide";}else{pre_left_slide_condition = 0;return "";}
}

2.2 屏幕滑动效果的实现

  通过QStackWidget模块实现容纳多个不同的QWidget对象,可进行按索引选择所展现的具体页面。
  这里“左右切换屏幕”的效果用Qt的动画模块QPropertyAnimation进行的实现。
  当每次有动态手势被检测到的时候,同时调用Interface_Switching_Animation函数,该函数包含两个参数,第一个参数int m_currentIndex用来表示QStackWidget的索引数,第二个参数int left_right_type用来表示是“左移”还是“右移”。

void Widget::Interface_Switching_Animation(int m_currentIndex, int left_right_type)
void Widget::Interface_Switching_Animation(int m_currentIndex, int left_right_type)
{int flag = 0;QLabel *m_label = new QLabel(ui->stackedWidget);m_label->resize(QSize(ui->stackedWidget->width(),ui->stackedWidget->height()));m_label->setPixmap(ui->stackedWidget->grab());m_label->setAttribute(Qt::WA_DeleteOnClose);m_label->show();QPropertyAnimation *animation1 = new QPropertyAnimation(m_label, "geometry");animation1->setDuration(1000);if(left_right_type == 1){//向左拉出前一页animation1->setStartValue(QRect(0,0,ui->stackedWidget->width(),ui->stackedWidget->height()));animation1->setEndValue(QRect(ui->stackedWidget->width()*2,0,ui->stackedWidget->width(),ui->stackedWidget->height()));flag = 0;}else if(left_right_type == 0){//向右拉出前一页animation1->setStartValue(QRect(0,0,ui->stackedWidget->width(),ui->stackedWidget->height()));animation1->setEndValue(QRect(-ui->stackedWidget->width()*2,0,ui->stackedWidget->width(),ui->stackedWidget->height()));flag = 1;}animation1->setEasingCurve(QEasingCurve::InCubic);QParallelAnimationGroup *group = new QParallelAnimationGroup;group->addAnimation(animation1);group->start(QAbstractAnimation::DeleteWhenStopped);ui->stackedWidget->setCurrentIndex(m_currentIndex);m_label->raise();connect(group, &QParallelAnimationGroup::finished, this, [=](){m_label->close();}); //关闭动画完成后关闭labelif(flag == 0){count_times++;}else if (flag == 1){count_times--;}QString text = QString::number(count_times);QString styleSheet = "background-color: #";styleSheet += QString::number(qrand() % 256, 16).rightJustified(2, '0'); // 随机生成颜色styleSheet += QString::number(qrand() % 256, 16).rightJustified(2, '0');styleSheet += QString::number(qrand() % 256, 16).rightJustified(2, '0');QWidget* currentwidget = ui->stackedWidget->currentWidget();currentwidget->setStyleSheet(styleSheet);QLabel *label = new QLabel(currentwidget);label->setFont(QFont("Arial", 360));label->setText(text);label->setAlignment(Qt::AlignCenter);label->setGeometry(currentwidget->rect());
//        label->setStyleSheet("color: white;");label->show();
}

总结

  本系列文章,通过动、静态手势识别技术方式操控Qt界面软件实现相关操作功能:
(一)Qt 将某控件、图案绘制在最前面的方法,通过QGraphicsScene模块实现
(二)Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方,实现圆点的“彩色拖尾”效果以及“选中方框”效果
(三)Qt 动态手势识别“握拳”
(四)Qt 动态手势识别“手掌随动”+“握拳选择”
(五)Qt 动态手势识别“左右滑动”以及实现翻页效果

  本项目所有代码的获取,请私信与本人联系。


http://www.ppmy.cn/news/661890.html

相关文章

数据中心加湿系统计算及方法探讨【新规范加湿方式对比及计算分析】

// 摘要 /// NOCITCE 数据中心机房的电子信息及IT 设备需要在一个合适的环境下稳定、安全的运行。数据中心室内环境设计参数应满足国家相关规范的要求&#xff0c;湿度是数据中心环境控制的一个重要参数。加湿量的大小与系统设定的湿度上下限有关系&#xff0c;同时也受项目所…

51单片机室内环境甲醛PM2.5光照温度湿度检测及窗帘加湿消毒控制系统

实践制作DIY- GC0042-单片机室内环境检测 一、功能说明&#xff1a; 基于51单片机设计-单片机室内环境检测 二、功能介绍&#xff1a; STC89C52&#xff08;AT89C51/52&#xff09;最小系统GP2Y10 PM2.5传感器DHT11温度湿度传感器SGP甲醛传感器ADC0832采集光敏电阻光强3个继…

pm2基本使用

1.pm2的基本介绍 pm2是node的进程管理器&#xff0c;利用它可以简化node任务的管理,且内置了许多功能,常用于后台脚本管理。 pm2特性 自带热部署 - - - 当源文件更新 线上项目也会自动重启后台运行 - - - 不会占用实时窗口 会在后台运行服务信息查看 - - - 查看运行中程序的…

利用jmeter测试java请求

jmeter和loadrunner一样包含了测试脚本开发、测试执行、以及测试结果统计三个部分。只是jmeter没有脚本开发工具&#xff0c;因此测试java请求的脚本选择在eclipse中进行。 首先介绍如何用eclipse编写接口性能测试脚本。 针对"Java请求"类型的测试&#xff0c;需要…

中国移动互联网十年

这是一段波澜壮阔、荡气回肠的历史。 本文授权转载自猎云网&#xff08;微信号&#xff1a;ilieyun&#xff09; 作者 | 颜西龙 责编 | 胡巍巍 2011年8月16日&#xff0c;北京798艺术中心。 台上&#xff0c;雷军每公布一项技术参数&#xff0c;台下就传来一阵几乎要掀翻屋顶的…

移动互联网十年(建议收藏)

作者 | 颜西龙 来源 | 猎云网&#xff08;ID&#xff1a;ilieyun&#xff09; 全文18218字&#xff0c;约需30分钟以上阅读 这是一段波澜壮阔、荡气回肠的历史 2011 年 8 月 16 日&#xff0c;北京 798 艺术中心。 台上&#xff0c;雷军每公布一项技术参数&#xff0c;台下就…

记一次Native memory leak排查过程 | 京东云技术团队

1 问题现象 路由计算服务是路由系统的核心服务&#xff0c;负责运单路由计划的计算以及实操与计划的匹配。在运维过程中&#xff0c;发现在长期不重启的情况下&#xff0c;有TP99缓慢爬坡的现象。此外&#xff0c;在每周例行调度的试算过程中&#xff0c;能明显看到内存的上涨…

PCB封装设计指导(一)基础知识

PCB封装设计指导(一)基础知识 PCB封装是PCB设计的基础,也是PCB最关键的部件之一,尺寸需要非常准确且精确,关系到设计,生产加工,贴片等后续一系列的流程。 下面以Allegro为例介绍封装创建前的一些基础知识 1.各个psm文件代表什么 mechanical symbol 是.bsm Package sy…

1253. Convert a Number to Hexadecimal

描述 Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used. 1.All letters in hexadecimal (a-f) must be in lowercase.2.The hexadecimal string must not contain extra leading 0s. If the numbe…

1282. Reverse Vowels of a String

描述 Write a function that takes a string as input and reverse only the vowels of a string. The vowels does not include the letter "y". 您在真实的面试中是否遇到过这个题&#xff1f; 是 样例 Example 1:Given s "hello", return "holl…

E03.05 Nomadland’ Review: A Tale of Roaming and Yearning

2021.03.05 文章目录 【课程导读】【英文原文】【外刊原文】 【课程导读】 华人女导演赵婷凭借《无依之地》获得了金球奖最佳导演奖&#xff0c;她也成为首位获得该奖项的亚裔女导演。著名影评人 Joe Morgenstern在《华尔街日报》发表影评&#xff0c;深度分析这部影片的成功…

02【托业口语】 - PART2 Describe a picture

【托业口语】 - PART2 Describe a picture 评价标准&#xff1a;发音&#xff0c;重音&#xff0c;语调&#xff0c;语法&#xff0c;词汇&#xff0c;连贯性 类型&#xff1a;日常生活等 时间&#xff1a; 准备时间 30s 回答时间 45s 第一部分 1&#xff0c;注意事项 &am…

C++:实现量化美国期权的买入/卖出平价根据赫斯顿模型测试实例

C++:实现量化美国期权的买入/卖出平价根据赫斯顿模型测试实例 #include "fdheston.hpp" #include "utilities.hpp" #include <ql/math/functional.hpp> #include <ql/quotes/simplequote.hpp>

TOEFL wordlist 25

1. pancreas [ˈpŋkriəs] n. Your pancreas is an organ in your body that is situated behind your stomach. It produces insulin and substances that help your body digest food. The pancreas is a storage depot for digestive enzymes. 2. Gothic [ˈɡɒθɪk] …

git fetch - git merge - git pull 指令

git fetch - git merge - git pull 指令 Incorporates changes from a remote repository into the current branch. In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD. 在默认模式下&#xff0c;git pull 命令是 git fetch 和 git…

论文阅读:Zero-shot Word Sense Disambiguation using Sense Defifinition Embeddings

目录 论文阅读&#xff1a;Zero-shot Word Sense Disambiguation using Sense Defifinition Embeddings 0 摘要 1 介绍 2 相关工作 3 背景知识 4 EWISE 5 实验设置 6 评估 7 结论和未来工作 论文阅读&#xff1a;Zero-shot Word Sense Disambiguation using Sense Defi…

1.A+B问题

描述 给出两个整数a和b, 求他们的和, 但不能使用 等数学运算符。 你不需要从输入流读入数据&#xff0c;只需要根据aplusb的两个参数a和b&#xff0c;计算他们的和并返回就行。 您在真实的面试中是否遇到过这个题&#xff1f; 是 说明 a和b都是 32位 整数么&#xff1f; 是的…

Codeforces--1271A--Suits

题目描述&#xff1a; A new delivery of clothing has arrived today to the clothing store. This delivery consists of a ties, b scarves, c vests and d jackets. The store does not sell single clothing items — instead, it sells suits of two types: a suit of th…

创意云FAQ | 你的云渲染问题一文帮你全搞定!

现在使用蓝海创意云渲染农场的设计师越来越多&#xff0c;咨询的问题也是五花八门&#xff0c;这里整理下最近问的最多的几个问题统一解答下。如果你现在有云渲染问题&#xff0c;那这一篇指南千万不能错过&#xff01; 一、渲染前问题&#xff1a; 问题一&#xff1a;蓝海创意…

[CodeForces - 1271A ]suits

生词 delivery [dɪˈlɪvəri] n.交货 scarves [skɑ:vz] n.领带(scarf的复数形式) 音标ka发汉语拼音ga音 tie n.领带 jacket n. 夹克 vest n.马甲 题意 有两类套装&#xff0c;第一类需要1条tie、一件夹克&#xff1b;第二类需要一条scarf、一件马甲、一件夹克。 给出…
最新文章