人脸识别系统开发(4) -- 图片列表功能
2018-01-03 13:19
411 查看
在该人脸识别系统中,每次识别过程都会从摄像头实时捕获N(暂定为3)张人脸图片,用这N张图片来和证件上面的人脸进行比对。系统会将每次捕获的人脸图片显示在右侧的列表中,我们可以通过QML中的ListView来实现列表功能。
Model-View—Controller(MVC)是源自SmallTalk的一个设计模式,在构建用户界面或前端网页时经常用到。作为一种经典的设计模式,MVC通过将系统分解为模型、视图、控制器三部分,每一部分相互独立,职责单一,在实现过程中只用专注于自身的核心逻辑。模型代表数据,视图代表呈现给用户看的界面部分,而控制器就是一个中间人,从模型拿数据给视图来呈现。
Qt中MVC框架对Controller部分进行了改动,引入了delegate的概念,合起来就是Model-View-Delegate。模型还是负责提供数据,View负责提供舞台进行呈现,Delegate负责控制以什么方式来显示。
有时候ListView中的Model数据可能是通过某种复杂的方式获取到的(如网络接收、文件读取、硬件解码等),这个就需要通过C++构造Model提供到QML中。我们的人脸识别系统的Model数据就是实时从摄像头捕获的图片数据,所以也是在C++中定义Model。
在Qt中QAbstractItemModel是大部分模型(Model)类的基类,比如QAbstractListModel, QAbstractProxyModel, QAbstractTableModel, QFileSystemModel等。
QAbstractItemView是多部分视图(View)类的基类,如QListView, QTableView, QTreeView等。
QAbstractItemDelegate是所有delegate的基类,它又衍生出了QStyledItemDelegate和QItemDelegate两个分支。如果需要实现自己的delegate,可以从这2个类中选择一个作为基类。
C++中Model类
该类的关键在重载的三个虚函数
delegate定义在QML中(因为篇幅有删减):
delegate的定义比较简单,在Component中定义一个Image即可。注意,Image的source设置的不是图片实际地址,而是
Delegate通过
MVC
在说ListView功能前,就不得不提MVC设计模式了,因为ListView是采用这个模式来实现的。Model-View—Controller(MVC)是源自SmallTalk的一个设计模式,在构建用户界面或前端网页时经常用到。作为一种经典的设计模式,MVC通过将系统分解为模型、视图、控制器三部分,每一部分相互独立,职责单一,在实现过程中只用专注于自身的核心逻辑。模型代表数据,视图代表呈现给用户看的界面部分,而控制器就是一个中间人,从模型拿数据给视图来呈现。
Qt中MVC框架对Controller部分进行了改动,引入了delegate的概念,合起来就是Model-View-Delegate。模型还是负责提供数据,View负责提供舞台进行呈现,Delegate负责控制以什么方式来显示。
Model
ListView的Model(也就是数据)可以在QML中定义,如:import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 Rectangle { width: 360; height: 300; color: "#EEEEEE"; Component { id: phoneDelegate; Item { id: wrapper; width: parent.width; height: 30; MouseArea { anchors.fill: parent; onClicked: wrapper.ListView.view.currentIndex = index; } RowLayout { anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter; spacing: 8; Text { id: col1; text: name; color: wrapper.ListView.isCurrentItem ? "red" : "black"; font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18; Layout.preferredWidth: 120; } Text { text: cost; color: wrapper.ListView.isCurrentItem ? "red" : "black"; font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18; Layout.preferredWidth: 80; } Text { text: manufacturer; color: wrapper.ListView.isCurrentItem ? "red" : "black"; font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18; Layout.fillWidth: true; } } } } ListView { id: listView; anchors.fill: parent; delegate: phoneDelegate; model: ListModel { id: phoneModel; ListElement{ name: "iPhone 3GS"; cost: "1000"; manufacturer: "Apple"; } ListElement{ name: "iPhone 4"; cost: "1800"; manufacturer: "Apple"; } ListElement{ name: "iPhone 4S"; cost: "2300"; manufacturer: "Apple"; } ListElement{ name: "iPhone 5"; cost: "4900"; manufacturer: "Apple"; } ListElement{ name: "B199"; cost: "1590"; manufacturer: "HuaWei"; } ListElement{ name: "MI 2S"; cost: "1999"; manufacturer: "XiaoMi"; } ListElement{ name: "GALAXY S5"; cost: "4699"; manufacturer: "Samsung"; } } focus: true; highlight: Rectangle{ color: "lightblue"; } } }
有时候ListView中的Model数据可能是通过某种复杂的方式获取到的(如网络接收、文件读取、硬件解码等),这个就需要通过C++构造Model提供到QML中。我们的人脸识别系统的Model数据就是实时从摄像头捕获的图片数据,所以也是在C++中定义Model。
在Qt中QAbstractItemModel是大部分模型(Model)类的基类,比如QAbstractListModel, QAbstractProxyModel, QAbstractTableModel, QFileSystemModel等。
QAbstractItemView是多部分视图(View)类的基类,如QListView, QTableView, QTreeView等。
QAbstractItemDelegate是所有delegate的基类,它又衍生出了QStyledItemDelegate和QItemDelegate两个分支。如果需要实现自己的delegate,可以从这2个类中选择一个作为基类。
C++中Model类
GrapImageListModel定义:
#pragma once #include <QAbstractListModel> #include <QImage> #include "GrapImageData.h" class GrapImageListModelPrivate; // http://doc.qt.io/qt-5/qabstractlistmodel.html // class GrapImageListModel : public QAbstractListModel { Q_OBJECT public: GrapImageListModel(QObject* parent = NULL); virtual ~GrapImageListModel(); // virtual function. int rowCount(const QModelIndex &parent = QModelIndex() ) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const; QHash<int, QByteArray> roleNames() const; public slots: void addGrapImage(const GrapImageData& data); void clearGrapImage(); signals: void newImage(const QImage &img) const; // 连接ImageDisplay::setImage槽 protected: GrapImageListModelPrivate* m_pPrivate; private: mutable int m_iIndex; };
该类的关键在重载的三个虚函数
rowCount,
data,
roleNames,Delegate在需要数据时会调用这3个函数来获取数据。
delegate定义在QML中(因为篇幅有删减):
Component { id: grapImageDelegate; Rectangle { id: wrapper; width: 140; height: 90; color: "transparent"; Image { id: imgGrap; anchors.fill: parent; smooth: true; fillMode: Image.PreserveAspectFit; source: imgUri; visible: false; } } }
delegate的定义比较简单,在Component中定义一个Image即可。注意,Image的source设置的不是图片实际地址,而是
imgUri。
Delegate通过
rowCount函数获取数据的总行数;通过
roleNames来获取到
QHash<int, QByteArray>,
QHash<int, QByteArray>可以理解为”int - string”的对应集合,比如我们设置
0 - imgUri将0对应到imgUri上,在Delegate需要数据,调用
data时就会在
role参数传0,我们就可以知道这时是需要什么类型的数据了,并且可以根据
index参数知道Delegate要获取哪一行的数据。
相关文章推荐
- 人脸识别系统开发(4) -- 图片列表功能
- (转)【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- 16—【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能
- 人脸识别系统开发(8) -- OpenCV人脸检测
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- 微信公众平台消息接口开发(24)图片识别之人脸识别API
- 人脸识别系统开发(6) -- OpenCV摄像头预览
- 人脸识别系统开发(9) -- Dlib人脸比对
- iOS/Android开发人脸识别SDK列表
- 人脸识别系统开发(7) -- cv::Mat与QImage相互转换
- 人脸识别系统开发(1) -- 系统及开发环境介绍
- 移动端禁止长按图片弹出系统功能列表和禁止文本选择
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- 微信公众平台消息接口开发(20)图片识别之人脸识别
- 微信公众平台消息接口开发(24)图片识别之人脸识别API
- 人脸识别系统开发(8) -- OpenCV人脸检测
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- 微信公众平台消息接口开发(24)图片识别之人脸识别API
- Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题
- 人脸识别系统开发(2) -- QML基础语法