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以获取平均梯度,浮点数的矩阵运算是麻 ...
OpenCV C++记录(七):霍夫变换、仿射变换、透视变换
霍夫变换(Hough Transform)
霍夫变换只是一种特征变换,服务于图像霍夫直线、圆的检测,这两种图形是霍夫变换最常用的两个应用,也算基本图形,基于此扩展霍夫检测能识别图像中几乎所有的几何图形。
对人而言判断一条直线或者某种图形是非常直接简单的,而对于计算机而言,它获取的信息是像素,如何确定某一群像素就是一条共线的直线、一个圆形,如果出现像素外溢,如何辨认出这种偏差影响,是比较复杂的任务,也是霍夫变换的基本任务。
霍夫直线检测基本原理
假设给定两点像素坐标(x1,y1)和(x2,y2),可知过两点得到一条直线y = kx + b,这是笛卡尔空间的表达式,重新描述这个表达式:
b = -xk + y,自变量为k、因变量为b,该空间称为霍夫空间,对于笛卡尔坐标的两点(x1,y1)和(x2,y2),分别对应b = -x1k + y1和b = -x2k + y2,即对应霍夫空间两条线,且x1不等于x2的情况下(相等的情况后文再讨论),两条霍夫空间直线必然交与一点,该点(b0,k0)同时满足两条霍夫直线方程,故知(b0,k0)就是原式y = kx + b的解。
因此,一句话表 ...
OpenCV C++记录(六):轮廓提取
OpenCV轮廓
轮廓提取任务是许多图像分析、识别的必要步骤,前置工作是将灰度图进行二值化,然后基于二值化图进行轮廓提取,本文记录了OpenCV一系列轮廓相关的分析手段,包括基本轮廓提取、绘制、外接多边形/椭圆/圆、多轮廓的交、并、差填充等。
轮廓提取与绘制
cv提供了强大的基本轮廓识别和绘制功能:
123456789101112131415161718192021222324void cv::findContours(InputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point())参数:image:输入的二值图像contours:轮廓信息,一般为点的二维vector,第一维是数组,代表第i个轮廓的点集,第二维是某个轮廓的第j个点hierarchy:轮廓层次信息,一般是关于Vec4i的vector,第一维代表第i个轮廓;第 ...
序列化协议Protobuf(二):C++ Proto3指南
protobuf使用
虽然protobuf的版本管理比较拉跨,然而其使用指南可以说非常详尽与方便,具体可参考:
Language Guide
(proto 3)
Language Guide
(proto 2)
C++
Generated Code Guide
Protocol Buffer
Basics: C++
本文记录了其中proto3使用和C++构建和使用proto较重点的部分,只有少量proto2部分(少用;
proto 3基础语法
第一行必须非空、非注释行,表示版本信息,如:syntax = "proto3";若缺省默认为proto2;
第二行一般使用package
xxx;指明包名,防止不同protobuf定义的冲突;
数据类型
标量类型(Scalar Value Types)
一般数据类型,和C++数据类型类似;
类型
说明
类型
说明
double
64浮点
float
32浮点
uint32
相当于uint32,可变长度编码
fixed32
...
序列化协议Protobuf(一):MSVC环境编译
C++ Protocol Buffers
protobuf是google推出的一个数据序列化/反序列化库,和Json/XML类似,但是其以二进制编码进行传输,而Json/XML以文本格式传输,因此文件大小更小(3-10倍)、传输速度更快(20-100倍);
protobuf是一种语言无关的库,支持C++、Python、Java、Js、Ruby等主流语言,广泛用于网络、数据传输中,例如网络协议grpc;
但protobuf也不是完美的,例如它不能像Json一样即插即用,对C++而言尤为复杂,需要编译器以及runtime环境,对其他语言略微友好一点;以下记录了Win10
+
MSVC编译protobuf过程,尽量列出要点,对版本无要求的可以按照本文进行,经过二次验证成功率较高,对于非C++用户/配置/VS小白/高血压患者建议使用Unix环境包管理器或vcpkg等安装依赖,无需参考本文(本文也针对禁git的生产环境。
protobuf的github仓库给出了各种语言的安装方法,但就C++安装而言其指向仍然是不清晰的,这也是issue和迭代频繁的原因,网上提供的方法许多已经过时,因 ...
CMake学习笔记
cmake学习
为什么需要cmake:
C/CPP复杂的编译依赖关系需要通过特定文件指定,方便大型项目管理;
Cmake学习成本远低于Makefile文件;
本文主要参考两篇cmake教程良作:CMake
保姆级教程(上)和CMake
保姆级教程(下),写得比较详细,可直接移步学习;
另外,和原作不同,本文主要基于windows环境验证,基本也是大同小异.
准备工作
windows:检查cmake安装、mingw编译器安装并添加了相关环境变量
linux:cmake安装、gcc -v、g++ -v、make -v均有对应版本输出;
多文件编译
假设存在g++环境,编译以下若干示例文件方法:g++ main.cpp div.cpp multi.cpp sub.cpp add.cpp -o test.exe
123456//add.cpp#include <iostream>#include "main.h"int add(int a,int b){ return a+b;}
123456//su ...
简记:正则表达式
正则表达式
仅记录常识。
单字符匹配
1234567[abcd] 仅匹配列表中的单个字符[^abcde] 匹配列表以外的字符单字符[a-z] 匹配a-z,大写、数字同理[\w] 匹配小写、大写、数字、下划线,同[A-Za-z0-9_](单个字符)[\d] 匹配单个数字[\s\S] \s匹配空白符(空格、tab、换行等);\S匹配非空白符(非换行、空格、制表等);[.] 任意单字符,除了换行;
多次匹配
12345{n} 匹配n次{n,m} 匹配n到m次* *前面的字符或者表达式匹配0次或多次+ +前面的字符或者表达式匹配1次或多次? ?前面的字符或者表达式匹配0次或1次
例子: 12345678910string test = "edcbabcdex"; ...