序列化协议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"; ...
C++ Qt数据类型
Qt作为一种跨平台开发工具,具有强大的基本数据类型基础,除了承袭C++和STL数据类型的衣钵,还抽象出大量的Qt特色数据类型支撑以满足应用开发的各种需求。本文记录了常用的一些数据类型,持续更新。
Qt基本数据类型
以下数据类型对应不同位数,用于要求较高的场合;跨平台环境应该避免直接使用int和long,int最常见是32位的,但是也见16位、64位;long在32位系统是32位,相当于int,在64位系统是64位的,相当于long
long。
类型
大小
说明
bool
8位
布尔
int8_t/qint8
8位
signed char
int16_t/qint16
16位
signed short
int32_t/qint32/int
32位
signed int
int64_t/qint64
64位
long long int
uint8_t/quint8
8位
unsigned char
uint16_t/quint16
16位
unsigned sh ...
OpenCV C++记录(五):插值算法:最近邻插、双线性插值、双三次插值
插值算法
图像放缩的过程也是像素增加、减小的过程,因此需要插值算法、采样算法等,在保证一定性能的基础上争取较好的输出质量。记录几种方法原理,对应OpenCV中几种常用插值算法,分别是最近邻插值、双线性插值、双三次插值,其性能依次递减,效果依次递增,其中双线性插值是二者比较均衡的算法,是许多插值模型的默认模式。如果对原生插值算法无兴趣,可直接跳过本文,看简单的放缩函数,不小心引出这么一大段,我想也是比较扯蛋,但终归有所收获。
最近邻插值INTER_NEAREST
最近邻插值最大的特点是:不会产生新的像素,目标图像的像素均来自源图像,新图像坐标与源图像坐标对应如下:
例如将2*2的图片放大成4*8的图片,新图(3,8)位置的像素计算: 故取原图(2,2)位置的像素。
最近邻插实现图像放大:由于我先完成了双三次和双线性插值算法再回头写这个,有些问题反而在篇头省略了。例如这里的int y_ = round((i+0.5)*scale_y-0.5)等详见后文《双线性插值优化》讨论,是一种几何中心对齐,主要是用于纠正计算参考点时几何中心偏差。
123456789101112131 ...
OpenCV C++记录(四):基本图形绘制与图像操作
图形绘制
line画线函数
123456void cv::line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)// 参数解释:输入图形、Point起点、终点、Scalar颜色、粗细 // lineType为连接线类型(默认八方向线LINE_8),抗锯齿可使用LINE_AA// shift代表坐标缩放(除以2的shift次方)
实例: 12345678910111213141516171819202122232425262728293031323334353637#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;int main(){ Mat img; img.create(Size ...
OpenCV C++记录(三):颜色空间/椒盐/高斯噪声
图像基础
位图与矢量图
位图是以像素表示图像信息,因此能很容易控制色彩和细节信息,容易进行编辑,但最大的问题在于位图的清晰度束缚于像素分辨率,无限放大的图片必然带来图像的失真,清晰度下降;矢量图则是比较少接触的图像,它不以像素存储图像信息,而是使用各种数学化的几何元素、线段、曲线、多边形等描述,其算法不随放大而变化,因此无限放大下依然能够保持图像清晰,但因为设计数学公式运算,其编辑灵活性较低,矢量图格式包括swf、dwg、emf等;
jpeg、jpg和png
这是位图中常常看到的三种格式,其中jpeg、jpg是一种格式,命名差异在于早期Windows限定三个字符,因此将jpeg称为jpg/jif等,jpg的特点是对图像进行有损压缩,体积较小,容易传播,一般的jpg压缩率是95%,即质量值为95,质量值越低,清晰度越差;jpg通常采用Progressive JPG(渐进式加载)的保存方式,网络接收时先展示图像的模糊轮廓,再逐渐填充其他细节,在应用图片加载比较常用;另一种保存方式是Baseline JPG(线性加载),从上到下进行扫描和显示,jpg适用于风景图片(压缩效果不容易导致 ...
OpenCV C++记录(二):Mat数据类型
Mat数据类型
Mat是OpenCV特有的结构,其可以存储图像和矩阵,其中Mat支持不同的数据类型,表示不同的数据长度和通道数量。命名规则是CV_nUCm,其中n是数据长度,m是通道数量,从数据长度来看一般有CV_8U、CV_8S、CV_16U、CV_16S、CV_32S、CV_32F、CV_64F七种,U代表Unsigned、S代表Signed,数字取8、16、32代表位数,决定了整型数据的表示范围,此外还有32F、64F代表32位、64位精度浮点数;从通道数来看分别有C1——C4,表示了1——4个通道,二者结合就是基本的数据类型。
所谓不同通道,实际上是列数增加,例如RGB图像就是三个通道,即将三个数字看成是一个统一数据。
1234567891011Mat m1(4, 3, CV_8SC1,256);cout<<m1; //单通道// [127, 127, 127;// 127, 127, 127;// 127, 127, 127;// 127, 127, 127]Mat m2(4, 3, CV_8SC2,256);cout<<m2; //双通道,第一 ...
C++ 11 新特性总结(三):多线程编程
C++11 多线程相关
在Linux操作系统:进程与线程中介绍了Linux系pthread创建和管理线程基本方法,在C++11中,又引入了五个头文件支持多线程编程,它们分别是<thread>、<future>、<atomic>、<mutex>和<condition_variable>,带来不少实用的新特性,值得学习。其函数基本使用标准命名空间std,不赘述。
thread
thread用于创建一个线程,其定义了相关构造函数,具体如下:
12345678thread() noexcept; //无参构造函数,一个空线程template <class Fn, class... Args>explicit thread(Fn&& fn, Args&&... args); //有参构造,线程+参数thread(const thread&) = delete; //禁用拷贝构造thread(thread&& x) noexcept; //移动构造函数
thre ...