Qt的Json序列化
Json的易用性使得它成为最常用的通信格式之一,本文记录了Qt中的Json封装和解析,包括QJsonDocument、QJsonObject、QJsonValue、QJsonArray类型;
QJson
直接看示例就会用了,一个示例json: 123456789101112131415{ "Company": "Digia", "From": "1991", "Name": "Qt", "Page": { "Developers": "https://www.qt.io/developers/", "Download": "https://www.qt.io/download/", "Home": "https://www.qt.io/" ...
Mat/QImage To Json:Mat/QImage类型的Json序列化
记录了cv::Mat的json序列化和反序列化过程,以及比对序列化反序列化前后的两个Mat矩阵是否对应。
Mat to json序列化
Mat是一种特殊的数据类型,如果使用vector再进行JsonArray序列化略微繁琐,且类型不同通道数通用性较差,一般习惯使用base64编码图像信息,首先通过cv::imencode函数进行编码(因为大多数图像是8位位深,故该函数仅支持CV_8U类型的编码);
12345678910111213141516bool cv::imencode(const std::string& ext, InputArray img, std::vector<uchar>& buf, const std::vector<int>& params = std::vector<int>())//参数:ext:png或者jpg,前者无损,后者有损;img:输入图像;buf:编码数组;params:png/jpg模式具体参数(可缺省),如: - std::vector<int& ...
(Private)巧思设计:基于任意对象的日志打印设计
103c704d716c2a6b4b59a60c7b698e01e267a92d601a60f130246c8b57cc624a003856e3d418a0f461510530aabe27de357c3c56037bc9ce191314c495c6c1714fbf8efc9b427c0491c5c978a7861b748bdab2c41c43fe1b842056241317123a7fff4bb9e0e27fc9b212a04545d21f4c46a954ab65a678fcb60d640c871be6fe9d83491bc34b2625dd65be1558c7d68907a211232efcbff63266f1bec2426119f26c5d6a55ee3dff2b1ca911ec8ecc05a072f0d36fcb8412d57a876092ed44d4f8d1ea667d82bf10633ad087a98db3eb3354d39ce35f37470d8580c05e12ad0d8de5f3b5a93500db31c6fba0a2cad211fdf110f61f51da50f ...
C++ 14 读写锁
C++读写锁
C++14引入了shared_mutex,允许使用shared_lock来进行并发读取操作,大幅度提高读线程的吞吐量,对于写操作仍然使用unique_lock独占锁维护数据安全,因为读写锁始终是共享一把锁,虽然读线程间没有了竞态条件,但写线程仍然需要和读、写线程同时竞争锁,而且读写锁一般开销大于普通互斥锁。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <iostream>#include <vector>#include <shared_mutex>#include <mutex>#include <thread>#include <functional>#include <chrono>using namespace std;class Person{private ...
Qt Core Application:元对象/属性系统/反射
有限的RTTI
运行时类型信息(Run-Time Type
Info,RTTI)是C++等静态语言的一个重要特性,C++的类型检查基本在编译期完成,仅提供了typeid、dynamic_cast两种用于支持运行时的类型信息,它们在前面的文章介绍过了:typeid用于获取类名,然而在不同的编译平台上这个方法得到的结果并不统一,尤其是gcc、clang等平台,需要进行转换;dynamic_cast常用于避免大指针去操控小内存(例如子类指针去操作父类),这是非安全的下行转换行为;
可见C++对RTTI的支持实在非常有限,而恰巧Qt中对RTTI的需求是较高的,例如一个基类指针Animal*
去保存若干派生类如Monkey* 、
Panda*,一旦编译完成,在已编译信息中就无法区分哪些函数、成员变量是属于哪个类的了,C++
RTTI唯一可以做的是通过上述typeid获取到其类名,而不能特别地访问某些类成员变量或者函数,莫谈如何操作;但同为静态语言的Java、C#等就有强大的RTTI支持,乃至成为其引以为傲的动态特性,这种支持运行时动态创建、访问类型的特性,称为反射(Reflectio ...
C++ 11 线程池
单任务队列线程池
C++
11引入了五个头文件用于支持多线程编程,但是在很多场合下,工作的子任务往往是循环往复的,因此产生了线程池的应用,线程池一个重要的初衷就是希望将线程成池管理起来,由我们去控制它的分配和使用,需要时取出线程分配使用,当线程结束时它能够被重新回到池中复用。在搜寻相关资料时看到一篇通俗易懂的文章,这部分的代码参考自原文,对语法糖不熟悉的可以移步学习。
其基本工作流如下:
积木一:安全队列
安全队列是一个带锁的FIFO结构,用于管理各种任务的出入:
1234567891011121314151617181920212223242526272829303132333435template<typename T>class SafeQueue{private: mutex qlock; queue<T> m_queue;public: SafeQueue(){} SafeQueue(SafeQueue&& otherQueue){} ~Saf ...
Qt TCP Socket与WebSocket
网络通信是Qt框架的常见应用,本文以TCP和WebSocket为例介绍了二者实现信息收发的基本方法和细节,可以作为初始开发的基本demo,采用cmake方法管理基本文件依赖关系,本文暂不涉及界面开发部分,直接基于QObject而不是QWidget。
前置环境说明
在Linux环境下进行网络通信实验是比较方便的,Windows下则需要一些步骤去适配动态库差异,本文兼顾了两个系统运行,所以某些步骤对Linux环境可能是多余的,本文采用mingw来编译工程,应该提前检查环境变量,并且在Qt Creator-帮助-关于插件-搜索cmake勾选"load"。
Ubuntu防火墙检查
首次使用某端口进行通信时,常常需要打开防火墙,windows会有弹窗提示,点击允许即可,linux则使用ufw检查:
1234567891011sudo ufw statussudo ufw allow 8887 #开放端口sudo ufw enable #启动防火墙sudo ufw reload #重新加载规则sudo ufw status #端口已经更新## 其余规则sudo ufw delete al ...
设计模式(三):简单工厂模式、工厂模式、抽象工厂模式
简单工厂模式
简单工厂模式的设计是当我们需要各种各样的产品时,只需要在工厂新建一条产线,让工厂进行产品供给,而无需用户侧关心产品的制作细节,仅需要根据类型向工厂下订单即可。换到程序设计的语言,也即用户需要不同的产品类,这些产品类都具有相同功能、特性不同的接口,仅需要向工厂类提供类型,由工厂类进行分配,对工厂类而言,也不过是多了一个case去包含这个产品,实现了类间的松耦合。
简单工厂模式的角色为几类:
抽象产品类:相当于提供给工厂统一接口,具体特性接口由产品自身override;
具体产品类:提供不同的类特性和接口;
唯一工厂类:工厂类负责生产各种各样的产品;
由描述可知C++ 虚函数多态可以完成实现,以下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#include <iostream>using name ...
设计模式(二):单例模式
单例模式
保证一个类仅提供一个实例,并且通过此唯一实例提供类数据的全局访问,该模式被称为单例模式,单例模式常常应用于仅需单一对象的任务,例如打印时仅有一个打印上下文对象、写入文件时仅提供一个对象防止繁琐的同步机制等。
为了实现这种特性,单例模式的类采用了:
私有化的构造函数:禁止在类外实例化类对象;
禁用的拷贝、赋值构造函数:防止出现第二个实例;
单例模式的另一个初衷是避免单一实例反复构造和析构带来大量的开销,且通过类名即可访问,因此单例模式采用了静态成员变量对象,为了操作这个静态成员变量提供了公共的静态成员函数接口,通过此函数向类外提供静态对象。
一个单例模式的类如下: 12345678910class Singleton{public: Singleton(const Singleton& obj) = delete; Singleton& operator=(const Singleton& obj) = delete; static Singleton* getInstance();private: ...
OpenCV C++记录(八):Sobel、Scharr、Laplacian、Canny算子
Sobel算子
Sobel算子是一种边缘检测算子,由Irwin
Sobel在1968斯坦福的博士生讨论会提出,在那个不重视论文和专利的年代,作者也没有为此发表论文,只在后来一本专著中公开,从此广泛被学界和工业界引用了几十年。
图像处理中经典的3阶Sobel卷积核常常表述为x方向和y方向,分别为:
此处我们发现零行两侧的系数恰好是相反数,尽管一些博客中矩阵调换了两侧符号顺序,只影响差分顺序,并不影响最终的差分结果。
Sobel算子的推导我查阅了大量博客资料,发现大多摘自电子科大彭真明教授的Sobel算子的数学基础,彭教授的参考来自文献,主要问题来自公式解读不同,以此图为坐标系:
原文公式为:
其中(1,1)、(-1,1)、(0,1)、(1,0)来自四个方向相邻点的方向向量,既然仅考虑了相邻点,所以这里是一种前向差分,前向差分表述为:
对于四分一、二分一,这里彭教授认为是一种城市距离(city-block
distance),几种常见距离定义如下图:
距离定义
根据文献意图,四个方向梯度计算完成,还需要除以4以获取平均梯度,浮点数的矩阵运算是麻 ...