├── .github └── stale.yml ├── .gitignore ├── .readthedocs.yaml ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── assets └── GIT.emmx ├── cmakes ├── .clang-format ├── .gitignore ├── condition │ ├── .gitignore │ ├── CMakeLists.txt │ ├── build.sh │ └── main.cpp ├── grammar │ ├── .clang-format │ ├── .gitignore │ ├── CMakeLists.txt │ ├── libs │ │ ├── hellolibrary.cc │ │ └── hellolibrary.h │ └── main.cc ├── hello │ ├── CMakeLists.txt │ └── main.cpp ├── optimization │ ├── .clang-format │ ├── .gitignore │ ├── CMakeLists.txt │ ├── main.cpp │ └── run.sh └── submodules │ ├── CMakeLists.txt │ ├── exec │ ├── CMakeLists.txt │ └── main.cc │ ├── libs │ ├── CMakeLists.txt │ ├── common │ │ ├── CMakeLists.txt │ │ ├── common.cc │ │ ├── common.h │ │ └── mm.h │ ├── ma │ │ ├── CMakeLists.txt │ │ ├── helloma.cc │ │ └── helloma.h │ └── mb │ │ ├── CMakeLists.txt │ │ ├── himb.cc │ │ └── himb.h │ └── tests │ └── CMakeLists.txt ├── docs ├── clang-format │ ├── clion.md │ ├── generate.md │ └── index.md ├── cmake │ ├── basic.md │ ├── condition.md │ ├── crosscompile.md │ ├── index.md │ ├── install.md │ ├── minimum.md │ ├── opencv.md │ ├── optimization.md │ └── submodule.md ├── cplusplus │ ├── C++标准.md │ ├── advanced │ │ ├── class │ │ │ ├── imgs │ │ │ │ ├── access_control.png │ │ │ │ ├── base_access.png │ │ │ │ └── multiple_inheritance.png │ │ │ ├── static成员.md │ │ │ ├── 基本类结构.md │ │ │ ├── 复制和移动操作.md │ │ │ ├── 嵌套类定义.md │ │ │ ├── 成员函数概述.md │ │ │ ├── 成员访问控制.md │ │ │ ├── 显式默认和删除函数.md │ │ │ ├── 构造器概述.md │ │ │ ├── 析构器.md │ │ │ ├── 类、结构体和共同体.md │ │ │ ├── 类定义.md │ │ │ ├── 结构体.md │ │ │ └── 继承.md │ │ ├── reference │ │ │ ├── lvalue和rvalue.md │ │ │ ├── 引用概述.md │ │ │ ├── 引用类型函数操作.md │ │ │ └── 指针引用.md │ │ ├── smart-pointer │ │ │ ├── imgs │ │ │ │ ├── shared_ptr.png │ │ │ │ └── unique_ptr.png │ │ │ ├── shared_ptr.md │ │ │ ├── unique_ptr.md │ │ │ ├── weak_ptr.md │ │ │ ├── 使用原始指针还是智能指针.md │ │ │ └── 智能指针类型.md │ │ ├── stl │ │ │ ├── STL概述.md │ │ │ ├── [shuffle]随机重排列.md │ │ │ ├── array.md │ │ │ ├── find.md │ │ │ ├── for_each.md │ │ │ ├── map.md │ │ │ ├── queue.md │ │ │ ├── sort.md │ │ │ ├── stack.md │ │ │ └── vector.md │ │ └── template │ │ │ ├── 函数模板.md │ │ │ ├── 模板和名称解析.md │ │ │ └── 模板概述.md │ ├── faq │ │ ├── ISO C++ forbids converting a string constant to char*.md │ │ └── multiple-definition-of.md │ ├── get-started │ │ ├── basic-concepts │ │ │ ├── imgs │ │ │ │ ├── Comp-link.png │ │ │ │ ├── include.png │ │ │ │ └── overloading_consideration.png │ │ │ ├── 临时对象.md │ │ │ ├── 作用域.md │ │ │ ├── 函数.md │ │ │ ├── 初始化.md │ │ │ ├── 声明和定义.md │ │ │ ├── 头文件.md │ │ │ ├── 常量.md │ │ │ ├── 指针引用.md │ │ │ ├── 数组.md │ │ │ ├── 程序终止.md │ │ │ ├── 类型别名设置.md │ │ │ └── 链接.md │ │ ├── keywords │ │ │ ├── cv限定符.md │ │ │ ├── enum.md │ │ │ ├── main.md │ │ │ ├── namespace.md │ │ │ ├── nullptr.md │ │ │ └── size_t.md │ │ ├── operator-overload │ │ │ ├── 一元运算符重载.md │ │ │ ├── 下标运算符重载.md │ │ │ ├── 二元运算符重载.md │ │ │ ├── 函数调用运算符重载.md │ │ │ ├── 操作符重载概述.md │ │ │ └── 赋值运算符重载.md │ │ ├── pointer-array │ │ │ ├── const指针和volatile指针.md │ │ │ ├── 二维数组和二级指针.md │ │ │ ├── 原始指针.md │ │ │ ├── 原始数组.md │ │ │ ├── 指针名和数组名的区别.md │ │ │ ├── 指针和数组.md │ │ │ ├── 指针常量和常量指针.md │ │ │ ├── 指针数组和数组指针.md │ │ │ └── 指针类型.md │ │ └── type-cast-deduce │ │ │ ├── auto.md │ │ │ ├── decltype.md │ │ │ ├── imgs │ │ │ ├── decltype.png │ │ │ └── promotion.png │ │ │ ├── void类型.md │ │ │ ├── 基本类型.md │ │ │ ├── 字符串类型.md │ │ │ ├── 标准转换.md │ │ │ ├── 现代类型转换.md │ │ │ ├── 用户定义的类型转换.md │ │ │ └── 类型概述.md │ ├── operate │ │ └── 计时.md │ └── 学习C++之路.md ├── gtest │ ├── compile.md │ ├── index.md │ ├── primer.md │ └── summary.md ├── index.md ├── libjpeg │ ├── index.md │ └── ubuntu-compile.md ├── matplotlib │ ├── 3d绘图.md │ ├── imgs │ │ ├── anatomy.png │ │ ├── axes-2-2.png │ │ ├── contour_1.png │ │ ├── contour_2.png │ │ ├── contour_3.png │ │ ├── contour_4.png │ │ ├── contour_5.png │ │ ├── coordinate-3d.png │ │ ├── curve-3d.png │ │ ├── figure-1.png │ │ ├── figure-2.png │ │ ├── figure-3.png │ │ ├── figure-suptitle.png │ │ ├── fmt-color.png │ │ ├── fmt-line.png │ │ ├── fmt-marker.png │ │ ├── gray-2-3.png │ │ ├── gray.png │ │ ├── line-chart.png │ │ ├── line-legend-1.png │ │ ├── line-text.png │ │ ├── line2d-properties-1.png │ │ ├── line2d-properties-2.png │ │ ├── line_spots.png │ │ ├── mat_image.png │ │ ├── multi-scatter.png │ │ ├── pie-1.png │ │ ├── pie-2.png │ │ ├── pie-3.png │ │ ├── pie-4.png │ │ ├── pie-5.png │ │ ├── pie-6.png │ │ ├── plot-x-y-+.png │ │ ├── plot-x-y.png │ │ ├── plot-y.png │ │ ├── scatter-3d.png │ │ ├── single-scatter.png │ │ ├── sphx_glr_pyplot_001.png │ │ ├── sphx_glr_pyplot_002.png │ │ ├── sphx_glr_pyplot_003.png │ │ ├── sphx_glr_pyplot_004.png │ │ ├── sphx_glr_pyplot_005.png │ │ ├── sphx_glr_pyplot_006.png │ │ ├── sphx_glr_pyplot_007.png │ │ ├── sphx_glr_pyplot_008.png │ │ ├── sphx_glr_pyplot_009.png │ │ ├── sphx_glr_pyplot_010.png │ │ ├── subplot-1-2-2.png │ │ ├── surface-3d.png │ │ ├── two_y_axes.png │ │ ├── unorder.png │ │ ├── xaxis.png │ │ ├── xlim_xticks.png │ │ └── xlim_xticks_1.png │ ├── y轴坐标错乱.md │ ├── 中文乱码.md │ ├── 图像读取-显示和保存.md │ ├── 属性配置.md │ ├── 引言.md │ ├── 手动设置轴刻度间隔.md │ ├── 折线图.md │ ├── 指定轴取值范围以及显示轴刻度.md │ ├── 散点图.md │ ├── 矩阵显示.md │ ├── 等高线图.md │ ├── 绘图关键概念Figure和Axes.md │ ├── 设置双Y轴.md │ ├── 译-Pyplot教程.md │ └── 饼图.md ├── mnn │ ├── compile.md │ ├── convert.md │ ├── dataformat.md │ ├── imageprocess.md │ ├── index.md │ ├── infer.md │ └── quantization.md ├── numpy │ ├── troubleshooting.md │ ├── 元素累加.md │ ├── 增加或者减少一维.md │ ├── 提取数组中属于某一条件的数据.md │ ├── 数据保存和加载.md │ └── 限制取值范围.md ├── opencv │ ├── configure │ │ ├── 3.4.2 │ │ │ ├── Contrib-源码安装.md │ │ │ ├── 测试.md │ │ │ └── 源码安装.md │ │ ├── 4.0.1 │ │ │ ├── 安装.md │ │ │ ├── 测试.md │ │ │ └── 编译OpenCV4Android.md │ │ ├── 4.1.0 │ │ │ ├── 安装.md │ │ │ └── 配置及测试.md │ │ ├── 4.2.0 │ │ │ ├── 安装.md │ │ │ └── 配置及测试.md │ │ ├── 4.4.0 │ │ │ └── 安装.md │ │ ├── 4.7.0 │ │ │ └── INSTALL.md │ │ ├── SSH-OpenCV-远程图像显示.md │ │ └── python │ │ │ ├── anaconda配置.md │ │ │ ├── opencv-python.md │ │ │ └── pycharm.md │ ├── draw │ │ ├── fillPoly.md │ │ ├── imgs │ │ │ ├── freetype.png │ │ │ ├── line.png │ │ │ ├── rectangle.png │ │ │ └── text.png │ │ ├── line.md │ │ ├── rectangle.md │ │ ├── text.md │ │ └── 绘制中文字符.md │ ├── index.md │ └── process │ │ ├── advanced │ │ └── contour.md │ │ ├── base │ │ ├── Point_.md │ │ ├── Scalar_.md │ │ ├── cartToPolar.md │ │ ├── convertTo.md │ │ ├── copyMakeBorder.md │ │ ├── h264-mpeg4.md │ │ ├── imgs │ │ │ ├── affine │ │ │ │ ├── Warp_Affine_Tutorial_Theory_0.jpg │ │ │ │ ├── X.png │ │ │ │ ├── affine-1.png │ │ │ │ ├── affine-2.png │ │ │ │ ├── affine-matrix.png │ │ │ │ ├── affine-result.png │ │ │ │ ├── compute.png │ │ │ │ ├── get-rotation-matrix.png │ │ │ │ ├── rotate-python.png │ │ │ │ └── warp-affine.png │ │ │ ├── cartToPolar.png │ │ │ ├── constraint_border.png │ │ │ ├── contrast.jpg │ │ │ ├── convert-to.png │ │ │ ├── kernel.png │ │ │ ├── normalize │ │ │ │ ├── norm-type-1.png │ │ │ │ └── norm-type-2.png │ │ │ ├── replicate_border.png │ │ │ ├── sample-edge-second-derivative.jpg │ │ │ └── thresh │ │ │ │ ├── Threshold_Tutorial_Theory_Base_Figure.png │ │ │ │ ├── Threshold_Tutorial_Theory_Binary.png │ │ │ │ ├── Threshold_Tutorial_Theory_Binary_Inverted.png │ │ │ │ ├── Threshold_Tutorial_Theory_Truncate.png │ │ │ │ ├── Threshold_Tutorial_Theory_Zero.png │ │ │ │ ├── Threshold_Tutorial_Theory_Zero_Inverted.png │ │ │ │ ├── thresh-binary-inv.png │ │ │ │ ├── thresh-binary.png │ │ │ │ ├── thresh-tozero-inv.png │ │ │ │ ├── thresh-tozero.png │ │ │ │ └── thresh-truncate.png │ │ ├── normalize.md │ │ ├── threshold.md │ │ ├── vconcat-hconcat.md │ │ ├── 仿射变换.md │ │ ├── 保存图像数据为字节文件.md │ │ ├── 单目标追踪.md │ │ ├── 去除小黑点.md │ │ ├── 对比度增强.md │ │ ├── 运行时间统计.md │ │ └── 非局部均值去噪.md │ │ ├── feature │ │ ├── Understanding-Features.md │ │ ├── imgs │ │ │ ├── matcher │ │ │ │ ├── knnmatch_sift.png │ │ │ │ └── match_sift.png │ │ │ └── sift │ │ │ │ ├── sift_dog.jpg │ │ │ │ ├── sift_keypoints-gray.jpg │ │ │ │ ├── sift_keypoints.jpg │ │ │ │ └── sift_local_extrema.jpg │ │ ├── sift.md │ │ └── 特征匹配.md │ │ └── filter │ │ ├── canny.md │ │ ├── filter2d.md │ │ ├── imgs │ │ ├── Laplace_Operator_Tutorial_Theory_Previous.jpg │ │ ├── Laplace_Operator_Tutorial_Theory_ddIntensity.jpg │ │ ├── canny.png │ │ ├── filter2d.png │ │ ├── gaussian-filter.png │ │ ├── gradient-compute.png │ │ ├── gradient-like-compute.png │ │ ├── gradient.png │ │ ├── kernel.png │ │ ├── laplacian-1.png │ │ ├── laplacian-2.png │ │ ├── laplacian-3.png │ │ ├── laplacian-kernel.png │ │ ├── laplacian-math.png │ │ ├── replicate_border.png │ │ ├── sample-edge-second-derivative.jpg │ │ ├── scharr-1.png │ │ ├── scharr-2.png │ │ ├── scharr-3.png │ │ ├── scharr-kernel.png │ │ ├── sobel-1.png │ │ ├── sobel-2.png │ │ ├── sobel-3.png │ │ ├── sobel-horizontal.png │ │ └── sobel-vertical.png │ │ ├── laplacian.md │ │ ├── scharr.md │ │ └── sobel.md ├── python │ ├── grammar │ │ ├── abc.md │ │ ├── around.md │ │ ├── collections-defaultdict.md │ │ ├── collections-deque.md │ │ ├── easydict.md │ │ ├── enumerate.md │ │ ├── f-strings.md │ │ ├── imgs │ │ │ ├── decorator.png │ │ │ ├── tqdm-1.gif │ │ │ ├── tqdm-2.gif │ │ │ ├── tqdm-3.gif │ │ │ └── xml.png │ │ ├── itertools-product.md │ │ ├── json.md │ │ ├── list.md │ │ ├── logging.md │ │ ├── monkey-patch.md │ │ ├── pprint.md │ │ ├── slice.md │ │ ├── tqdm.md │ │ ├── xml.md │ │ ├── xmltodict.md │ │ ├── yacs.md │ │ ├── 模块和包.md │ │ ├── 类操作.md │ │ └── 装饰器.md │ ├── tool │ │ ├── converage.md │ │ ├── fire.md │ │ ├── pip.md │ │ ├── pnno.md │ │ ├── pytest.md │ │ ├── requirements.md │ │ ├── setup.md │ │ └── 打包和分发Python程序.md │ └── troubleshooting.md ├── pytorch │ ├── cuda │ │ ├── benchmark.md │ │ ├── empty_cache.md │ │ ├── 安装哪个版本的CUDA.md │ │ ├── 指定哪张卡运行.md │ │ └── 监控显存使用.md │ ├── grammar │ │ ├── AdaptiveMaxPool-AdaptiveAvgPool.md │ │ ├── AlexNet.md │ │ ├── LeNet5.md │ │ ├── clamp.md │ │ ├── conv-pool.md │ │ ├── hook-获取运行时中间层计算结果.md │ │ ├── imgs │ │ │ ├── alexnet-500.png │ │ │ ├── alexnet-loss-500.png │ │ │ ├── mnist.png │ │ │ ├── spp-pretrained-acc.png │ │ │ └── spp-pretrained-loss.png │ │ ├── index_fill.md │ │ ├── nonzero.md │ │ ├── onehot.md │ │ ├── precision.md │ │ ├── softmax.md │ │ ├── tensor.md │ │ └── transpose-permute.md │ ├── index.md │ ├── tool │ │ └── visualize.md │ ├── train │ │ ├── distributeddataparallel.md │ │ ├── imgs │ │ │ ├── spp-pretrained-acc.png │ │ │ └── spp-pretrained-loss.png │ │ ├── 为什么推荐使用static_dict方式保存模型.md │ │ ├── 加载部分预训练模型.md │ │ ├── 固定部分参数进行训练.md │ │ ├── 查询模型参数总数.md │ │ ├── 自定义损失函数.md │ │ └── 译-保存和加载模型.md │ └── troubleshooting.md ├── requirements.txt ├── stb │ └── index.md └── torchvision │ ├── ImageFolder.md │ ├── concatdataset.md │ ├── imgs │ ├── cifar-sample-4.png │ ├── fivecrop.png │ ├── preprocess.png │ ├── sphx_glr_data_loading_tutorial_001.png │ ├── sphx_glr_data_loading_tutorial_004.png │ ├── voc-aeroplane.png │ └── voc-dataloader.png │ ├── ten-crops.md │ ├── 加载数据集-批量以及转换操作.md │ ├── 均值和方差.md │ ├── 数据预处理.md │ ├── 自定义数据集和预处理操作.md │ ├── 自定义采样器.md │ └── 采样器.md ├── imgs ├── VisionGuide.png └── VisionGuide.svg ├── libjpeg ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── mkdocs.yml ├── patches └── simhei.ttf ├── py ├── .gitignore ├── data_preprocessing │ ├── __init__.py │ ├── color.py │ ├── compose.py │ ├── crop.py │ ├── erase.py │ ├── flip.py │ ├── resize.py │ └── ten-crops.py └── lr │ ├── SmoothLabelCriterion.py │ ├── __init__.py │ ├── find_lr.py │ ├── find_wd.py │ ├── train_lr.py │ ├── train_wd.py │ └── util.py ├── requirements.txt ├── samples ├── GTestDemo │ ├── .clang-format │ ├── .gitignore │ ├── CMakeLists.txt │ ├── gtest_main.cpp │ └── gtest_two.cpp ├── OpenCVDemo │ ├── .clang-format │ ├── 3rdparty │ │ └── opencv │ ├── CMakeLists.txt │ ├── cropped_lena.jpg │ ├── lena.jpg │ └── main.cpp └── plantuml │ ├── class.puml │ ├── common.puml │ └── version.puml ├── stb ├── .gitignore ├── CMakeLists.txt ├── assets │ └── mnist_0.png ├── main.cpp ├── stb_image.h └── stb_image_write.h └── tools ├── createsamples ├── .vscode │ ├── c_cpp_properties.json │ ├── launch.json │ └── tasks.json ├── CMakeLists.txt ├── createsamples.cpp ├── utility.cpp └── utility.hpp └── traincascade ├── .vscode ├── c_cpp_properties.json └── settings.json ├── CMakeLists.txt ├── HOGfeatures.cpp ├── HOGfeatures.h ├── boost.cpp ├── boost.h ├── cascadeclassifier.cpp ├── cascadeclassifier.h ├── features.cpp ├── haarfeatures.cpp ├── haarfeatures.h ├── imagestorage.cpp ├── imagestorage.h ├── lbpfeatures.cpp ├── lbpfeatures.h ├── old_ml.hpp ├── old_ml_boost.cpp ├── old_ml_data.cpp ├── old_ml_inner_functions.cpp ├── old_ml_precomp.hpp ├── old_ml_tree.cpp ├── traincascade.cpp └── traincascade_features.h /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | mkdocs: 9 | configuration: mkdocs.yml 10 | 11 | # Optionally set the version of Python and requirements required to build your docs 12 | python: 13 | version: 3.8 14 | install: 15 | - requirements: docs/requirements.txt -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cmake.sourceDirectory": "${workspaceFolder}/cmakes/submodules/tests" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 语言: 3 | 🇨🇳 4 | 5 | 6 |
7 | 8 |
9 | 10 |

11 | «VisionGuide»记录了视觉相关的编程语法、计算框架以及视觉库使用 12 |
13 |
14 | 15 | 16 | 17 | 18 | Documentation Status 19 | 20 |

21 | 22 | ## 内容列表 23 | 24 | - [内容列表](#内容列表) 25 | - [主要维护人员](#主要维护人员) 26 | - [参与贡献方式](#参与贡献方式) 27 | - [许可证](#许可证) 28 | 29 | ## 主要维护人员 30 | 31 | * zhujian - *Initial work* - [zjykzj](https://github.com/zjykzj) 32 | 33 | ## 参与贡献方式 34 | 35 | 欢迎任何人的参与!打开[issue](https://github.com/ZJDoc/VisionGuide/issues)或提交合并请求。 36 | 37 | 注意: 38 | 39 | * `GIT`提交,请遵守[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)规范 40 | * 语义版本化,请遵守[Semantic Versioning 2.0.0](https://semver.org)规范 41 | * `README`编写,请遵守[standard-readme](https://github.com/RichardLitt/standard-readme)规范 42 | 43 | ## 许可证 44 | 45 | [Apache License 2.0](LICENSE) © 2021 zjykzj -------------------------------------------------------------------------------- /assets/GIT.emmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/assets/GIT.emmx -------------------------------------------------------------------------------- /cmakes/condition/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(condition) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | set(CON1 OFF) 7 | set(CON2 "con2") 8 | 9 | if (NOT CON1) 10 | MESSAGE(STATUS "con1 is ${CON1}") 11 | endif () 12 | 13 | if (CON1) 14 | MESSAGE(STATUS "con1 is ${CON1}") 15 | elseif (CON2 MATCHES "con2") 16 | MESSAGE(STATUS "con2 is ${CON2}") 17 | endif () 18 | 19 | if (CON3) 20 | MESSAGE(STATUS "con3 is ${CON3}") 21 | endif () 22 | 23 | add_definitions(-DAHAH -DHAHA) 24 | 25 | add_executable(condition main.cpp) 26 | -------------------------------------------------------------------------------- /cmakes/condition/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | BUILD_DIR=build/ 6 | if [[ ! -d "${BUILD_DIR}" ]]; then 7 | mkdir -p ${BUILD_DIR} 8 | fi 9 | 10 | cd ${BUILD_DIR} 11 | cmake -DCON3=ON ../ 12 | make 13 | ./condition -------------------------------------------------------------------------------- /cmakes/condition/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | #ifdef HAHA 5 | std::cout <<"Hello HAHA"< 8 | 9 | void HelloLibrary::hello() { 10 | std::cout << "Hello World, two" << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /cmakes/grammar/libs/hellolibrary.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-21. 3 | // 4 | 5 | #ifndef HELLO_LIBS_HELLOLIBRARY_H_ 6 | #define HELLO_LIBS_HELLOLIBRARY_H_ 7 | 8 | class HelloLibrary { 9 | 10 | public: 11 | HelloLibrary() = default; 12 | ~HelloLibrary() = default; 13 | 14 | void hello(); 15 | }; 16 | 17 | #endif//HELLO_LIBS_HELLOLIBRARY_H_ 18 | -------------------------------------------------------------------------------- /cmakes/grammar/main.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-21. 3 | // 4 | 5 | #include 6 | 7 | #include "libs/hellolibrary.h" 8 | 9 | int main(int argc, char* argv[]) { 10 | std::cout << "Hello World" << std::endl; 11 | 12 | HelloLibrary hello_library; 13 | hello_library.hello(); 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /cmakes/hello/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(hello) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | add_executable(hello main.cpp) -------------------------------------------------------------------------------- /cmakes/hello/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::cout << "Hello, World!" << std::endl; 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /cmakes/optimization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(hello) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | add_executable(hello main.cpp) 7 | 8 | IF (NOT DEFINED ENV{CMAKE_INSTALL_PREFIX}) 9 | MESSAGE(STATUS "CMAKE_INSTALL_PREFIX not defined") 10 | set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) 11 | ENDIF() 12 | MESSAGE(STATUS "output: ${CMAKE_INSTALL_PREFIX}") 13 | install(TARGETS hello RUNTIME DESTINATION bin) -------------------------------------------------------------------------------- /cmakes/optimization/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::cout << "Hello, World!" << std::endl; 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /cmakes/optimization/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=../install .. 6 | 7 | make && make install && cd .. 8 | -------------------------------------------------------------------------------- /cmakes/submodules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(SubModules) 3 | 4 | # 目标处理器架构 5 | MESSAGE(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") 6 | 7 | # 安装路径前缀 8 | set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) 9 | MESSAGE(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") 10 | # 可执行程序运行时搜索路径 11 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_SYSTEM_PROCESSOR}") 12 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 13 | 14 | # 设置动态库名 15 | set(BUILD_COMMON COMMON) 16 | set(BUILD_MA MA) 17 | set(BUILD_MB MB) 18 | # 设置可执行文件名 19 | set(BUILD_MAIN main) 20 | 21 | MESSAGE(STATUS "=> BUILD ...") 22 | # 编译库目录 23 | add_subdirectory(libs) 24 | # 编译测试目录 25 | add_subdirectory(tests) 26 | # 编译可执行文件目录 27 | add_subdirectory(exec) 28 | 29 | MESSAGE(STATUS "=> INSTALL ...") 30 | install(TARGETS ${BUILD_COMMON} ${BUILD_MA} ${BUILD_MB} ${BUILD_MAIN} 31 | RUNTIME DESTINATION bin 32 | LIBRARY DESTINATION lib/${CMAKE_SYSTEM_PROCESSOR} 33 | ARCHIVE DESTINATION lib 34 | PUBLIC_HEADER DESTINATION include 35 | ) 36 | -------------------------------------------------------------------------------- /cmakes/submodules/exec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Exec VERSION 0.1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_C_STANDARD ${CMAKE_C_STANDARD}) 5 | set(CMAKE_CXX_STANDARD 17) 6 | MESSAGE(STATUS "CMAKE_C_STANDARD: ${CMAKE_C_STANDARD}") 7 | MESSAGE(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") 8 | 9 | # 设置C++编译器 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -std=c99") 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -std=c++17") 12 | MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") 13 | MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 14 | 15 | file(GLOB_RECURSE FILES_RECURSE . "*.cc") 16 | MESSAGE(STATUS "FILES_RECURSE: ${FILES_RECURSE}") 17 | 18 | include_directories(../libs/common) 19 | include_directories(../libs/ma) 20 | include_directories(../libs/mb) 21 | 22 | add_executable(${BUILD_MAIN} ${FILES_RECURSE}) 23 | #target_link_libraries(main PRIVATE MA MB COMMON) 24 | target_link_libraries(${BUILD_MAIN} PRIVATE ${BUILD_MA} ${BUILD_MB} ${BUILD_COMMON}) 25 | -------------------------------------------------------------------------------- /cmakes/submodules/exec/main.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #include 6 | 7 | #include "common.h" 8 | #include "helloma.h" 9 | #include "himb.h" 10 | 11 | int main(int argc, char* argv[]) { 12 | std::cout << "Hello main" << std::endl; 13 | 14 | HelloMa ma; 15 | ma.Hello(); 16 | 17 | HiMb mb; 18 | mb.Hi(3, 4); 19 | 20 | Common cm; 21 | std::cout << cm.a_plus_b(5, -3) << std::endl; 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /cmakes/submodules/libs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Libs) 3 | 4 | add_subdirectory(common) 5 | add_subdirectory(ma) 6 | add_subdirectory(mb) 7 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Common VERSION 0.1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_C_STANDARD ${CMAKE_C_STANDARD}) 5 | set(CMAKE_CXX_STANDARD 17) 6 | MESSAGE(STATUS "CMAKE_C_STANDARD: ${CMAKE_C_STANDARD}") 7 | MESSAGE(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") 8 | 9 | # 设置C++编译器 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -std=c99") 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -std=c++17") 12 | MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") 13 | MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 14 | 15 | file(GLOB_RECURSE FILES_RECURSE . "*.cc") 16 | MESSAGE(STATUS "FILES_RECURSE: ${FILES_RECURSE}") 17 | 18 | MESSAGE(STATUS "BUILD_COMMON: ${BUILD_COMMON}") 19 | add_library(${BUILD_COMMON} SHARED ${FILES_RECURSE}) 20 | #set_target_properties(${BUILD_COMMON} PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/*.h) 21 | 22 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") 23 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/common/common.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #include "common.h" 6 | int Common::a_plus_b(int a, int b) { 7 | return a + b; 8 | } 9 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/common/common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #ifndef SUBMODULES_SUBMODULES_LIBS_COMMON_COMMON_H_ 6 | #define SUBMODULES_SUBMODULES_LIBS_COMMON_COMMON_H_ 7 | 8 | class Common { 9 | 10 | public: 11 | Common() = default; 12 | ~Common() = default; 13 | 14 | int a_plus_b(int a, int b); 15 | }; 16 | 17 | #endif//SUBMODULES_SUBMODULES_LIBS_COMMON_COMMON_H_ 18 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/common/mm.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #ifndef SUBMODULES_SUBMODULES_LIBS_COMMON_MM_H_ 6 | #define SUBMODULES_SUBMODULES_LIBS_COMMON_MM_H_ 7 | 8 | #include 9 | 10 | inline std::string GetMM() { 11 | return "Hello MM"; 12 | } 13 | 14 | #endif//SUBMODULES_SUBMODULES_LIBS_COMMON_MM_H_ 15 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/ma/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Ma VERSION 0.1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_C_STANDARD ${CMAKE_C_STANDARD}) 5 | set(CMAKE_CXX_STANDARD 17) 6 | MESSAGE(STATUS "CMAKE_C_STANDARD: ${CMAKE_C_STANDARD}") 7 | MESSAGE(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") 8 | 9 | # 设置C++编译器 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -std=c99") 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -std=c++17") 12 | MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") 13 | MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 14 | 15 | file(GLOB_RECURSE FILES_RECURSE . "*.cc") 16 | MESSAGE(STATUS "FILES_RECURSE: ${FILES_RECURSE}") 17 | 18 | include_directories(../common) 19 | 20 | MESSAGE(STATUS "BUILD_MA: ${BUILD_MA}") 21 | add_library(${BUILD_MA} SHARED ${FILES_RECURSE}) 22 | set_target_properties(${BUILD_MA} PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/helloma.h) 23 | 24 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") 25 | 26 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/ma/helloma.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #include "helloma.h" 6 | 7 | #include 8 | 9 | #include "mm.h" 10 | 11 | int HelloMa::Hello() { 12 | std::cout << "Hello MA" << std::endl; 13 | std::cout << GetMM() << std::endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/ma/helloma.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #ifndef HELLO_SUBMODULES_LIBS_MA_HELLOMA_H_ 6 | #define HELLO_SUBMODULES_LIBS_MA_HELLOMA_H_ 7 | 8 | class HelloMa { 9 | public: 10 | HelloMa() = default; 11 | ~HelloMa() = default; 12 | 13 | int Hello(); 14 | }; 15 | 16 | #endif//HELLO_SUBMODULES_LIBS_MA_HELLOMA_H_ 17 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/mb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Mb VERSION 0.1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_C_STANDARD ${CMAKE_C_STANDARD}) 5 | set(CMAKE_CXX_STANDARD 17) 6 | MESSAGE(STATUS "CMAKE_C_STANDARD: ${CMAKE_C_STANDARD}") 7 | MESSAGE(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") 8 | 9 | # 设置C++编译器 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -std=c99") 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -std=c++17") 12 | MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") 13 | MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 14 | 15 | file(GLOB_RECURSE FILES_RECURSE . "*.cc") 16 | MESSAGE(STATUS "FILES_RECURSE: ${FILES_RECURSE}") 17 | 18 | include_directories(../common) 19 | 20 | MESSAGE(STATUS "BUILD_MB: ${BUILD_MB}") 21 | add_library(${BUILD_MB} SHARED ${FILES_RECURSE}) 22 | target_link_libraries(${BUILD_MB} PRIVATE ${BUILD_COMMON}) 23 | 24 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") 25 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/mb/himb.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #include "himb.h" 6 | 7 | #include 8 | 9 | #include "common.h" 10 | 11 | int HiMb::Hi(int a, int b) { 12 | std::cout << "Hi MB" << std::endl; 13 | 14 | std::cout << "a = " << a << " b = " << b << std::endl; 15 | auto cm = Common(); 16 | int r = cm.a_plus_b(a, b); 17 | std::cout << "result: " << r << std::endl; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /cmakes/submodules/libs/mb/himb.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 23-3-22. 3 | // 4 | 5 | #ifndef HELLO_SUBMODULES_LIBS_MB_HIMB_H_ 6 | #define HELLO_SUBMODULES_LIBS_MB_HIMB_H_ 7 | 8 | class HiMb { 9 | 10 | public: 11 | HiMb() = default; 12 | ~HiMb() = default; 13 | 14 | int Hi(int a, int b); 15 | }; 16 | 17 | #endif//HELLO_SUBMODULES_LIBS_MB_HIMB_H_ 18 | -------------------------------------------------------------------------------- /cmakes/submodules/tests/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/cmakes/submodules/tests/CMakeLists.txt -------------------------------------------------------------------------------- /docs/clang-format/clion.md: -------------------------------------------------------------------------------- 1 | 2 | # CLion配置 3 | 4 | ## 配置文件 5 | 6 | 将`.clang-format`放置到`CLion`工程根路径 7 | 8 | ## CLion配置 9 | 10 | * 点击菜单栏`File->Settings->Editor->Code Style`,打开`ClangFormat`设置 11 | 12 | 修改`C++`文件后使用快捷命令`ctrl+alt+L`即进行格式化操作 13 | 14 | * 点击菜单栏`File->Settings->Tools->Actions on Save`,选中`Reformat code / Optimize imports / Rearrange code` 15 | 16 | 这样修改文件后保存文件就可以自动格式化了 17 | 18 | ## 错误 19 | 20 | ``` 21 | Error reading /home/zj/repos/VisionGuide/samples/GTestDemo/.clang-format:97:4: Invalid argument - unknown key 'Delimiter 22 | ``` 23 | 24 | 当前解决方案:注释掉该选项 25 | 26 | ``` 27 | #RawStringFormats: 28 | # - Delimiter: pb 29 | # Language: TextProto 30 | # BasedOnStyle: google 31 | ``` -------------------------------------------------------------------------------- /docs/clang-format/generate.md: -------------------------------------------------------------------------------- 1 | 2 | # 配置文件 3 | 4 | ## 安装 5 | 6 | 首先安装`clang-format` 7 | 8 | ```shell 9 | sudo apt install clang-format 10 | ``` 11 | 12 | ## 配置 13 | 14 | 执行如下命令,生成`Google`风格`C++`配置文件: 15 | 16 | ```shell 17 | clang-format -style=google -dump-config > .clang-format 18 | ``` 19 | 20 | 生成得到`YAML`格式配置文件`.clang-format` 21 | 22 | ## 修改 23 | 24 | 修改部分选项,更符合个人需求: 25 | 26 | 1. `tab`宽度从`8`修改为`4` 27 | 28 | ``` 29 | #TabWidth: 8 30 | TabWidth: 4 31 | ``` 32 | 33 | 2. `indent`宽度从`2`修改为`4` 34 | 35 | ``` 36 | #IndentWidth: 2 37 | IndentWidth: 4 38 | ``` -------------------------------------------------------------------------------- /docs/clang-format/index.md: -------------------------------------------------------------------------------- 1 | 2 | # Clang-format 3 | 4 | `clang-format`是常用的格式化`C++`代码工具,支持多种代码规范(`Google Code Style/LLVM`等等),并且常用的开发工具(`CLion/VS/VS Code`)上均可配置 5 | 6 | ## 相关阅读 7 | 8 | * [Clang 16.0.0git documentation](https://clang.llvm.org/docs/index.html) -------------------------------------------------------------------------------- /docs/cmake/basic.md: -------------------------------------------------------------------------------- 1 | 2 | # 基础语法 3 | 4 | * 具体示例可以查看:[grammar](../../cmakes/grammar/) 5 | 6 | ## 打印信息 7 | 8 | ```text 9 | message([] "message text" ...) 10 | ``` 11 | 12 | * [Log a message.](https://cmake.org/cmake/help/latest/command/message.html?highlight=message) 13 | 14 | ## 文件操作 15 | 16 | ```text 17 | # 获取文件 18 | file({GLOB | GLOB_RECURSE} [...] [...]) 19 | # 获取当前目录中的所有.cc文件 20 | file(GLOB FILES . "*.cc") 21 | # 递归获取当前目录中所有的.cc文件和.txt文件 22 | file(GLOB_RECURSE FILES_RECURSE . "*.cc" "*.txt") 23 | ``` 24 | 25 | * [File manipulation command.](https://cmake.org/cmake/help/latest/command/file.html?highlight=file#command:file) 26 | 27 | ```text 28 | aux_source_directory( ) 29 | # 获取指定路径下的所有源文件 30 | aux_source_directory(${CMAKE_SOURCE_DIR} SOURCES) 31 | MESSAGE(STATUS "SOURCES: ${SOURCES}") 32 | ``` 33 | 34 | * [aux_source_directory](https://cmake.org/cmake/help/latest/command/aux_source_directory.html) -------------------------------------------------------------------------------- /docs/cmake/crosscompile.md: -------------------------------------------------------------------------------- 1 | 2 | # 交叉编译 3 | 4 | ## aarch64 5 | 6 | ## Android 7 | 8 | * [Android CMake](https://developer.android.google.cn/ndk/guides/cmake#command-line_2) -------------------------------------------------------------------------------- /docs/cmake/index.md: -------------------------------------------------------------------------------- 1 | 2 | # 引言 3 | 4 | 不知不觉已经写了好多的`CMakeLists.txt`文件,对于基本的`CMake`语法也有了简单的理解和使用,记录一下常用的内容。 5 | 6 | * [最小实现](./minimum.md) 7 | * [结构优化](./optimization.md) 8 | * [配置OpenCV](./opencv.md) 9 | 10 | ## 相关阅读 11 | 12 | * [CMake实践应用专题](https://www.zhihu.com/column/c_1369781372333240320) 13 | * 目前看到的比较全面的CMake教程,提供了文档介绍以及示例代码 14 | * 阅读代码,发现作者有一个很好的习惯,就是会给出大部分代码的释义 15 | * 另外代码仓库里面还有一个彩蛋(*关于clang-format*) -------------------------------------------------------------------------------- /docs/cmake/install.md: -------------------------------------------------------------------------------- 1 | 2 | # make install 3 | 4 | ## 文档 5 | 6 | * [cmake应用:安装和打包](https://zhuanlan.zhihu.com/p/377131996) 7 | * [CMake之install方法的使用](https://zhuanlan.zhihu.com/p/102955723) 8 | * [【CMake 系列】(五)安装、打包与导出](https://blog.xizhibei.me/tags/CMake/) 9 | 10 | ## 可执行文件链接库文件 11 | 12 | * [链接选项RPATH以及在cmake和gcc中的使用](https://bewaremypower.github.io/2019/09/05/%E9%93%BE%E6%8E%A5%E9%80%89%E9%A1%B9RPATH%E4%BB%A5%E5%8F%8A%E5%9C%A8cmake%E5%92%8Cgcc%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8/) 13 | 14 | ## 实现 15 | 16 | * [cmakes/submodules](https://github.com/ZJDoc/VisionGuide/tree/master/cmakes/submodules) -------------------------------------------------------------------------------- /docs/cmake/minimum.md: -------------------------------------------------------------------------------- 1 | 2 | # 最小实现 3 | 4 | ## 目标 5 | 6 | 创建可执行文件,打印`Hello World` 7 | 8 | ## 源文件 9 | 10 | ``` 11 | #include 12 | 13 | int main() { 14 | std::cout << "Hello, World!" << std::endl; 15 | return 0; 16 | } 17 | ``` 18 | 19 | ## CMakeList.txt 20 | 21 | ``` 22 | cmake_minimum_required(VERSION 3.16.0) 23 | project(hello) 24 | 25 | set(CMAKE_CXX_STANDARD 11) 26 | 27 | add_executable(hello main.cpp) 28 | ``` 29 | 30 | ## 目录结构 31 | 32 | ``` 33 | . 34 | ├── CMakeLists.txt 35 | └── main.cpp 36 | ``` 37 | 38 | ## 编译&运行 39 | 40 | ``` 41 | $ cmake . 42 | -- The C compiler identification is GNU 7.5.0 43 | -- The CXX compiler identification is GNU 7.5.0 44 | -- Check for working C compiler: /usr/bin/cc 45 | -- Check for working C compiler: /usr/bin/cc -- works 46 | -- Detecting C compiler ABI info 47 | -- Detecting C compiler ABI info - done 48 | -- Detecting C compile features 49 | -- Detecting C compile features - done 50 | -- Check for working CXX compiler: /usr/bin/c++ 51 | -- Check for working CXX compiler: /usr/bin/c++ -- works 52 | -- Detecting CXX compiler ABI info 53 | -- Detecting CXX compiler ABI info - done 54 | -- Detecting CXX compile features 55 | -- Detecting CXX compile features - done 56 | -- Configuring done 57 | -- Generating done 58 | -- Build files have been written to: /home/zj/CLionProjects/hello 59 | $ make 60 | Scanning dependencies of target hello 61 | [ 50%] Building CXX object CMakeFiles/hello.dir/main.cpp.o 62 | [100%] Linking CXX executable hello 63 | [100%] Built target hello 64 | $ ./hello 65 | Hello, World! 66 | ``` -------------------------------------------------------------------------------- /docs/cmake/opencv.md: -------------------------------------------------------------------------------- 1 | 2 | # 配置OpenCV 3 | 4 | -------------------------------------------------------------------------------- /docs/cmake/submodule.md: -------------------------------------------------------------------------------- 1 | 2 | # 子模块 3 | 4 | ## 场景 5 | 6 | 一个完整的工程中存在多个子目录,分别保存有库文件、运行文件和测试文件。分别创建三个子模块: 7 | 8 | 1. 在库目录中创建动态库 9 | 2. 在运行文件中创建可执行程序,链接动态库 10 | 3. 在测试文件中创建gtest测试程序,链接动态库 11 | 12 | ```text 13 | submodules 14 | ├── CMakeLists.txt 15 | ├── exec 16 | │   ├── CMakeLists.txt 17 | │   └── main.cc 18 | ├── libs 19 | │   ├── CMakeLists.txt 20 | │   ├── common 21 | │   │   ├── CMakeLists.txt 22 | │   │   ├── common.cc 23 | │   │   ├── common.h 24 | │   │   └── mm.h 25 | │   ├── ma 26 | │   │   ├── CMakeLists.txt 27 | │   │   ├── helloma.cc 28 | │   │   └── helloma.h 29 | │   └── mb 30 | │   ├── CMakeLists.txt 31 | │   ├── himb.cc 32 | │   └── himb.h 33 | └── tests 34 | └── CMakeLists.txt 35 | ``` 36 | 37 | ## 实现 38 | 39 | * [cmakes/submodules](https://github.com/ZJDoc/VisionGuide/tree/master/cmakes/submodules) 40 | 41 | ## 相关阅读 42 | 43 | * [CMake多模块的构建方式](https://www.leadroyal.cn/p/781/) 44 | * [CMake应用:模块化及库依赖](https://zhuanlan.zhihu.com/p/373363335) 45 | * [Subdirectories, spliting code in CMake](https://codeiter.com/en/posts/subdirectories-spliting-code-in-cmake) 46 | * [CMake 管理多项目](https://zcteo.top/blog/CMake/002_CmakeMultiproject.html) 47 | * [使用子工程CMake](https://sfumecjf.github.io/cmake-examples-Chinese/02-sub-projects/A-basic/) -------------------------------------------------------------------------------- /docs/cplusplus/C++标准.md: -------------------------------------------------------------------------------- 1 | 2 | # C++标准 3 | 4 | 参考:[C++ 的历史](https://zh.cppreference.com/w/cpp/language/history) 5 | 6 | `C++`标准一直在进步,从远到近有以下版本: 7 | 8 | * `C++98` 9 | * `C++03` 10 | * `C++11` 11 | * `C++14` 12 | * `C++17` 13 | * `C++20` 14 | 15 | ## 使用哪个标准 16 | 17 | 之前编译`OpenCV 4.0`的时候,发现其中一个新特征就是完全符合`C++11`标准,所以当前学习和使用`C++11`标准 -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/imgs/access_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/advanced/class/imgs/access_control.png -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/imgs/base_access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/advanced/class/imgs/base_access.png -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/imgs/multiple_inheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/advanced/class/imgs/multiple_inheritance.png -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/static成员.md: -------------------------------------------------------------------------------- 1 | 2 | # static成员 3 | 4 | 参考:[Static Members (C++)](https://docs.microsoft.com/en-us/cpp/cpp/static-members-cpp?view=vs-2019) 5 | 6 | 类可以包含静态成员数据和成员函数。当一个数据成员声明为静态时,该类的所有对象只维护一个数据副本 7 | 8 | 静态数据成员不是给定类类型的对象的一部分。因此,静态数据成员的声明不被视为定义。数据成员在类作用域中声明,但定义在文件作用域中执行。这些静态成员具有外部链接。以下示例说明了这一点: 9 | 10 | ## 使用 11 | 12 | 可以引用静态数据成员而不引用类类型的对象 13 | 14 | ``` 15 | long nBytes = BufferedOutput::bytecount; 16 | ``` 17 | 18 | 也可以通过类对象引用 19 | 20 | ``` 21 | BufferedOutput Console; 22 | long nBytes = Console.bytecount; 23 | ``` 24 | 25 | ## 访问规则 26 | 27 | 静态数据成员受类成员访问规则的约束。对于私有定义的静态数据成员而言,只允许类成员函数和友元函数进行私有访问。例外情况是,不管静态数据成员的访问限制如何,都必须在文件作用域中定义它们。如果要显式初始化数据成员,则必须为该定义提供初始值设定项 -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/嵌套类定义.md: -------------------------------------------------------------------------------- 1 | 2 | # 嵌套类定义 3 | 4 | 参考:[Nested Class Declarations](https://docs.microsoft.com/en-us/cpp/cpp/nested-class-declarations?view=vs-2019) 5 | 6 | ## 声明 7 | 8 | 一个类可以在另一个类的范围内声明,这样的类称为`嵌套类`。嵌套类被视为在封闭类的范围内,并可在该范围内使用。若要从其直接封闭作用域以外的作用域引用嵌套类,必须使用完全限定名 9 | 10 | ``` 11 | class Cls { 12 | public: 13 | class NestA { 14 | public: 15 | void print() { 16 | std::cout << "NestA" << std::endl; 17 | } 18 | }; 19 | 20 | class NestB { 21 | public: 22 | void print() { 23 | std::cout << "NestB" << std::endl; 24 | } 25 | }; 26 | 27 | void print() { 28 | NestA nestA; 29 | NestB nestB; 30 | nestA.print(); 31 | nestB.print(); 32 | std::cout << "Cls" << std::endl; 33 | } 34 | }; 35 | 36 | int main() { 37 | Cls cls; 38 | cls.print(); 39 | 40 | Cls::NestA nestA; 41 | nestA.print(); 42 | Cls::NestB nestB; 43 | nestB.print(); 44 | } 45 | ``` 46 | 47 | ## 使用 48 | 49 | * 对于封闭类中的成员/函数,嵌套类可以直接使用 50 | * 对于其他类的成员/函数,必须通过指针、引用或对象名来使用 51 | * 对于嵌套类的友元函数,其仅能访问嵌套类,不能访问封闭类 -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/析构器.md: -------------------------------------------------------------------------------- 1 | 2 | # 析构器 3 | 4 | 参考:[Destructors (C++)](https://docs.microsoft.com/en-us/cpp/cpp/destructors-cpp?view=vs-2019) 5 | 6 | 当对象超出作用域时,自动调用析构器进行删除 7 | 8 | ## 声明 9 | 10 | * 不接受参数 11 | * 不返回值 12 | * 无法声明为`const,volatile`或`static` 13 | * 可以声明为`virtual`。使用虚拟析构函数,可以在不知道对象类型的情况下销毁对象 - 使用虚拟函数机制调用对象的正确析构函数。注意,析构函数也可以声明为抽象类的纯虚拟函数 14 | 15 | ## 使用 16 | 17 | 当以下事件发生时调用析构器: 18 | 19 | * 具有块作用域的本地(自动)对象超出作用域 20 | * 使用`new`运算符分配的对象使用`delete`显式释放 21 | * 临时对象的生存期结束 22 | * 程序结束后为全局或静态对象调用析构器 23 | * 使用析构函数的完全限定名显式调用 24 | 25 | 使用限制如下: 26 | 27 | * 无法获取析构器地址 28 | * 派生类无法继承基类的析构器 29 | 30 | ## 调用顺序 31 | 32 | * 首先调用对象类的析构器,执行函数体 33 | * `nonstatic`成员对象的析构器以声明的相反顺序调用 34 | * 以声明的相反顺序调用非虚拟基类的析构器 35 | * 以声明的相反顺序调用虚拟基类的析构器 36 | 37 | ### 虚拟基类 38 | 39 | 虚拟基类的析构函数的调用顺序与它们在有向无环图中的出现顺序相反(深度优先、从左到右、后序遍历)。下图描述了继承关系图 40 | 41 | ![](https://docs.microsoft.com/en-us/cpp/cpp/media/vc392j1.gif?view=vs-2019) 42 | 43 | ``` 44 | class A 45 | class B 46 | class C : virtual public A, virtual public B 47 | class D : virtual public A, virtual public B 48 | class E : public C, public D, virtual public B 49 | ``` 50 | 51 | 首先`C/D`是非虚拟基类调用,非虚拟基类的析构函数的调用顺序与基类名称的声明顺序相反;然后才是虚拟基类的析构器调用。销毁顺序为`E->D->C->B->A` 52 | 53 | ## 显式析构调用 54 | 55 | ``` 56 | s.String::~String(); // non-virtual call 57 | ps->String::~String(); // non-virtual call 58 | 59 | s.~String(); // Virtual call 60 | ps->~String(); // Virtual call 61 | ``` 62 | 63 | 对未定义析构函数的显式调用没有任何效果 -------------------------------------------------------------------------------- /docs/cplusplus/advanced/class/类、结构体和共同体.md: -------------------------------------------------------------------------------- 1 | 2 | # 类、结构体和共同体 3 | 4 | 类、结构体和共同体是`3`种类的类型,分别通过关键字`class、struct`和`union`定义 5 | 6 | ## 类 vs. 结构体 7 | 8 | 这两个构造在`C++`中是相同的,除了在结构中默认的可访问性是公共的,而在类中默认是私有的 9 | 10 | 类和结构体是用于自定义类型的构造。类和结构体都可以包含数据成员和成员函数,能够描述类型的状态和行为 11 | 12 | ## 访问控制和限制 13 | 14 | 类、结构体和共同体的访问控制(`access control`)和限制(`constraint`)有所差异。如下图所示: 15 | 16 | ![](./imgs/access_control.png) 17 | 18 | * 就访问控制而言,结构体和共同体默认访问权限是`public`,而类的访问权限是`private` 19 | * 就访问限制而言,结构体和类没有任何限制,而共同体每次只能使用一个成员 20 | -------------------------------------------------------------------------------- /docs/cplusplus/advanced/reference/引用概述.md: -------------------------------------------------------------------------------- 1 | 2 | # 引用概述 3 | 4 | 参考:[References (C++)](https://docs.microsoft.com/en-us/cpp/cpp/references-cpp?view=vs-2019) 5 | 6 | ## 引用 vs. 指针 7 | 8 | 引用(`reference`)相对于指针(`pointer`)而言,有如下异同: 9 | 10 | 1. 相似:存储其他对象的内存地址 11 | 2. 不同:初始化后的引用不能引用其他对象或设置为空 12 | 13 | ## lvalue和rvalue 14 | 15 | 引用可分为左值引用(`lvalue`)和右值引用(`rvalue`): 16 | 17 | 1. `lvalue`引用命名变量,用符号`&`表示 18 | 2. `rvalue`引用临时对象,用符号`&&`表示 19 | 20 | ## 语法 21 | 22 | 通用语法如下: 23 | 24 | ``` 25 | [storage-class-specifiers] [cv-qualifiers] type-specifiers declarator [= expression]; 26 | ``` 27 | 28 | 简化语法如下: 29 | 30 | ``` 31 | [storage-class-specifiers] [cv-qualifiers] type-specifiers [& or &&] [cv-qualifiers] identifier [= expression]; 32 | ``` 33 | 34 | 引用声明顺序如下: 35 | 36 | 1. 说明符 37 | * 可选的存储类说明符 38 | * 可选的`cv`限定符 39 | * 类说明符:类名 40 | 2. 声明符 41 | * `&`或者`&&`运算符 42 | * 可选的`cv`限定符 43 | * 标识符 44 | 3. 可选的初始化器 45 | 46 | 引用类型的声明必须包含初始化器,以下情况除外: 47 | 48 | * 显式`extern`声明 49 | * 类成员的声明 50 | * 类内声明 51 | * 函数的参数或函数的返回类型声明 52 | 53 | ## 示例 54 | 55 | 引用对象拥有对象的地址,但其操作和对象一样,可看成是对象的别名 56 | 57 | ``` 58 | struct S { 59 | short i; 60 | }; 61 | 62 | int main() { 63 | S s; // Declare the object. 64 | S &SRef = s; // Declare the reference. 65 | 66 | cout << (void *) &s << endl; 67 | cout << (void *) &SRef << endl; 68 | 69 | // 已初始化的引用不能引用其他对象 70 | S ss; 71 | SRef = ss; 72 | 73 | cout << (void *) &s << endl; 74 | cout << (void *) &ss << endl; 75 | cout << (void *) &SRef << endl; 76 | } 77 | ``` 78 | 79 | 结果: 80 | 81 | ``` 82 | 0x7ffc568084d0 83 | 0x7ffc568084d0 84 | 0x7ffc568084d0 // s 85 | 0x7ffc568084e0 // ss 86 | 0x7ffc568084d0 // SRef 87 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/reference/引用类型函数操作.md: -------------------------------------------------------------------------------- 1 | 2 | # 引用类型函数操作 3 | 4 | 引用可作用于函数参数和函数返回值 5 | 6 | ## 引用类型函数参数 7 | 8 | 参考:[Reference-Type Function Arguments](https://docs.microsoft.com/en-us/cpp/cpp/reference-type-function-arguments?view=vs-2019) 9 | 10 | 将引用作为函数参数,通过传递对象地址的方式进行对象访问,避免对象复制带来的额外开销,通常比直接输入对象更有效 11 | 12 | ### 语法 13 | 14 | 分两种情况,一是函数能够**修改**对象信息,而是函数能够**访问**对象信息 15 | 16 | ``` 17 | // 可修改 18 | ret-type func(type& declarator); 19 | // 可访问 20 | ret-type func(const type& declarator); 21 | ``` 22 | 23 | ## 引用类型函数返回值 24 | 25 | 参考:[Reference-Type Function Returns](https://docs.microsoft.com/en-us/cpp/cpp/reference-type-function-returns?view=vs-2019) 26 | 27 | 正如通过引用将大对象传递给函数更有效一样,通过引用从函数返回大对象也更有效。引用返回协议消除了在返回之前将对象复制到临时位置的必要性 28 | 29 | 将引用作为函数返回值有以下要求: 30 | 31 | 1. 函数返回类型一定是`lvalue` 32 | 2. 当函数返回时,引用的对象不能超出其作用域范围 33 | 34 | ### 示例 35 | 36 | ``` 37 | struct S { 38 | short i; 39 | }; 40 | 41 | S &f(S &s) { 42 | // S s; 43 | s.i = 333; 44 | 45 | cout << (void *) &s << endl; 46 | 47 | return s; 48 | } 49 | 50 | int main() { 51 | S a; 52 | 53 | S &s = f(a); 54 | 55 | cout << (void *) &s << endl; 56 | } 57 | ``` 58 | 59 | 在`main`函数内将结构体对象`a`输入函数`f`,再返回其引用到`main`函数,赋值给引用对象`s` 60 | 61 | **注意:此时对象`a`的作用域是`main`函数,所以函数返回时没有超出其作用域** -------------------------------------------------------------------------------- /docs/cplusplus/advanced/reference/指针引用.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针引用 3 | 4 | 参考:[References to pointers](https://docs.microsoft.com/en-us/cpp/cpp/references-to-pointers?view=vs-2019) 5 | 6 | 对指针的引用(`Reference to pointer`)可以用与对对象的引用(`reference to object`)几乎相同的方式声明。指针的引用是一个可修改的值,可以像普通指针一样使用 7 | 8 | ## 示例 9 | 10 | ``` 11 | void f(int *&b) { 12 | for (int i = 0; i < 10; i++) { 13 | cout << b[i] << " "; 14 | b[i] = 10 - i; 15 | } 16 | cout << endl; 17 | } 18 | 19 | int main(int argc, char *argv[]) { 20 | int *a; 21 | // 指针引用b和指针a指向同一个地址 22 | int *&b = a; 23 | 24 | b = new int[10]; 25 | for (int i = 0; i < 10; i++) { 26 | b[i] = i; 27 | } 28 | 29 | cout << (void *) a << endl; 30 | cout << (void *) b << endl; 31 | 32 | f(b); 33 | for (int i = 0; i < 10; i++) { 34 | cout << a[i] << " "; 35 | } 36 | } 37 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/smart-pointer/imgs/shared_ptr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/advanced/smart-pointer/imgs/shared_ptr.png -------------------------------------------------------------------------------- /docs/cplusplus/advanced/smart-pointer/imgs/unique_ptr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/advanced/smart-pointer/imgs/unique_ptr.png -------------------------------------------------------------------------------- /docs/cplusplus/advanced/smart-pointer/weak_ptr.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11]weak_ptr 3 | 4 | 参考:[How to: Create and Use weak_ptr Instances](https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-weak-ptr-instances?view=vs-2019) 5 | 6 | `weak_ptr`是为了避免`shared_ptr`出现循环引用(`cyclic reference`)问题而设计的 7 | 8 | `weak_ptr`实例本身不拥有内存资源,它只能指向`shared_ptr`实例保存的共享资源,所以本身不参与引用计数,因此它不能防止引用计数变为零。使用`weak_ptr`实例时,需要先转换成`shared_ptr`实例,再进行访问;当引用计数为`0`时,内存会被删除,此时调用`weak_ptr`有可能会引发`bad_weak_ptr`异常 9 | 10 | *`weak_ptr`类似于`Java`的弱引用,一方面能够保证避免循环引用问题,另一方面能够保证资源及时销毁,避免内存泄漏* 11 | 12 | ## 成员函数 13 | 14 | * [expired](http://www.cplusplus.com/reference/memory/weak_ptr/expired/):是否`weak_ptr`对象为空或者和它相关的`shared_ptr`对象不存在 15 | * [lock](http://www.cplusplus.com/reference/memory/weak_ptr/lock/):返回一个`shared_ptr`对象,如果`weak_ptr`已经失效(`expired`),返回一个空指针的`shared_ptr` 16 | * [use_count](http://www.cplusplus.com/reference/memory/weak_ptr/use_count/):`weak_ptr`对象所属的`shared_ptr`的引用计数 17 | * [reset](http://www.cplusplus.com/reference/memory/weak_ptr/reset/):设置`weak_ptr`对象为空 18 | * [swap](http://www.cplusplus.com/reference/memory/weak_ptr/swap/):交换两个`weak_ptr`对象的内容,包括所属组 19 | 20 | ## 创建 21 | 22 | ``` 23 | template 24 | struct array_deleter { 25 | void operator()(T const *p) { 26 | delete[] p; 27 | } 28 | }; 29 | 30 | int main() { 31 | // 创建整型数组 32 | std::shared_ptr ints(new int[10], array_deleter()); 33 | for (int i = 0; i < 5; i++) { 34 | ints.get()[i] = i; 35 | } 36 | 37 | // 创建weak_ptr 38 | std::weak_ptr wints(ints); 39 | 40 | cout << wints.use_count() << endl; 41 | cout << wints.expired() << endl; 42 | 43 | auto sptr = wints.lock(); 44 | for (int i = 0; i < 5; i++) { 45 | cout << sptr.get()[i] << endl; 46 | } 47 | } 48 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/smart-pointer/使用原始指针还是智能指针.md: -------------------------------------------------------------------------------- 1 | 2 | # 使用原始指针还是智能指针 3 | 4 | 参考:[C++智能指针的正确使用方式](https://cloud.tencent.com/developer/article/1517336) 5 | 6 | 智能指针能够自动操作内存分配和删除,所以相比较于指针而言,其更能够确保内存和资源不被泄漏 7 | 8 | 不过由于智能指针额外增加了对内存和引用的操作,所以性能上会弱于原始指针操作 9 | 10 | 使用关键在于是否需要关心指针内存: 11 | 12 | * 如果指向已有数组和对象,不需要指针进行内存管理,那么应该使用原始指针 13 | * 对于使用`new`关键字进行显式内存分配的指针而言,因为需要指针自己完成内存新建和删除操作,所以使用智能指针更加安全 -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/[shuffle]随机重排列.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl][shuffle]随机重排列 3 | 4 | 参考:[std::shuffle](http://www.cplusplus.com/reference/algorithm/shuffle/) 5 | 6 | `c++`实现了`shuffle`函数用于随机重新排列指定范围内的元素,使用均匀随机数发生器 7 | 8 | ``` 9 | // shuffle algorithm example 10 | #include // std::cout 11 | #include // std::shuffle 12 | #include // std::array 13 | #include // std::default_random_engine 14 | #include // std::chrono::system_clock 15 | 16 | int main() { 17 | std::array foo{1, 2, 3, 4, 5}; 18 | 19 | // obtain a time-based seed: 20 | long seed = std::chrono::system_clock::now().time_since_epoch().count(); 21 | 22 | shuffle(foo.begin(), foo.end(), std::default_random_engine(seed)); 23 | 24 | std::cout << "shuffled elements:"; 25 | for (int &x: foo) std::cout << ' ' << x; 26 | std::cout << '\n'; 27 | 28 | return 0; 29 | } 30 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/find.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl]find 3 | 4 | 参考:[std::find](http://www.cplusplus.com/reference/algorithm/find/) 5 | 6 | `C++`提供了丰富的查询函数 7 | 8 | * `find` 9 | * `find_end` 10 | * `find_first_of` 11 | * `find_if` 12 | * `find_if_not` 13 | 14 | ## find_if 15 | 16 | 参考:[std::find_if](http://www.cplusplus.com/reference/algorithm/find_if/) 17 | 18 | 函数`find_if`发现指定范围内(不包含最后一个位置)是否存在数值符合条件 19 | 20 | 如果存在,返回第一个符合条件的迭代器;如果不存在,返回最后一个值的迭代器 21 | 22 | ``` 23 | // find_if example 24 | #include // std::cout 25 | #include // std::find_if 26 | #include // std::vector 27 | 28 | bool IsOdd(int i) { 29 | return ((i % 2) == 1); 30 | } 31 | 32 | int main() { 33 | std::vector myvector; 34 | 35 | myvector.push_back(10); 36 | myvector.push_back(25); 37 | myvector.push_back(40); 38 | myvector.push_back(55); 39 | 40 | std::vector::iterator it = std::find_if(myvector.begin(), myvector.end(), IsOdd); 41 | std::cout << "The first odd value is " << *it << '\n'; 42 | 43 | return 0; 44 | } 45 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/for_each.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl]for_each 3 | 4 | 参考:[std::for_each](http://www.cplusplus.com/reference/algorithm/for_each/?kw=for_each) 5 | 6 | 使用`for_each`函数对指定范围内的数值逐个进行函数操作 7 | 8 | 最常用的就是遍历操作 9 | 10 | ``` 11 | #include // std::cout 12 | #include // std::for_each 13 | #include // std::vector 14 | 15 | void myfunction(int i) { // function: 16 | std::cout << ' ' << i; 17 | } 18 | 19 | struct myclass { // function object type: 20 | void operator()(int i) { std::cout << ' ' << i; } 21 | } myobject; 22 | 23 | int main() { 24 | std::vector myvector; 25 | myvector.emplace_back(10); 26 | myvector.emplace_back(20); 27 | myvector.emplace_back(30); 28 | 29 | std::cout << "myvector contains:"; 30 | for_each(myvector.begin(), myvector.end(), myfunction); 31 | std::cout << '\n'; 32 | 33 | // or: 34 | std::cout << "myvector contains:"; 35 | for_each(myvector.begin(), myvector.end(), myobject); 36 | std::cout << '\n'; 37 | 38 | return 0; 39 | } 40 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/map.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl]map 3 | 4 | 参考:[std::map](http://www.cplusplus.com/reference/map/map/) 5 | 6 | `map`是存储键/值对的关联容器 7 | 8 | ## 头文件 9 | 10 | ``` 11 | #include 12 | ``` 13 | 14 | ## 使用 15 | 16 | ``` 17 | #include 18 | 19 | template 20 | void forward_print(std::map maps) { 21 | // for (auto it = maps.begin(); it != maps.end(); ++it) 22 | // std::cout << it->first << " => " << it->second << ' '; 23 | 24 | for (auto &x:maps) { 25 | std::cout << x.first << " => " << x.second << ' '; 26 | } 27 | std::cout << std::endl; 28 | } 29 | 30 | int main() { 31 | // 创建 32 | std::map maps; 33 | // 添加 34 | for (int i = 0; i < 10; i++) { 35 | maps.emplace(i, i + 1); 36 | } 37 | forward_print(maps); 38 | 39 | // 修改 40 | // 第二个位置,从0开始 41 | maps[1] = 444; 42 | forward_print(maps); 43 | 44 | // 删除 45 | // 先查找再删除 46 | std::map::iterator it = maps.find(3); 47 | maps.erase(it); 48 | // 按键删除 49 | maps.erase(4); 50 | forward_print(maps); 51 | // 删除所有 52 | maps.clear(); 53 | std::cout << "size: " << maps.size() << std::endl; 54 | std::cout << "isEmpty: " << maps.empty() << std::endl; 55 | } 56 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/queue.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl]queue 3 | 4 | `c++`提供了队列的实现:[queue](http://www.cplusplus.com/reference/queue/queue/),实现先进先出(`first-in first-out, FIFO`)功能 5 | 6 | ## 创建队列 7 | 8 | 引入头文件`queue`,创建时指定数据类型: 9 | 10 | ``` 11 | #include 12 | 13 | queue q; 14 | ``` 15 | 16 | ## 队列功能 17 | 18 | `queue`提供了如下常用功能实现: 19 | 20 | * empty():判断队列是否问空,为空返回`true`,不为空返回`false` 21 | * size():返回队列长度 22 | * front():返回队头(第一个出队)数据 23 | * back():返回队尾(第一个入队)数据 24 | * push(value_type&& __x):添加数据到队尾 25 | * pop():移除队头数据。注意,返回值为空 26 | 27 | `c++11`提供了两个新特性: 28 | 29 | * [swap](http://www.cplusplus.com/reference/queue/queue/swap/):交换两个队列的值 30 | * [emplace](http://www.cplusplus.com/reference/queue/queue/emplace/):添加数据到队尾。这个新元素是就地(`in place`)构造的,它传递参数作为其构造函数的参数,可替换push操作 31 | 32 | *参考:[C++11中emplace的使用](https://blog.csdn.net/u013700358/article/details/52623985):emplace能通过参数构造对象,不需要拷贝或者移动内存,相比push能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升* 33 | 34 | ## 实现 35 | 36 | ``` 37 | #include 38 | #include 39 | using namespace std; 40 | 41 | int main() { 42 | queue q; 43 | // 队列大小 44 | cout << q.size() << endl; 45 | // 队列是否为空 46 | cout << q.empty() << endl; 47 | 48 | q.push(3); 49 | q.push(4); 50 | q.emplace(5); 51 | 52 | // 队头元素 53 | cout << q.front() << endl; 54 | // 队尾元素 55 | cout << q.back() << endl; 56 | 57 | queue s; 58 | s.push(3232); 59 | 60 | q.swap(s); 61 | cout << q.size() << endl; 62 | cout << q.empty() << endl; 63 | } 64 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/stl/stack.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11][stl]stack 3 | 4 | `c++`提供了栈的实现:[queue](http://www.cplusplus.com/reference/queue/queue/),实现后进先出(`last-in first-out, LIFO`)功能 5 | 6 | ## 创建栈 7 | 8 | 引入头文件`stack`,创建时指定数据类型: 9 | 10 | ``` 11 | #include 12 | 13 | stack s; 14 | ``` 15 | 16 | ## 栈功能 17 | 18 | `stack`提供了如下常用功能实现: 19 | 20 | * empty():判断栈是否问空,为空返回`true`,不为空返回`false` 21 | * size():返回栈长度 22 | * top():返回栈顶数据 23 | * push(value_type&& __x):插入数据到栈顶 24 | * pop():移除栈顶数据。注意,返回值为空 25 | 26 | `c++11`提供了两个新特性: 27 | 28 | * [swap](http://www.cplusplus.com/reference/stack/stack/swap/):交换两个栈的值 29 | * [emplace](http://www.cplusplus.com/reference/stack/stack/emplace/):添加数据到栈顶。这个新元素是就地(`in place`)构造的,它传递参数作为其构造函数的参数,可替换push操作 30 | 31 | *参考:[C++11中emplace的使用](https://blog.csdn.net/u013700358/article/details/52623985):emplace能通过参数构造对象,不需要拷贝或者移动内存,相比push能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升* 32 | 33 | 34 | ## 实现 35 | 36 | ``` 37 | stack s; 38 | // 栈大小 39 | cout << s.size() << endl; 40 | // 栈是否为空 41 | cout << s.empty() << endl; 42 | 43 | s.push(3); 44 | s.push(4); 45 | s.emplace(5); 46 | 47 | // 栈顶元素 48 | cout << s.top() << endl; 49 | 50 | stack s2; 51 | s2.push(3232); 52 | 53 | s2.swap(s); 54 | cout << s.size() << endl; 55 | cout << s.empty() << endl; 56 | cout << s.top() << endl; 57 | } 58 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/advanced/template/模板和名称解析.md: -------------------------------------------------------------------------------- 1 | 2 | # 模板和名称解析 3 | 4 | 参考:[Templates and Name Resolution](https://docs.microsoft.com/en-us/cpp/cpp/templates-and-name-resolution?view=vs-2019) 5 | 6 | ## 名称类型 7 | 8 | 在模板定义中分为`3`种类型名称: 9 | 10 | 1. 局部声明名称,包括模板名以及在模板定义中声明的名称 11 | 2. 模板定义之外的封闭作用域中的名称 12 | 3. 以某种方式依赖于模板参数的名称,称为依赖名称 13 | 14 | 模板的名称解析规则主要处理第三类依赖名称,因为编译器在模板被实例化之前对这些名称知之甚少,因为它们可能是完全不同的类型,具体取决于使用的模板参数 15 | 16 | 依赖名称可能使用如下几种方式定义: 17 | 18 | * 使用模板参数本身定义 19 | 20 | ``` 21 | T 22 | ``` 23 | 24 | * 限定名的限定部分包含了依赖类型 25 | 26 | ``` 27 | T::myType 28 | ``` 29 | 30 | * 限定名的非限定部分包含了依赖类型 31 | 32 | ``` 33 | N::T 34 | ``` 35 | 36 | * 基于依赖类型的`const/volatile`定义 37 | 38 | ``` 39 | const T 40 | ``` 41 | 42 | * 基于依赖类型的指针、引用、数组和函数指针类型 43 | 44 | ``` 45 | T *、T &、T [10]、T (*)() 46 | ``` 47 | 48 | * 大小基于模板参数的数组 49 | 50 | ``` 51 | template class X { 52 | int x[arg] ; // dependent type 53 | } 54 | ``` 55 | 56 | * 从模板参数构造的模板类型 57 | 58 | ``` 59 | T, MyTemplate 60 | ``` 61 | 62 | ## 类型依赖和值依赖 63 | 64 | * 依赖于类型参数的模板,称为类型依赖 65 | * 依赖于值参数的模板,称为值依赖 66 | 67 | ## 依赖类型名称解析 68 | 69 | 参考:[Name Resolution for Dependent Types](https://docs.microsoft.com/en-us/cpp/cpp/name-resolution-for-dependent-types?view=vs-2019) 70 | 71 | 在模板定义中使用`typename`作为限定名,告诉编译器给定的限定名称标识类型 72 | 73 | ``` 74 | template 75 | class X 76 | { 77 | public: 78 | typename T::myType f(typename T::myType* mt) { 79 | mt->aa = 3; 80 | return *mt; 81 | } 82 | }; 83 | 84 | class Yarg 85 | { 86 | public: 87 | struct myType { 88 | int aa; 89 | }; 90 | }; 91 | 92 | int main() 93 | { 94 | X x; 95 | Yarg::myType type = x.f(new Yarg::myType()); 96 | std::cout < 12 | using namespace std; 13 | 14 | // 人脸检测模型路径 15 | string FACE_CASCADE_PATH = "../../models/haarcascade_frontalface_default.xml"; 16 | 17 | #endif //C_MACRO_H 18 | 19 | 编译时出错 20 | 21 | CMakeFiles/c__.dir/OpencvDetect.cpp.o:(.bss+0x0): multiple definition of `WINDOWS_NAME[abi:cxx11]' 22 | CMakeFiles/c__.dir/main.cpp.o:(.bss+0x0): first defined here 23 | 24 | ## 问题解析 25 | 26 | 头文件被多次引用,导致重复定义 27 | 28 | 解决:设置成常量,添加`const`关键字 29 | 30 | const string FACE_CASCADE_PATH = "../../models/haarcascade_frontalface_default.xml"; -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/imgs/Comp-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/get-started/basic-concepts/imgs/Comp-link.png -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/imgs/include.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/get-started/basic-concepts/imgs/include.png -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/imgs/overloading_consideration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/get-started/basic-concepts/imgs/overloading_consideration.png -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/临时对象.md: -------------------------------------------------------------------------------- 1 | 2 | # 临时对象 3 | 4 | 参考: 5 | 6 | [Temporary Objects](https://docs.microsoft.com/en-us/cpp/cpp/temporary-objects?view=vs-2019) 7 | 8 | [c++ 临时变量问题?](https://www.zhihu.com/question/41137408) 9 | 10 | 临时对象的创建有如下原因: 11 | 12 | * 要初始化一个`const`引用,但是其初始化器的类型不同于引用的基础类型 13 | * 存储返回用户定义类型的函数返回值 14 | 15 | * 只有当程序不会将返回值复制到对象时,才会创建这些临时文件 16 | 17 | // 函数声明,使用自定义类型作为返回值 18 | UDT Func1(); 19 | ... 20 | // 调用该函数,不接受返回值。此时编译器创建一个临时对象来保存返回值 21 | Func1(); 22 | 23 | * 创建临时变量的更常见情况是在表达式的计算过程中,必须调用重载的运算符函数。这些重载的运算符函数返回一个用户定义的类型,该类型通常不会复制到另一个对象 24 | 25 | class Complex { 26 | 27 | public: 28 | Complex(int num) : num(num) {} 29 | 30 | Complex operator+(Complex &other) { 31 | return Complex{this->getNum() + other.getNum()}; 32 | } 33 | 34 | int getNum() { 35 | return num; 36 | } 37 | 38 | private: 39 | int num; 40 | }; 41 | 42 | int main() { 43 | Complex complex1(1), complex2(2), complex3(3); 44 | // complex1和complex2的加法结果被存储在一个临时对象tmp中 45 | // tmp再继续和complex3进行加法计算,将结果复制到result 46 | Complex result = complex1 + complex2 + complex3; 47 | 48 | cout << result.getNum() << endl; 49 | } 50 | 51 | * 将强制转换的结果存储到用户定义的类型。当给定类型的对象显式转换为用户定义的类型时,该新对象将被构造为临时对象 -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/声明和定义.md: -------------------------------------------------------------------------------- 1 | 2 | # 声明和定义 3 | 4 | 参考: 5 | 6 | [Declarations and Definitions (C++)](https://docs.microsoft.com/en-us/cpp/cpp/declarations-and-definitions-cpp?view=vs-2019) 7 | 8 | [Declarations, Prototypes, Definitions, and Implementations](http://www.cplusplus.com/articles/yAqpX9L8/) 9 | 10 | ## 声明和定义 11 | 12 | * 声明(`declaration`)用于为程序引入名称 13 | * 定义(`definition`)是在内存中创建实体位置 14 | 15 | 声明通常可看成定义,除了以下情况: 16 | 17 | 1. 函数原型(`function prototype`):只有函数声明,没有函数体 18 | 2. 包含`extern`标识符,同时没有初始化值(对于对象和变量而言)或没有函数体(对于函数而言)。这意味着不一定在当前单元进行定义,给予其外部链接 19 | 3. 类声明中的静态数据成员:因为静态类数据成员是类中所有对象共享的离散变量,所以必须在类声明之外定义和初始化它们 20 | 4. 不包含定义的类声明,比如`class T;` 21 | 5. `typedef`表达式 22 | 23 | 声明后都需要进行定义,除了以下两种情况: 24 | 25 | 1. 函数已声明,但从未被函数调用或者被表达式引用其地址 26 | 2. 类的使用方式不需要知道其定义,但是必须声明类。比如 27 | 28 | ``` 29 | class WindowCounter; // Forward declaration; no definition 30 | 31 | class Window 32 | { 33 | // Definition of WindowCounter not required 34 | static WindowCounter windowCounter; 35 | }; 36 | 37 | int main() 38 | { 39 | } 40 | ``` 41 | 42 | ## 为什么要区分声明和定义 43 | 44 | 从源文件编译得到程序可分为两个过程:编译(`compile`)和链接(`link`) 45 | 46 | ![](./imgs/Comp-link.png) 47 | 48 | * 编译阶段:独立编译每一个`.cpp`文件。将所有`#include`文件插入到`.cpp`中,然后从头到尾进行编译,生成机器码输出为`.obj`文件 49 | * 链接阶段:组合所有`.obj`文件,生成内存寻址以及函数调用,最后输出一个可执行程序 50 | 51 | 在编译阶段编译器只需要知道函数参数类型以及返回值类型即可,不关心具体实现过程 52 | 53 | 所以声明作用于编译阶段,定义作用于链接阶段 54 | 55 | ## 使用声明和定义 56 | 57 | 在编译阶段编译器从头到尾处理`.cpp`文件,所以在使用变量、函数等名称之前必须有声明,有两种方式: 58 | 59 | 1. 前向声明(`Forward declaration`):仅包含声明,在之后进行定义(**推荐**) 60 | 2. 在使用之前同时进行声明和定义 -------------------------------------------------------------------------------- /docs/cplusplus/get-started/basic-concepts/指针引用.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针引用 3 | 4 | 参考:[References to pointers](https://docs.microsoft.com/en-us/cpp/cpp/references-to-pointers?view=vs-2019) 5 | 6 | 对指针的引用(`Reference to pointer`)可以用与对对象的引用(`reference to object`)几乎相同的方式声明。指针的引用是一个可修改的值,可以像普通指针一样使用 7 | 8 | ## 示例 9 | 10 | ``` 11 | void f(int *&b) { 12 | for (int i = 0; i < 10; i++) { 13 | cout << b[i] << " "; 14 | b[i] = 10 - i; 15 | } 16 | cout << endl; 17 | } 18 | 19 | int main(int argc, char *argv[]) { 20 | int *a; 21 | // 指针引用b和指针a指向同一个地址 22 | int *&b = a; 23 | 24 | b = new int[10]; 25 | for (int i = 0; i < 10; i++) { 26 | b[i] = i; 27 | } 28 | 29 | cout << (void *) a << endl; 30 | cout << (void *) b << endl; 31 | 32 | f(b); 33 | for (int i = 0; i < 10; i++) { 34 | cout << a[i] << " "; 35 | } 36 | } 37 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/keywords/nullptr.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11]nullptr 3 | 4 | 参考:[nullptr](https://docs.microsoft.com/en-us/cpp/cpp/nullptr?view=vs-2019) 5 | 6 | `std::nullptr`是类型`std::nullptr_t`的空指针常量,可以转换成任何原始指针类型 7 | 8 | 之前通常使用`NULL`或者`0`来表示空指针,这有可能造成编译错误。从`c++11`开始推荐使用常量`std::nullptr` 9 | 10 | ## 示例一 11 | 12 | 参考:[std::nullptr_t](https://en.cppreference.com/w/cpp/types/nullptr_t) 13 | 14 | ``` 15 | void f(int *pi) { 16 | std::cout << "Pointer to integer overload\n"; 17 | } 18 | 19 | void f(double *pd) { 20 | std::cout << "Pointer to double overload\n"; 21 | } 22 | 23 | void f(std::nullptr_t nullp) { 24 | std::cout << "null pointer overload\n"; 25 | } 26 | 27 | int main() { 28 | int *pi; 29 | double *pd; 30 | 31 | f(pi); 32 | f(pd); 33 | f(nullptr); // would be ambiguous without void f(nullptr_t) 34 | // f(0); // ambiguous call: all three functions are candidates 35 | // f(NULL); // ambiguous if NULL is an integral null pointer constant 36 | // (as is the case in most implementations) 37 | } 38 | ``` 39 | 40 | 定义了三个重载函数,分别使用`int/double/nullptr_t`作为参数类型。如果输入`0`或者`NULL`作为参数,会存在二义性(`ambiguous`),因为均符合这`3`个重载函数 41 | 42 | ## 示例二 43 | 44 | 参考:[nullptr, the pointer literal](https://en.cppreference.com/w/cpp/language/nullptr) 45 | 46 | `std::nullptr`能够输入模板函数,而`0`和`NULL`会发生错误 47 | 48 | ``` 49 | template 50 | void Fwd(F f, A a) { 51 | f(a); 52 | } 53 | 54 | void g(int *i) { 55 | std::cout << "Function g called\n"; 56 | } 57 | 58 | int main() { 59 | g(NULL); // Fine 60 | g(0); // Fine 61 | 62 | Fwd(g, nullptr); // Fine 63 | // Fwd(g, NULL); // ERROR: No function g(int) 64 | } 65 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/keywords/size_t.md: -------------------------------------------------------------------------------- 1 | 2 | # size_t 3 | 4 | 参考: 5 | 6 | [size_t](http://www.cplusplus.com/reference/cstddef/size_t/?kw=size_t) 7 | 8 | [std::size_t](https://en.cppreference.com/w/cpp/types/size_t) 9 | 10 | 无符号整数值,可作为基本无符号整数类型的别名 11 | 12 | 它是一种能够以字节表示任何对象大小的类型:`size_t`是`sizeof`运算符返回的类型,在标准库中广泛用于表示大小和计数 13 | 14 | ``` 15 | #include 16 | #include 17 | #include 18 | 19 | int main() 20 | { 21 | std::array a; 22 | for (std::size_t i = 0; i != a.size(); ++i) 23 | a[i] = i; 24 | for (std::size_t i = a.size()-1; i < a.size(); --i) 25 | std::cout << a[i] << " "; 26 | } 27 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/operator-overload/下标运算符重载.md: -------------------------------------------------------------------------------- 1 | 2 | # 下标运算符重载 3 | 4 | 下标运算符`operator[]`和函数调用运算符类似,也是二元运算符。除了二元运算符的规范外,下标运算符必须是**非静态成员函数** 5 | 6 | ## 示例 7 | 8 | ``` 9 | class IntVector { 10 | public: 11 | IntVector(int cElements); 12 | 13 | ~IntVector() { delete[] _iElements; } 14 | 15 | int &operator[](int nSubscript); 16 | 17 | private: 18 | int *_iElements; 19 | int _iUpperBound; 20 | }; 21 | 22 | // Construct an IntVector. 23 | IntVector::IntVector(int cElements) { 24 | _iElements = new int[cElements]; 25 | _iUpperBound = cElements; 26 | } 27 | 28 | // Subscript operator for IntVector. 29 | int &IntVector::operator[](int nSubscript) { 30 | static int iErr = -1; 31 | 32 | if (nSubscript >= 0 && nSubscript < _iUpperBound) 33 | return _iElements[nSubscript]; 34 | else { 35 | cout << "Array bounds violation." << endl; 36 | return iErr; 37 | } 38 | } 39 | 40 | // Test the IntVector class. 41 | int main() { 42 | IntVector v(10); 43 | int i; 44 | 45 | for (i = 0; i <= 10; ++i) 46 | v[i] = i; 47 | 48 | v[3] = v[9]; 49 | 50 | for (i = 0; i <= 10; ++i) 51 | cout << "Element: [" << i << "] = " << v[i] << endl; 52 | } 53 | ``` 54 | 55 | 结果 56 | 57 | ``` 58 | Array bounds violation. 59 | Array bounds violation. 60 | Element: [0] = 0 61 | Element: [1] = 1 62 | Element: [2] = 2 63 | Element: [3] = 9 64 | Element: [4] = 4 65 | Element: [5] = 5 66 | Element: [6] = 6 67 | Element: [7] = 7 68 | Element: [8] = 8 69 | Element: [9] = 9 70 | Array bounds violation. 71 | Element: [10] = 10 72 | ``` 73 | 74 | * 重载下标运算符函数返回的是左值引用,所以可用于等号左右侧 75 | * 当下标值为`10`时,超出了数组界限,返回静态`int`值引用并赋值为`10`,所以之后调用过程中超出数组界限的返回值为`10` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/operator-overload/二元运算符重载.md: -------------------------------------------------------------------------------- 1 | 2 | # 二元运算符重载 3 | 4 | 参考:[Binary Operators](https://docs.microsoft.com/en-us/cpp/cpp/binary-operators?view=vs-2019) 5 | 6 | 二元运算符重载和一元运算符重载类似,区别仅在于参数个数 7 | 8 | ## 二元运算符 9 | 10 | 可被重定义的二元运算符:[Redefinable Binary Operators](https://docs.microsoft.com/en-us/cpp/cpp/binary-operators?view=vs-2019#redefinable-binary-operators) 11 | 12 | ## 语法 13 | 14 | ``` 15 | // 非静态成员函数 16 | ret-type operator op(arg) 17 | // 全局函数 18 | ret-type operator op(arg1, arg2) 19 | ``` 20 | 21 | * `ret-type`表示返回值 22 | * `op`表示运算符号 23 | * `arg_`表示参数 24 | 25 | 对二元运算符的返回类型没有限制,通常返回类类型或对类类型的引用 -------------------------------------------------------------------------------- /docs/cplusplus/get-started/operator-overload/函数调用运算符重载.md: -------------------------------------------------------------------------------- 1 | 2 | # 函数调用运算符重载 3 | 4 | ## 语法 5 | 6 | 函数调用运算符`operator()`是一个二元运算符,语法如下: 7 | 8 | ``` 9 | primary-expression ( expression-list ) 10 | ``` 11 | 12 | * `primary-expression`是第一个操作数 13 | * `expression-list`是第二个操作数,有可能为空的参数列表 14 | 15 | **注意 1:函数调用运算符重载必须是非静态成员函数** 16 | 17 | **注意 2:函数调用运算符是应用于对象,而不是函数** 18 | 19 | ## 示例 20 | 21 | 定义类`Point`,重定义函数调用运算符 22 | 23 | ``` 24 | class Point { 25 | public: 26 | Point() { _x = _y = 0; } 27 | 28 | Point &operator()(int dx, int dy) { 29 | _x += dx; 30 | _y += dy; 31 | return *this; 32 | } 33 | 34 | inline void print() { 35 | cout << "_x = " << _x << " _y = " << _y << endl; 36 | } 37 | 38 | private: 39 | int _x, _y; 40 | }; 41 | 42 | int main() { 43 | Point pt; 44 | 45 | pt.print(); 46 | pt(3, 2); 47 | pt.print(); 48 | } 49 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/operator-overload/赋值运算符重载.md: -------------------------------------------------------------------------------- 1 | 2 | # 赋值运算符重载 3 | 4 | 参考:[Assignment](https://docs.microsoft.com/en-us/cpp/cpp/assignment?view=vs-2019) 5 | 6 | ## 规范 7 | 8 | 赋值运算符(`operator=`)是二元运算符,除了遵循二元运算符的规范外,还有以下限制: 9 | 10 | 1. 必须是非静态成员函数 11 | 2. 无法被派生类继承 12 | 3. 如果不存在,默认的`opeator=`函数会被编译器生成 13 | 14 | ## 赋值 vs. 复制 15 | 16 | 赋值(`copy assignment`)运算和复制(`copy`)操作有区别,后者在新对象构造期间调用 17 | 18 | ``` 19 | // Copy constructor is called--not overloaded copy assignment operator! 20 | Point pt3 = pt1; 21 | 22 | // The previous initialization is similar to the following: 23 | Point pt4(pt1); // Copy constructor call. 24 | ``` 25 | 26 | **最佳实践:定义赋值运算的同时定义复制构造器和析构器** 27 | 28 | ## 示例 29 | 30 | 定义类`Point`,重载赋值运算符,重载复制构造器和析构器 31 | 32 | ``` 33 | class Point { 34 | public: 35 | Point(int x, int y) : _x{x}, _y{y} {} 36 | 37 | Point() : _x(0), _y(0) {} 38 | 39 | Point(const Point &point) : _x{point._x}, _y{point._y} {} 40 | 41 | // Right side of copy assignment is the argument. 42 | Point &operator=(const Point &); 43 | 44 | inline void print() { 45 | cout << "x = " << _x << " y = " << _y << endl; 46 | } 47 | 48 | private: 49 | int _x, _y; 50 | }; 51 | 52 | // Define copy assignment operator. 53 | Point &Point::operator=(const Point &otherPoint) { 54 | _x = otherPoint._x; 55 | _y = otherPoint._y; 56 | 57 | // Assignment operator returns left side of assignment. 58 | return *this; 59 | } 60 | 61 | int main() { 62 | Point pt1{2, 3}, pt2{3, 5}; 63 | 64 | // 使用复制构造器 65 | Point pt3(pt2); 66 | pt3.print(); 67 | 68 | // 使用赋值运算符 69 | pt1 = pt2; 70 | pt1.print(); 71 | } 72 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/二维数组和二级指针.md: -------------------------------------------------------------------------------- 1 | 2 | # 二维数组和二级指针 3 | 4 | * 二维数组是指向数组的数组 5 | * 二级指针是指向指针的指针 6 | 7 | 一维数组名可以赋值给一级指针,但是二级数组名不可以赋值给二级指针 8 | 9 | 参考:[二维数组名不能赋值给二级指针](https://zhidao.baidu.com/question/1512707882225632860.html?qbl=relate_question_0&word=c%2B%2B%20%CE%AA%CA%B2%C3%B4%B6%FE%BC%B6%D6%B8%D5%EB%B2%BB%C4%DC%B8%B3%D6%B5%B8%F8%B6%FE%BC%B6%CA%FD%D7%E9) 10 | 11 | ``` 12 | const int LENGTH = 3; 13 | const int WIDTH = 2; 14 | 15 | int arr[LENGTH][WIDTH]={}; 16 | int **p; 17 | 18 | p = arr; // Assigning to 'int **' from incompatible type 'int [3][2]' 19 | ``` 20 | 21 | * 对于二维指针`p`而言,其声明为`int*`类型的一维指针 22 | * 对于二维数组`arr`而言,其声明为`int[4]`类型的一维数组 23 | 24 | 因为两者声明类型不一致,所以无法兼容。如果将`p`定义为数组指针即可操作 25 | 26 | ``` 27 | char (*p2)[WIDTH] = arr; 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/原始数组.md: -------------------------------------------------------------------------------- 1 | 2 | # 原始数组 3 | 4 | ``` 5 | const int LENGTH = 3; 6 | const int WIDTH = 10; 7 | const int HEIGHT = 5; 8 | 9 | int a1[LENGTH] = {1, 2, 3}; 10 | int a2[LENGTH][WIDTH]{}; 11 | int a3[LENGTH][WIDTH][HEIGHT]{}; 12 | ``` 13 | 14 | 通过列表进行初始化 15 | -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/指针名和数组名的区别.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针名和数组名的区别 3 | 4 | 参考: 5 | 6 | [指针和数组的区别](https://blog.csdn.net/u012124564/article/details/47323817) 7 | 8 | [c中,数组名跟指针有区别吗?](https://www.zhihu.com/question/41805285) 9 | 10 | 有如下区别: 11 | 12 | 1. 可以用数组名初始化指针,但是数组名必须用列表进行初始化 13 | 2. 数组名指向固定内存地址,不能修改,而指针名可以指向其他地址 14 | 3. 使用`sizeof`计算两者所占的内存字节数,数组名返回整个数组所占字节数,而指针名返回单个地址的字节大小(当前`CPU`的最大位数:`8`字节) 15 | 16 | 测试代码如下: 17 | 18 | ``` 19 | int arr[3] = {1, 2, 3}; 20 | int *p = arr; 21 | 22 | cout << arr << endl; 23 | cout << p << endl; 24 | 25 | cout << arr[1] << endl; 26 | cout << *(p + 1) << endl; 27 | 28 | cout << sizeof(arr) << endl; 29 | cout << sizeof(p) << endl; 30 | ``` 31 | 32 | * 新建整型数组`arr`并初始化 33 | * 新建整型指针`p`,指向数组`arr` 34 | * 打印数组名和指针名,此时两者均指向数组首地址 35 | * 通过数组方式和指针方式访问第二个元素 36 | * 打印数组名和指针名所占内存字节数 37 | 38 | 结果如下: 39 | 40 | ``` 41 | 0x7fff2b649180 42 | 0x7fff2b649180 43 | 2 44 | 2 45 | 12 46 | 8 47 | ``` 48 | 49 | 总的来说,**数组名就是指针常量,而指针名是指针变量** -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/指针和数组.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针和数组 3 | 4 | 从`C++11`开始,除了提供原始数组形式外,`STL`容器库还提供了`std::array`;与此同时,除了提供原始指针形式外,`C++`还提供了智能指针操作 5 | 6 | * 原始指针 7 | * 原始数组 8 | * 指针名和数组名的区别 9 | * 指针数组 10 | * 数组指针 11 | 12 | ## 一维/二维/三维数组 13 | 14 | 实现原始数组和`std::array`的一维/二维/三维创建 15 | 16 | ``` 17 | const int LENGTH = 3; 18 | const int WIDTH = 10; 19 | const int HEIGHT = 5; 20 | 21 | int a1[LENGTH] = {1, 2, 3}; 22 | int a2[LENGTH][WIDTH]{}; 23 | int a3[LENGTH][WIDTH][HEIGHT]{}; 24 | 25 | using std::array; 26 | array aa1 = {1, 2, 3}; 27 | array, WIDTH> aa2{}; 28 | array, WIDTH>, HEIGHT> aa3{}; 29 | ``` 30 | 31 | 使用大括号进行列表初始化,`std::array`的存储形式是`第3维->第2维->第1维`(从外到里) 32 | 33 | ### 数组大小 34 | 35 | 打印第一维/第二维/第三维大小 36 | 37 | ``` 38 | cout << aa1.size() << endl; 39 | cout << aa2[0].size() << endl; 40 | cout << aa3[0][0].size() << endl; 41 | ``` 42 | 43 | 结果如下 44 | 45 | ``` 46 | 3 47 | 3 48 | 3 49 | ``` 50 | 51 | ### 数组遍历 52 | 53 | 通过迭代器方式可以快速遍历`std::array` 54 | 55 | ``` 56 | for (auto it = aa1.begin(); it != aa1.end(); ++it) { 57 | cout << *it << " "; 58 | } 59 | ``` 60 | 61 | 结果如下: 62 | 63 | ``` 64 | 1 2 3 65 | ``` 66 | 67 | 或者直接使用`for`循环 68 | 69 | ``` 70 | int i = 0; 71 | for (auto &items: aa2) { 72 | for (auto &x: items) { 73 | x = i + 1; 74 | i++; 75 | cout << x << " "; 76 | } 77 | cout << endl; 78 | } 79 | ``` 80 | 81 | 外边的`for`循环遍历了二维数组`aa2`的第二维,里面的`for`循环遍历了第一维。结果如下: 82 | 83 | ``` 84 | 1 2 3 85 | 4 5 6 86 | 7 8 9 87 | 10 11 12 88 | 13 14 15 89 | 16 17 18 90 | 19 20 21 91 | 22 23 24 92 | 25 26 27 93 | 28 29 30 94 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/指针常量和常量指针.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针常量和常量指针 3 | 4 | 参考:[const和volatile指针](https://zj-image-processing.readthedocs.io/zh_CN/latest/c++/const%E5%92%8Cvolatile%E6%8C%87%E9%92%88.html) 5 | 6 | ## 解析 7 | 8 | * 指针常量:指针指向的地址为常量,不能修改指针保存的地址,但可以修改地址保存的值。类似于**数组** 9 | * 常量指针:指针指向的对象为常量,可以修改指针保存的地址,但不能修改地址保存的值 10 | 11 | ## 声明 12 | 13 | 指针常量 14 | 15 | ``` 16 | char const *p; 17 | ``` 18 | 19 | 常量指针 20 | 21 | ``` 22 | const char *p; 23 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/pointer-array/指针类型.md: -------------------------------------------------------------------------------- 1 | 2 | # 指针类型 3 | 4 | 参考:[Pointers (C++)](https://docs.microsoft.com/en-us/cpp/cpp/pointers-cpp?view=vs-2019) 5 | 6 | 指针是`c/c++`相对于其他语言来说最不同的内容之一。通过指针的使用,`c/c++`可以更加自由的操作内存地址,下面学习指针的相关概念和用法 7 | 8 | ## 语法 9 | 10 | 通用语法如下: 11 | 12 | ``` 13 | [storage-class-specifiers] [cv-qualifiers] type-specifiers declarator ; 14 | ``` 15 | 16 | 简化版本如下: 17 | 18 | ``` 19 | * [cv-qualifiers] identifier [= expression] 20 | ``` 21 | 22 | 1. 声明说明符 23 | * 可选的存储类说明符 24 | * 可选的`cv`限定符,应用于要指向的对象的类型 25 | * 类型说明符:表示要指向的对象类型的类型的名称 26 | 2. 声明符 27 | * `*`运算符 28 | * 可选的`cv`限定符,应用于指针本身 29 | * 标识符 30 | * 可选的初始化器 31 | 32 | ### 函数指针 33 | 34 | 指向函数的指针的声明符如下所示: 35 | 36 | ``` 37 | (* [cv-qualifiers] identifier )( argument-list ) [cv-qualifers] [exception-specification] [= expression] ; 38 | ``` 39 | 40 | ### 指针数组 41 | 42 | 指针数组(`array of pointer`)的语法如下: 43 | 44 | ``` 45 | * identifier [ [constant-expression] ] 46 | ``` 47 | 48 | ## 示例 49 | 50 | * 声明指向`char`类型对象的指针 51 | 52 | ``` 53 | char *pch; 54 | ``` 55 | 56 | * 声明指向`unsigned int`类型的静态对象的常量指针 57 | 58 | ``` 59 | static unsigned int * const ptr; 60 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/auto.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11]auto 3 | 4 | 参考: 5 | 6 | [auto (C++)](https://docs.microsoft.com/en-us/cpp/cpp/auto-cpp?view=vs-2019) 7 | 8 | [placeholder type specifiers](https://en.cppreference.com/w/cpp/language/auto) 9 | 10 | ## 定义 11 | 12 | 关键字`auto`是`c++11`新增的,其目的是用于自动类型推断。语法如下: 13 | 14 | ``` 15 | auto declarator initializer; 16 | ``` 17 | 18 | `auto`本身不是类型,它是一个类型占位符。它能够指导编译器根据声明变量的初始化表达式或`lambda`表达式参数进行类型推断 19 | 20 | 使用`auto`代替固定类型声明有以下优点: 21 | 22 | * 鲁棒性:即使表达式的类型会更改也能工作,比如函数返回不同类型 23 | * 高性能:能够保证不会发生类型转换 24 | * 易用性:不需要关心拼写困难或打字错误 25 | * 高效率:使得编码更有效率 26 | 27 | 以下情况可能需要使用固定类型: 28 | 29 | 1. 只有某一类型能够起作用 30 | 2. 表达式模板辅助类型,比如`(valarray+valarray)` 31 | 32 | 网上也有关于`auto`的讨论:[如何评价 C++ 11 auto 关键字?](https://www.zhihu.com/question/35517805) 33 | 34 | ## 示例 35 | 36 | ``` 37 | # BEFORE 38 | float getSum(int A, float B) { 39 | return A + B; 40 | } 41 | 42 | int main(int argc, char *argv[]) { 43 | float sum = getSum(2, 33.33); 44 | 45 | vector src; 46 | src.emplace_back(1); 47 | src.emplace_back(4); 48 | src.emplace_back(3); 49 | for (vector::iterator it = src.begin(); it != src.end(); it++) { 50 | cout << *it << " "; 51 | } 52 | } 53 | 54 | # AFTER 55 | ... 56 | auto sum = getSum(2, 33.33); 57 | ... 58 | for (auto it = src.begin(); it != src.end(); it++) { 59 | cout << *it << " "; 60 | } 61 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/decltype.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11]decltype 3 | 4 | 参考: 5 | 6 | [decltype (C++)](https://docs.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=vs-2019) 7 | 8 | [decltype specifier](https://en.cppreference.com/w/cpp/language/decltype) 9 | 10 | `decltype`类型说明符是`c++11`新增的特性,能够生成指定表达式的类型。语法如下: 11 | 12 | ``` 13 | decltype( expression ) 14 | ``` 15 | 16 | ## 推导规则 17 | 18 | 编译器使用以下规则推导参数`expression`的类型 19 | 20 | 1. 如果参数`expression`是一个标识符(`identifier`)或者类成员访问(`class member access`),那么`decltype(expression)`是该实体(`entity`)的类型 21 | 2. 如果参数`expression`是一个函数或者重载操作符的调用,那么`decltype(expression)`返回函数值类型。忽略重载运算符周围的括号 22 | 3. 如果参数`expression`是一个`rvalue`,那么`decltype(expression)`是`expression`的类型;如果是一个`lvalue`,那么结果是对`expression`类型的`lvalue`引用 23 | 24 | ## 示例 25 | 26 | ``` 27 | int var; 28 | const int&& fx(); 29 | struct A { double x; } 30 | const A* a = new A(); 31 | ``` 32 | 33 | 推导结果如下: 34 | 35 | ![](./imgs/decltype.png) -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/imgs/decltype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/get-started/type-cast-deduce/imgs/decltype.png -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/imgs/promotion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/cplusplus/get-started/type-cast-deduce/imgs/promotion.png -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/void类型.md: -------------------------------------------------------------------------------- 1 | 2 | # void类型 3 | 4 | ## void类型 5 | 6 | 参考: 7 | 8 | [The void type](https://docs.microsoft.com/en-us/cpp/cpp/cpp-type-system-modern-cpp?view=vs-2019#the-void-type) 9 | 10 | [void (C++)](https://docs.microsoft.com/en-us/cpp/cpp/void-cpp?view=vs-2019) 11 | 12 | `void`类型有两个用处 13 | 14 | 1. 作为函数返回值类型,表示不返回一个值 15 | 2. 定义在函数参数列表,表示该函数没有任何参数 16 | 3. 使用`void *`作为指针,可以指向任何类型的变量 17 | 18 | ``` 19 | #include 20 | 21 | using std::cout; 22 | using std::endl; 23 | 24 | void f(void *a) { 25 | int *b = (int *) a; 26 | cout << sizeof(b) << endl; 27 | cout << sizeof(*b) << endl; 28 | 29 | cout << *b << endl; 30 | } 31 | 32 | 33 | int main() { 34 | 35 | int a = 3; 36 | f(&a); 37 | 38 | return 0; 39 | } 40 | ``` 41 | 42 | 结果 43 | 44 | ``` 45 | 8 46 | 4 47 | 3 48 | ``` 49 | 50 | `void *`可以指向任何类型的指针(除了`const`和`volatile`声明的),但是如果想要使用具体的变量值必须重新经过转换 51 | 52 | `void`指针同样可以指向函数,但是不能是类成员 53 | 54 | ## C++规范 55 | 56 | 1. 尽量避免使用`void`指针,其涉及到类型安全 57 | 2. 设置函数无参数,使用`f()`代替`f(void)` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/标准转换.md: -------------------------------------------------------------------------------- 1 | 2 | # 标准转换 3 | 4 | 参考:[Standard conversions](https://docs.microsoft.com/en-us/cpp/cpp/standard-conversions?view=vs-2019) 5 | 6 | `C++`定义了基本类型之间的转换,也定义了指针、引用和成员指针派生类型之间的转换,这些统称为标准转换(`standard conversion`) 7 | 8 | 共分为`8`个部分: 9 | 10 | 1. 整型提升(`integral promotions`) 11 | 2. 整型转换(`integral conversions`) 12 | 3. 浮点型转换(`floating conversions`) 13 | 4. 浮点和整数转换(`floating and integral conversions`) 14 | 5. 数值型间的转换(`arithmetic conversions`) 15 | 6. 指针转换(`pointer conversions`) 16 | 7. 引用转换(`reference conversions`) 17 | 8. 成员指针的转换(`pointer-to-member conversions`) 18 | 19 | ## 隐式类型转换 20 | 21 | 当表达式包含不同内置类型的操作数且不存在显式强制转换时,编译器执行隐式转换 22 | 23 | ### 加宽转换 24 | 25 | 在加宽转换(`Widening conversions`,也称为提升,`promotion`)中,较小变量中的值被分配给较大变量,而不会丢失数据。因为扩大转换总是安全的,编译器会静默地执行它们,不会发出警告。以下转换是加宽转换。 26 | 27 | ![](./imgs/promotion.png) 28 | 29 | ### 变窄转换 30 | 31 | 如果将精度较大变量分配给精度较小的变量,有可能发生数据损失情况,编译器会因为这个情况报出一个警告(`warn`) 32 | 33 | * 对于明确知道不会发生数据损失的情况,可以执行强制类型转换以消除警告 34 | * 如果不明确是否会发生数据损失,可以增加一些运行时检查 35 | 36 | ### 有符号-无符号转换 37 | 38 | `signed-unsigned`转换不会改变变量位数,但是因为其位模式发生了变化导致数据的大小发生了变化。编译器不警告有符号和无符号整数类型之间的隐式转换,但是建议完全避免有符号到无符号的转换 39 | 40 | 如果不能避免它们,那么在代码中添加一个运行时检查,以检测正在转换的值是否大于或等于零,并且小于或等于已签名类型的最大值。此范围内的值将从有符号转换为无符号,或从无符号转换为有符号,而不需要重新解释 41 | 42 | ### 指针转换 43 | 44 | `C`风格的数组可以隐式看成指向数组第一个元素的指针。虽然进行数据操作很简单,但也容易出错,不推荐使用 45 | 46 | ``` 47 | # 示例 48 | $ char* s = "Help" + 3; 49 | ``` 50 | 51 | ## 显式类型转换 52 | 53 | 相比较于隐式类型转换,使用显式类型转换更能明确转换目标,有两种方式: 54 | 55 | 1. `C`风格转换 56 | 2. `C++`风格转换 57 | 58 | ### C风格转换 59 | 60 | 最常用的是使用`C`风格的转换算子,即直接在变量前添加类型,如下所示: 61 | 62 | ``` 63 | (int) x; // old-style cast, old-style syntax 64 | int(x); // old-style cast, functional syntax 65 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/get-started/type-cast-deduce/类型概述.md: -------------------------------------------------------------------------------- 1 | 2 | # [c++11]类型概述 3 | 4 | 参考:[Type Conversions and Type Safety (Modern C++)](https://docs.microsoft.com/en-us/cpp/cpp/type-conversions-and-type-safety-modern-cpp?view=vs-2019) 5 | 6 | `c++`是强类型编程语言,每个变量、函数参数、函数返回值都必须拥有一个类型 7 | 8 | 类型的作用如下: 9 | 10 | 1. 指定变量(或表达式结果)分配的内存 11 | 2. 指定可能存储的值的类型 12 | 3. 指定编译器如何解释这些值(在位模式下) 13 | 4. 指定可以对其进行的操作 14 | 15 | `c++`的类型分为以下几种: 16 | 17 | 1. 基本类型 18 | 2. `void`类型 19 | 3. `string`类型 20 | 4. 用户自定义类型 21 | 5. 指针类型 22 | 23 | 另外也经常使用`const`类型限定符 -------------------------------------------------------------------------------- /docs/cplusplus/operate/计时.md: -------------------------------------------------------------------------------- 1 | 2 | # 计时 3 | 4 | `c++`提供了多种计时方式,包括: 5 | 6 | 1. `clock_t` 7 | 2. `struct timespec` 8 | 3. `std::chrono::time_point` 9 | 10 | 一句话总结:`clock_t`不适用于多核计算环境,会出现非常大的计算误差。使用后两种计时方式即可 11 | 12 | ## clock_t 13 | 14 | ``` 15 | clock_t start, end; 16 | start = clock(); 17 | ... 18 | ... 19 | end = clock(); 20 | std::cout << "image read: " << (double) (start - end) / CLOCKS_PER_SEC << std::endl; 21 | .... 22 | ``` 23 | 24 | ## timespec 25 | 26 | ``` 27 | struct timespec start, end; 28 | clock_gettime(CLOCK_MONOTONIC, &start); 29 | ... 30 | ... 31 | clock_gettime(CLOCK_MONOTONIC, &end); 32 | auto t1 = (double) (clock_img_read.tv_sec - start.tv_sec) * 1000 + 33 | (double) (clock_img_read.tv_nsec - start.tv_nsec) / 1000000; 34 | ... 35 | ... 36 | ``` 37 | 38 | ## time_point 39 | 40 | ``` 41 | int64_t getCurrentLocalTimeStamp() { 42 | std::chrono::time_point tp = std::chrono::time_point_cast(std::chrono::system_clock::now()); 43 | 44 | auto tmp = std::chrono::duration_cast(tp.time_since_epoch()); 45 | return tmp.count(); 46 | } 47 | ``` -------------------------------------------------------------------------------- /docs/cplusplus/学习C++之路.md: -------------------------------------------------------------------------------- 1 | 2 | # 学习c++之路 3 | 4 | 从大学开始,陆陆续续的学习和使用`C++`。最开始是从`C`入门,然后自学过`C++`,当时看的是书籍:`《C程序设计》`和`《C++ Primer》`等;后来做项目的时候需要`C++`编程,看得更多的是博客,专注于要解决的困难点;最近实践深度学习需要使用`C++`,所以在网上找一些教程和参考网站 5 | 6 | *以下涉及的网站同样提供了`C`语言规范和教程* 7 | 8 | ## 语法 9 | 10 | 网站[cplusplus](http://www.cplusplus.com/)和[cppreference](https://en.cppreference.com/w/)提供了全面的`C++`语法规范 11 | 12 | ## 教程 13 | 14 | 推荐以下`3`个在线教程 15 | 16 | 1. [Microsoft Docs](https://docs.microsoft.com/en-us/cpp/cpp/c-cpp-language-and-standard-libraries?view=vs-2019) 17 | 2. [cppreference - C++ language](https://en.cppreference.com/w/cpp/language) 18 | 3. [cplusplus - C++ Language](http://www.cplusplus.com/doc/tutorial/) 19 | 20 | 其中微软提供的教程排版比较好,易于阅读和理解,不过`3`个教程都有各自的角度,综合起来看比较全面 21 | 22 | ## 库参考 23 | 24 | `cplusplus`提供了标准`C++`库参考:[Standard C++ Library reference](http://www.cplusplus.com/reference/) 25 | 26 | ## 关键字 27 | 28 | [Microsoft - Keywords (C++)](https://docs.microsoft.com/en-us/cpp/cpp/keywords-cpp?view=vs-2019)提供了完整的关键字列表 29 | 30 | 关键字是具有特殊含义的预定义保留标识符,它们不能用作程序中的自定义标识符。以下标识符是微软`C++`保留的关键字,下划线开头的名字和附加(`C++/CLI`)的名字是微软扩展 31 | 32 | ## 操作符 33 | 34 | [C++ Built-in Operators, Precedence and Associativity](https://docs.microsoft.com/en-us/cpp/cpp/cpp-built-in-operators-precedence-and-associativity?view=vs-2019)提供了完整的操作符列表 35 | 36 | `C++`语言包括所有的`C`运算符,并添加了几个新的运算符。运算符指定一个或多个操作数执行计算 37 | 38 | ## 语言规范 39 | 40 | `C++`规范已经经历了多个版本的迭代(`98/03/11/14/17/20`),其实现方式从`C`语言风格转向脚本语言风格,越来越智能和现代化。当前专注于`C++11`版本的学习和使用,关于`C++11`舍弃的命令和使用方式,参考[Which C++ idioms are deprecated in C++11?](https://stackoverflow.com/questions/9299101/which-c-idioms-are-deprecated-in-c11) -------------------------------------------------------------------------------- /docs/gtest/index.md: -------------------------------------------------------------------------------- 1 | 2 | # Google Test 3 | 4 | `Google Test`提供了完善的测试和数据仿真框架,提供了文档、工具和示例。 5 | 6 | ## 相关阅读 7 | 8 | * [google/googletest](https://github.com/google/googletest) 9 | * [GoogleTest User’s Guide](http://google.github.io/googletest/) -------------------------------------------------------------------------------- /docs/gtest/summary.md: -------------------------------------------------------------------------------- 1 | 2 | # 小结 3 | 4 | 学习`Google Test`之前,充满了各种想法:我要把各个模块都测起来!我要把每个函数都进行测试~~。初步掌握`GTest`之后,面对工程中的各个模块和函数,却迟迟没有进展。会很迷茫,这么多的函数跟接口,有必要每一个都进行测试吗?思考和实践了很多,有一些小小的想法: 5 | 6 | * 测试要有目的性! 7 | 8 | 明确想要测试的目标是什么,是黑盒测试?是验证对外接口是不是有效?是异常情况能不能容错?有了目标之后才能编写得到更适用的单元测试。 9 | 10 | * 不是所有功能/函数/接口都需要进行单元测试 11 | 12 | 个人理解,对于简单的函数实现,没有必须进行测试的必要性。 -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # VisionGuide 2 | 3 | ## 章节 4 | 5 | * 编程语法 6 | * `Python` 7 | * `C++11` 8 | * 计算框架 9 | * `PyTorch` 10 | * `Numpy` 11 | * 视觉库 12 | * `Torchvision` 13 | * `OpenCV` 14 | * `Matplotlib` 15 | * `Libjpeg-turbo` 16 | * `stb` 17 | * 工具 18 | * `cmake` 19 | * `google test` 20 | * `clang-format` -------------------------------------------------------------------------------- /docs/libjpeg/index.md: -------------------------------------------------------------------------------- 1 | 2 | # libjpeg-turbo概述 3 | 4 | [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo)是一个图像编解码库,专门支持JPEG数据的编码和解码操作,支持不同平台和不同颜色空间,相比于`libjpeg`库加速了`2x~6x`,据说也比`OpenCV`快。 5 | 6 | 使用`libjpeg-turbo`可以进行`jpeg`图像的解析,获取字节数据以及宽/高等信息,可以作为`OpenCV`的替代(*因为相对而言编译和使用更加简单*) 7 | 8 | * 官网地址:[libjpeg-turbo/libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo) 9 | * 示例程序:[libjpeg-turbo/tjexample.c ](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/tjexample.c) 10 | 11 | 本地示例实现位于`libjpeg/` -------------------------------------------------------------------------------- /docs/libjpeg/ubuntu-compile.md: -------------------------------------------------------------------------------- 1 | 2 | # Ubuntu编译 3 | 4 | ## 实现步骤 5 | 6 | ``` 7 | $ git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git 8 | $ cd /path/to/libjpeg-turbo 9 | # 编译、配置和安装 10 | $ mkdir build 11 | $ cd build 12 | $ cmake -G"Unix Makefiles" -DCMAKE_INSTALL_PREFIX=../install ../ 13 | $ make -j8 14 | $ make install 15 | ``` 16 | 17 | ## 相关阅读 18 | 19 | * [Building libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/BUILDING.md) -------------------------------------------------------------------------------- /docs/matplotlib/imgs/anatomy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/anatomy.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/axes-2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/axes-2-2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/contour_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/contour_1.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/contour_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/contour_2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/contour_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/contour_3.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/contour_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/contour_4.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/contour_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/contour_5.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/coordinate-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/coordinate-3d.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/curve-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/curve-3d.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/figure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/figure-1.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/figure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/figure-2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/figure-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/figure-3.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/figure-suptitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/figure-suptitle.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/fmt-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/fmt-color.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/fmt-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/fmt-line.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/fmt-marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/fmt-marker.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/gray-2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/gray-2-3.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/gray.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line-chart.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line-legend-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line-legend-1.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line-text.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line2d-properties-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line2d-properties-1.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line2d-properties-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line2d-properties-2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/line_spots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/line_spots.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/mat_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/mat_image.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/multi-scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/multi-scatter.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-1.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-3.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-4.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-5.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/pie-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/pie-6.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/plot-x-y-+.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/plot-x-y-+.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/plot-x-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/plot-x-y.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/plot-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/plot-y.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/scatter-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/scatter-3d.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/single-scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/single-scatter.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_001.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_002.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_003.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_004.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_005.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_006.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_007.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_008.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_009.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/sphx_glr_pyplot_010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/sphx_glr_pyplot_010.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/subplot-1-2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/subplot-1-2-2.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/surface-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/surface-3d.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/two_y_axes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/two_y_axes.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/unorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/unorder.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/xaxis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/xaxis.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/xlim_xticks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/xlim_xticks.png -------------------------------------------------------------------------------- /docs/matplotlib/imgs/xlim_xticks_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/matplotlib/imgs/xlim_xticks_1.png -------------------------------------------------------------------------------- /docs/matplotlib/y轴坐标错乱.md: -------------------------------------------------------------------------------- 1 | 2 | # y轴坐标错乱 3 | 4 | 今天遇到一个问题,`y`轴坐标值出现了乱序,如下图所示: 5 | 6 | ![](./imgs/unorder.png) 7 | 8 | 参考[plt作图时出现横坐标或者纵坐标乱序的解决方法](https://blog.csdn.net/weixin_43748786/article/details/96432047),发现是因为输入`y`轴数据类型不是`np.int/np.float`,在程序中查了一下,发现果真如此,数据类型为`np.str` 9 | 10 | 复现代码如下: 11 | 12 | ``` 13 | import numpy as np 14 | import matplotlib.pyplot as plt 15 | 16 | 17 | def draw(y): 18 | f = plt.figure() 19 | 20 | x = list(range(len(y))) 21 | plt.scatter(x, y) 22 | 23 | plt.show() 24 | 25 | 26 | if __name__ == '__main__': 27 | a = np.arange(10).astype(np.str) 28 | np.random.shuffle(a) 29 | draw(a) 30 | ``` -------------------------------------------------------------------------------- /docs/matplotlib/中文乱码.md: -------------------------------------------------------------------------------- 1 | 2 | # 中文乱码 3 | 4 | ## 下载中文字体 5 | 6 | [simhei](https://fontzone.net/downloadfile/simhei) 7 | 8 | ## 存放 9 | 10 | 找到`matplotlib`字体存放位置 11 | 12 | ``` 13 | >>> import matplotlib 14 | >>> matplotlib.matplotlib_fname() 15 | '/home/zj/software/anaconda/anaconda3/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc' 16 | ``` 17 | 18 | 进入`mpl-data/fonts/ttf`文件夹,存放刚才下载的`simhei.ttf` 19 | 20 | ## 配置 21 | 22 | 可以全局配置,也可以局部配置 23 | 24 | ### 全局配置 25 | 26 | 在`mpl-data`有配置文件`matplotlibrc`,添加以下配置 27 | 28 | ``` 29 | font.family : sans-serif 30 | font.sans-serif : SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif 31 | axes.unicode_minus : False 32 | ``` 33 | 34 | ### 局部配置 35 | 36 | 在程序中配置使用中文字体 37 | 38 | ``` 39 | plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签 40 | plt.rcParams['axes.unicode_minus']=False #用来正常显示负号 41 | ``` 42 | 43 | ## 缓存 44 | 45 | 删除之前的缓存 46 | 47 | ``` 48 | $ rm -rf ~/.cache/matplotlib 49 | # 或 50 | $ rm -rf ~/.matplotlib 51 | ``` 52 | 53 | 也可以文件中使用命令重载字体 54 | 55 | ``` 56 | from matplotlib.font_manager import _rebuild 57 | _rebuild() # reload一下 58 | ``` 59 | 60 | ## 相关阅读 61 | 62 | * [Linux 系统下 matplotlib 中文乱码解决办法](https://www.cnblogs.com/michael-xiang/p/10466807.html) 63 | 64 | * [matplotlib图例中文乱码?](https://www.zhihu.com/question/25404709) 65 | 66 | * [第四步:删除缓存](https://www.jianshu.com/p/d20a0971756b) -------------------------------------------------------------------------------- /docs/matplotlib/属性配置.md: -------------------------------------------------------------------------------- 1 | 2 | # 属性配置 3 | 4 | ## 查找配置文件 5 | 6 | 使用命令查找配置文件 7 | 8 | ``` 9 | >>> import matplotlib 10 | >>> matplotlib.matplotlib_fname() 11 | 'xxx/xxx/matplotlib/mpl-data/matplotlibrc' 12 | ``` 13 | 14 | ## 重载配置文件 15 | 16 | 修改完成配置文件后需要重新加载,或者重启系统,或者输入以下命令 17 | 18 | ``` 19 | from matplotlib.font_manager import _rebuild 20 | _rebuild() 21 | ``` 22 | 23 | ## 属性查找 24 | 25 | 使用命令查看当前属性 26 | 27 | ``` 28 | >>> import matplotlib.pyplot as plt 29 | >>> plt.rcParams 30 | /home/zj/software/anaconda/anaconda3/lib/python3.7/site-packages/matplotlib/__init__.py:886: MatplotlibDeprecationWarning: 31 | examples.directory is deprecated; in the future, examples will be found relative to the 'datapath' directory. 32 | "found relative to the 'datapath' directory.".format(key)) 33 | RcParams({'_internal.classic_mode': False, 34 | 'agg.path.chunksize': 0, 35 | 'animation.avconv_args': [], 36 | 'animation.avconv_path': 'avconv', 37 | 'animation.bitrate': -1, 38 | 'animation.codec': 'h264', 39 | 'animation.convert_args': [], 40 | 'animation.convert_path': 'convert', 41 | 'animation.embed_limit': 20.0, 42 | 'animation.ffmpeg_args': [], 43 | 'animation.ffmpeg_path': 'ffmpeg', 44 | 'animation.frame_format': 'png', 45 | 'animation.html': 'none', 46 | ... 47 | ... 48 | ``` 49 | 50 | ## 属性设置 51 | 52 | 使用命令进行属性设置 53 | 54 | ``` 55 | plt.rcParams[xxx] = xxx 56 | ``` -------------------------------------------------------------------------------- /docs/matplotlib/引言.md: -------------------------------------------------------------------------------- 1 | 2 | # 引言 3 | 4 | [matplotlib](https://matplotlib.org/index.html)是`Python 2D`绘图库 5 | 6 | 之前对它的概念不太理解,都是在网上找的示例代码,所以很难在原先代码基础上添加一些特性 7 | 8 | 这一次深入`matplotlib`的绘图架构,争取能够实现好的绘图 9 | 10 | ## matplotlib.plot 11 | 12 | `matplotlib.plot`是`matplotlib`的一个模块,为底层的面向对象绘图库提供状态机接口,状态机隐式并自动创建图形和轴以实现所需的绘图 13 | 14 | 其`API`风格类似于`MATLIB`,更加简单直观 15 | 16 | ## 输入数据格式 17 | 18 | `matplotlib`支持多种格式数据输入,特别是`np.array`对象,所以最好在数据输入之前转换成`np.array`对象 19 | 20 | ``` 21 | b = np.matrix([[1,2],[3,4]]) 22 | b_asarray = np.asarray(b) 23 | ``` 24 | 25 | ## 代码风格 26 | 27 | 引用`matplotlib.plot`类库以及`numpy`类库如下 28 | 29 | ``` 30 | import matplotlib.pyplot as plt 31 | import numpy as np 32 | ``` 33 | 34 | ## jupyter notebook嵌入 35 | 36 | `matplotlib`支持在`jupyter notebook`嵌入绘图,仅需在最开始执行以下语句: 37 | 38 | ``` 39 | %matplotlib inline 40 | ``` 41 | 42 | ## 相关阅读 43 | 44 | * [Matplotlib, pyplot and pylab: how are they related?](https://matplotlib.org/tutorials/introductory/usage.html#matplotlib-pyplot-and-pylab-how-are-they-related) 45 | * [Types of inputs to plotting functions](https://matplotlib.org/tutorials/introductory/usage.html#types-of-inputs-to-plotting-functions) 46 | * [coding styles](https://matplotlib.org/tutorials/introductory/usage.html#coding-styles) -------------------------------------------------------------------------------- /docs/matplotlib/手动设置轴刻度间隔.md: -------------------------------------------------------------------------------- 1 | 2 | # 手动设置轴刻度间隔 3 | 4 | 默认情况下,`Matplotlib`会自动调整`x`轴刻度,需要手动设置 5 | 6 | ## 定义 7 | 8 | ``` 9 | import matplotlib.pyplot as plt 10 | from matplotlib.pyplot import MultipleLocator 11 | 12 | # 设置`x`轴刻度间隔为`1` 13 | x_major_locator = MultipleLocator(1) 14 | ax = plt.gca() 15 | ax.xaxis.set_major_locator(x_major_locator) 16 | ``` 17 | 18 | ## 示例 19 | 20 | 参考:[折线图](./折线图.md) 21 | 22 | ``` 23 | import matplotlib.pyplot as plt 24 | from matplotlib.pyplot import MultipleLocator 25 | 26 | def show(): 27 | x = list(range(10)) 28 | y = random.sample(list(range(100)), 10) 29 | 30 | plt.figure(1, figsize=(9, 3)) 31 | 32 | plt.title('test') 33 | plt.subplot(1, 2, 1) 34 | plt.plot(x, y, label='unset') 35 | plt.legend() 36 | 37 | plt.subplot(122) 38 | 39 | x_major_locator = MultipleLocator(1) 40 | ax = plt.gca() 41 | ax.xaxis.set_major_locator(x_major_locator) 42 | 43 | plt.plot(x, y, label='set') 44 | plt.legend() 45 | 46 | plt.show() 47 | ``` 48 | 49 | ![](./imgs/xaxis.png) 50 | 51 | ## 相关阅读 52 | 53 | * [Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围](https://www.jb51.net/article/163842.htm) -------------------------------------------------------------------------------- /docs/matplotlib/指定轴取值范围以及显示轴刻度.md: -------------------------------------------------------------------------------- 1 | 2 | # 指定轴取值范围以及显示轴刻度 3 | 4 | ## 实现 5 | 6 | ``` 7 | # Import Library 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | 12 | # Define Data 13 | 14 | x = np.arange(0, 15, 0.2) 15 | data_1 = np.sin(x) 16 | 17 | # Create Plot 18 | 19 | fig, ax1 = plt.subplots() 20 | 21 | # ## Get current axis info 22 | # print('xlim:', ax1.get_xlim()) 23 | # print('ylim:', ax1.get_ylim()) 24 | # print('xticks:', ax1.get_xticks()) 25 | # print('yticks:', ax1.get_yticks()) 26 | # 27 | # ## Set axis 28 | # xticks = np.arange(1, 20, 1) 29 | # xlim = (0.0, 20.0) 30 | # print('set xlim:', xlim) 31 | # print('set xticks:', xticks) 32 | # ax1.set_xlim(xlim) 33 | # ax1.set_xticks(xticks) 34 | 35 | ax1.set_xlabel('X-axis') 36 | ax1.set_ylabel('Y1-axis', color='red') 37 | ax1.plot(x, data_1, color='red') 38 | ax1.tick_params(axis='y', labelcolor='red') 39 | 40 | # Show plot 41 | 42 | plt.show() 43 | ``` 44 | 45 | ## 显示 46 | 47 | * Before: 48 | 49 | ![](./imgs/xlim_xticks_1.png) 50 | 51 | * After: 52 | 53 | ![](./imgs/xlim_xticks.png) 54 | 55 | ## 相关阅读 56 | 57 | * [python matplotlib.axes相关属性设置(绘图方式、坐标轴、坐标刻度、文本等)](https://blog.csdn.net/weixin_44237337/article/details/116149154) -------------------------------------------------------------------------------- /docs/matplotlib/矩阵显示.md: -------------------------------------------------------------------------------- 1 | 2 | # 矩阵显示 3 | 4 | 通过图形显示矩阵信息,依据图像颜色反映矩阵各个位置上的数值大小 5 | 6 | ## 函数定义 7 | 8 | 参考:[matplotlib.pyplot.matshow](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.matshow.html?highlight=matshow#matplotlib.pyplot.matshow) 9 | 10 | ``` 11 | matplotlib.pyplot.matshow(A, fignum=None, **kwargs) 12 | ``` 13 | 14 | * 参数`A`表示将要图形化的数组 15 | * 参数`fignum`指定图形窗口 16 | * 默认为`None`,表示新建一个窗口进行绘制 17 | * 如果为非零整数,那么将绘制到该窗口(如果不存在则新建) 18 | * 如果为`0`,那么使用当前窗口(如果不存在则新建) 19 | 20 | ## 示例 21 | 22 | 参考:[Matshow](https://matplotlib.org/gallery/images_contours_and_fields/matshow.html#sphx-glr-gallery-images-contours-and-fields-matshow-py) 23 | 24 | ``` 25 | import matplotlib.pyplot as plt 26 | import numpy as np 27 | import warnings 28 | 29 | warnings.filterwarnings("ignore") 30 | 31 | def samplemat(dims): 32 | """Make a matrix with all zeros and increasing elements on the diagonal""" 33 | aa = np.zeros(dims) 34 | for i in range(min(dims)): 35 | aa[i, i] = i 36 | return aa 37 | 38 | 39 | ma = samplemat((10, 10)) 40 | print(ma) 41 | # Display matrix 42 | plt.matshow(ma) 43 | plt.show() 44 | ``` 45 | 46 | 输出矩阵信息: 47 | 48 | ``` 49 | [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 50 | [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.] 51 | [0. 0. 2. 0. 0. 0. 0. 0. 0. 0.] 52 | [0. 0. 0. 3. 0. 0. 0. 0. 0. 0.] 53 | [0. 0. 0. 0. 4. 0. 0. 0. 0. 0.] 54 | [0. 0. 0. 0. 0. 5. 0. 0. 0. 0.] 55 | [0. 0. 0. 0. 0. 0. 6. 0. 0. 0.] 56 | [0. 0. 0. 0. 0. 0. 0. 7. 0. 0.] 57 | [0. 0. 0. 0. 0. 0. 0. 0. 8. 0.] 58 | [0. 0. 0. 0. 0. 0. 0. 0. 0. 9.]] 59 | ``` 60 | 61 | ![](./imgs/mat_image.png) -------------------------------------------------------------------------------- /docs/matplotlib/设置双Y轴.md: -------------------------------------------------------------------------------- 1 | 2 | # 设置双Y轴 3 | 4 | ## 实现 5 | 6 | ``` 7 | # Import Library 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | 12 | # Define Data 13 | 14 | x = np.arange(0, 15, 0.2) 15 | data_1 = np.sin(x) 16 | data_2 = np.cos(x) 17 | 18 | # Create Plot 19 | 20 | fig, ax1 = plt.subplots() 21 | 22 | ax1.set_xlabel('X-axis') 23 | ax1.set_ylabel('Y1-axis', color='red') 24 | ax1.plot(x, data_1, color='red') 25 | ax1.tick_params(axis='y', labelcolor='red') 26 | 27 | # Adding Twin Axes 28 | 29 | ax2 = ax1.twinx() 30 | 31 | ax2.set_ylabel('Y2-axis', color='blue') 32 | ax2.plot(x, data_2, color='blue') 33 | ax2.tick_params(axis='y', labelcolor='blue') 34 | 35 | # Show plot 36 | 37 | plt.show() 38 | ``` 39 | 40 | ## 显示 41 | 42 | ![](./imgs/two_y_axes.png) 43 | 44 | ## 相关阅读 45 | 46 | * [Matplotlib two y axes](https://pythonguides.com/matplotlib-two-y-axes/) 47 | * [python matplotlib.axes相关属性设置(绘图方式、坐标轴、坐标刻度、文本等)](https://blog.csdn.net/weixin_44237337/article/details/116149154) -------------------------------------------------------------------------------- /docs/mnn/compile.md: -------------------------------------------------------------------------------- 1 | 2 | # 编译 3 | 4 | ## Android 5 | 6 | * [推理框架Android编译](https://www.yuque.com/mnn/cn/build_android) 7 | * `Android`静态库编译 8 | * [libMNN.a 有151M #521](https://github.com/alibaba/MNN/issues/521) 9 | * [Android 静态库编译 #619](https://github.com/alibaba/MNN/issues/619) 10 | 11 | ## Linux 12 | 13 | * [推理框架Linux / macOS编译](https://www.yuque.com/mnn/cn/build_linux) -------------------------------------------------------------------------------- /docs/mnn/convert.md: -------------------------------------------------------------------------------- 1 | 2 | # 模型转换 3 | 4 | ## ONNX -> MNN 5 | 6 | ```shell 7 | ./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz 8 | ``` 9 | 10 | 正确性校验 11 | 12 | ```shell 13 | python ../tools/script/fastTestOnnx.py mobilenetv2-7.onnx # 模型转换后推理并与ONNXRuntime结果对比 14 | ``` 15 | 16 | ## MNN -> .h 17 | 18 | ```shell 19 | xxd -i xxx.mnn xxx.h 20 | ``` 21 | 22 | ## 相关阅读 23 | 24 | * [模型转换工具](https://mnn-docs.readthedocs.io/en/latest/tools/convert.html) -------------------------------------------------------------------------------- /docs/mnn/dataformat.md: -------------------------------------------------------------------------------- 1 | 2 | # 数据格式 3 | 4 | ## 相关阅读 5 | 6 | * [ONNX模型转MNN模型后在ios端推理结果错误 #1769](https://github.com/alibaba/MNN/issues/1769) -------------------------------------------------------------------------------- /docs/mnn/imageprocess.md: -------------------------------------------------------------------------------- 1 | 2 | # 图像预处理 3 | 4 | `MNN`提供了预处理模块`MNN/ImageProcess.hpp`,支持对图像数据进行归一化操作 5 | 6 | ## 相关阅读 7 | 8 | * [MNN 图像处理配置](https://www.yuque.com/mnn/cn/input#lXEW1) 9 | * [如何归一化到[-1.0, 1.0] #871](https://github.com/alibaba/MNN/issues/871) 10 | * [ONNX模型转MNN模型后在ios端推理结果错误 #1769](https://github.com/alibaba/MNN/issues/1769) 11 | * [What is the process of MNN :: CV :: ImageProcess module processing images? #854](https://github.com/alibaba/MNN/issues/854) 12 | * [MNN images process #936](https://github.com/alibaba/MNN/issues/936) -------------------------------------------------------------------------------- /docs/mnn/index.md: -------------------------------------------------------------------------------- 1 | 2 | # 引言 3 | 4 | `MNN`是一个深度网络移动端推理引擎,它支持端侧模型的训练和推理(*当然,常用的就是推理功能了*)。 5 | 6 | * 官网地址:[MNN 轻量级高性能推理引擎](https://www.mnn.zone/) 7 | * 官方文档:[MNN中文文档](https://www.yuque.com/mnn/cn/about) 8 | * `Github`地址:[alibaba/MNN](https://github.com/alibaba/MNN) 9 | 10 | ## 功能模块 11 | 12 | 按使用功能可以将`MNN`划分为以下模块: 13 | 14 | 1. 训练模块 15 | 2. 推理模块 16 | 3. 转换模块(*将其他格式模型转换成`MNN`计算格式*) 17 | 4. 预处理模块(*包含常用的图像操作,包括旋转、缩放、裁剪、归一化等等。可以替代第三方图像库使用,比如`OpenCV`*) 18 | 5. 其他组件 19 | 20 | ## 模型推理流程 21 | 22 | 1. 将`Pytorch`模型转换成`ONNX`格式:`.pt -> .onnx` 23 | 2. 将`ONNX`模型转换成`MNN`格式:`.onnx -> .mnn` 24 | 3. 输入图像数据,利用预处理模块进行图像操作; 25 | 4. 最后输入到`MNN`推理模块进行计算。 -------------------------------------------------------------------------------- /docs/mnn/infer.md: -------------------------------------------------------------------------------- 1 | 2 | # 推理 3 | 4 | ## 基本流程 5 | 6 | * 创建`Interpreter`(加载模型) 7 | * 创建`Session`(推理配置) 8 | * 输入数据 9 | * 运行会话 10 | * 获取输出 11 | 12 | ## 相关阅读 13 | 14 | * [Session API使用](https://mnn-docs.readthedocs.io/en/latest/inference/session.html) -------------------------------------------------------------------------------- /docs/mnn/quantization.md: -------------------------------------------------------------------------------- 1 | 2 | # 模型量化 3 | 4 | ## 相关阅读 5 | 6 | * [单输入模型离线量化工具](https://mnn-docs.readthedocs.io/en/latest/tools/quant.html) 7 | * [训练量化](https://mnn-docs.readthedocs.io/en/latest/train/quant.html) -------------------------------------------------------------------------------- /docs/numpy/troubleshooting.md: -------------------------------------------------------------------------------- 1 | 2 | # 问题解答 3 | 4 | ## 问题一:FutureWarning: Passing (type, 1) or '1type' ... 5 | 6 | * 问题描述 7 | 8 | ``` 9 | FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future ver... 10 | ``` 11 | 12 | * 问题解析 13 | 14 | `numpy`版本过高 15 | 16 | * 解决方案 17 | 18 | ``` 19 | pip install numpy==1.16.4 20 | ``` 21 | 22 | * 参考 23 | 24 | [解决FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future ver...](https://www.jianshu.com/p/945290726335) -------------------------------------------------------------------------------- /docs/numpy/元素累加.md: -------------------------------------------------------------------------------- 1 | 2 | # [numpy]元素累加 3 | 4 | `Numpy`提供了函数`cumsum`用于元素累加操作 5 | 6 | ``` 7 | import numpy as np 8 | 9 | if __name__ == '__main__': 10 | data = np.arange(10) 11 | print(data) 12 | 13 | res = np.cumsum(data) 14 | print(res) 15 | ################### 输出 16 | [0 1 2 3 4 5 6 7 8 9] 17 | [ 0 1 3 6 10 15 21 28 36 45] 18 | ``` -------------------------------------------------------------------------------- /docs/numpy/增加或者减少一维.md: -------------------------------------------------------------------------------- 1 | 2 | # [numpy]增加或者减少一维 3 | 4 | 增加维度使用`np.newaxis`,减少维度使用`np.squeeze` 5 | 6 | ## np.newaxis 7 | 8 | ``` 9 | >>> a = np.arange(3) 10 | >>> a.shape 11 | (3,) 12 | # 增加第一维 13 | >>> b = a[np.newaxis, :] 14 | >>> b.shape 15 | (1, 3) 16 | ``` 17 | 18 | ## np.squeeze 19 | 20 | ``` 21 | # 减少第一维 22 | >>> c = b.squeeze(0) 23 | >>> c.shape 24 | (3,) 25 | ``` 26 | 27 | ## 相关阅读 28 | 29 | * [numpy.ndarray 增加一维](https://blog.csdn.net/a362682954/article/details/81220035) -------------------------------------------------------------------------------- /docs/numpy/提取数组中属于某一条件的数据.md: -------------------------------------------------------------------------------- 1 | 2 | # [numpy]提取数组中属于某一条件的数据 3 | 4 | ## 示例 5 | 6 | ``` 7 | import numpy as np 8 | 9 | data = np.arange(10) 10 | print(data) 11 | # 取偶数 12 | print(data[data % 2 == 0]) 13 | # 取奇数 14 | print(data[data % 2 == 1]) 15 | ``` 16 | 17 | ## 相关阅读 18 | 19 | * [从numpy数组中取出满足条件的元素](https://blog.csdn.net/qq_27972567/article/details/82889376) -------------------------------------------------------------------------------- /docs/numpy/限制取值范围.md: -------------------------------------------------------------------------------- 1 | 2 | # [numpy][clip]限制取值范围 3 | 4 | >clip(a, a_min, a_max, out=None, **kwargs) 5 | 6 | 将数组取值限制为给定最小值和最大值之间 7 | 8 | ``` 9 | >>> import numpy as np 10 | >>> 11 | >>> a = np.arange(5) 12 | >>> a 13 | array([0, 1, 2, 3, 4]) 14 | >>> np.clip(a, 2, 3) 15 | array([2, 2, 2, 3, 3]) 16 | >>> a = np.arange(12).reshape(3,4) 17 | >>> a 18 | array([[ 0, 1, 2, 3], 19 | [ 4, 5, 6, 7], 20 | [ 8, 9, 10, 11]]) 21 | >>> np.clip(a, 3, 9) 22 | array([[3, 3, 3, 3], 23 | [4, 5, 6, 7], 24 | [8, 9, 9, 9]]) 25 | ``` -------------------------------------------------------------------------------- /docs/opencv/configure/4.0.1/测试.md: -------------------------------------------------------------------------------- 1 | 2 | # [Ubuntu 16.04]OpenCV-4.0.1测试 3 | 4 | 和之前`OpenCV`版本不同,`OpenCV-4.0.1`使用`c++11`,所以需要在配置文件中指定编译环境 5 | 6 | ## cmake 7 | 8 | $ cat CMakeLists.txt 9 | cmake_minimum_required(VERSION 2.8) 10 | # 指定c++11 11 | add_definitions(-std=c++11) 12 | project( DisplayImage ) 13 | find_package( OpenCV REQUIRED ) 14 | MESSAGE("OpenCV version: ${OpenCV_VERSION}") 15 | include_directories( ${OpenCV_INCLUDE_DIRS} ) 16 | add_executable( DisplayImage DisplayImage.cpp ) 17 | target_link_libraries( DisplayImage ${OpenCV_LIBS} ) 18 | 19 | ## make 20 | 21 | $ cat makefile 22 | INCLUDE=$(shell pkg-config --cflags opencv) 23 | LIB=$(shell pkg-config --libs opencv) 24 | SOURCE=DisplayImage.cpp 25 | RES=DisplayImage 26 | 27 | $(RES):$(SOURCE) 28 | g++ -std=c++11 $(SOURCE) $(INCLUDE) $(LIB) -o $(RES) 29 | 30 | clean: 31 | rm $(RES) 32 | 33 | ### 错误 34 | 35 | $ ./DisplayImage lena.jpg 36 | ./DisplayImage: error while loading shared libraries: libopencv_highgui.so.4.0: cannot open shared object file: No such file or directory 37 | 38 | 系统找不到动态库,需要配置进行动态库的绑定,在路径`/etc/ld.so.conf.d`下新建配置文件`opencv.conf`并刷新 39 | 40 | $ sudo vim opencv.conf 41 | /home/zj/opencv/opencv-4.0.1/install/lib 42 | $ sudo ldconfig 43 | 44 | ## 相关阅读 45 | 46 | * [cmake增加C++11](https://blog.csdn.net/sinat_21190681/article/details/83508228) 47 | * [Linux locate ldconfig pkg-config ldd 以及 OpenCV C++库的使用](https://blog.csdn.net/u012005313/article/details/82350430#T2) -------------------------------------------------------------------------------- /docs/opencv/configure/4.7.0/INSTALL.md: -------------------------------------------------------------------------------- 1 | 2 | # 4.7.0安装 3 | 4 | 目前OpenCV最新版本是[OpenCV 4.7.0](https://github.com/opencv/opencv/releases/tag/4.7.0),前几天尝试编译了一下,发觉比之前更加简单了,记录一下 5 | 6 | ## 安装文档 7 | 8 | * [OpenCV installation overview](https://docs.opencv.org/4.7.0/d0/d3d/tutorial_general_install.html) 9 | * [OpenCV configuration options reference](https://docs.opencv.org/4.7.0/db/d05/tutorial_config_reference.html) 10 | * [Installation in Linux](https://docs.opencv.org/4.7.0/d7/d9f/tutorial_linux_install.html) 11 | 12 | ## 安装操作 13 | 14 | 官网给出的安装流程如下: 15 | 16 | ```shell 17 | # Install minimal prerequisites (Ubuntu 18.04 as reference) 18 | sudo apt update && sudo apt install -y cmake g++ wget unzip 19 | # Download and unpack sources 20 | wget -O opencv.zip https://github.com/opencv/opencv/archive/4.x.zip 21 | wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.x.zip 22 | unzip opencv.zip 23 | unzip opencv_contrib.zip 24 | # Create build directory and switch into it 25 | mkdir -p build && cd build 26 | # Configure 27 | cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.x/modules ../opencv-4.x 28 | # Build 29 | cmake --build . 30 | ``` 31 | 32 | 在Configure阶段,我增加了一些安装选项,包括安装路径、Python安装等 33 | 34 | ```shell 35 | cmake -D CMAKE_INSTALL_PREFIX=../install \ 36 | -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \ 37 | -D BUILD_opencv_python3=ON \ 38 | -D PYTHON3_EXECUTABLE=~/anaconda3/bin/python \ 39 | -D PYTHON_LIBRARIES=~/anaconda3/lib \ 40 | -D PYTHON_INCLUDE_DIRS=~/anaconda3/include \ 41 | .. 42 | ``` 43 | 44 | 然后执行编译和安装 45 | 46 | ```shell 47 | cmake --build . && make -j12 48 | ``` -------------------------------------------------------------------------------- /docs/opencv/configure/python/pycharm.md: -------------------------------------------------------------------------------- 1 | 2 | # [PyCharm]解码opencv python库 3 | 4 | `opencv`源码编译得到的`python`库仅是一个`.so`文件,在`vscode`中编辑代码时无法跳转到内部,但是在`pycharm`中可以查看函数头和常量定义 5 | 6 | 进入(`Ctrl+B`)之后发现是一个`__init__.py`文件,存储`python_stubs`路径下 7 | 8 | /home/zj/.PyCharm2018.3/system/python_stubs/-1678504091/cv2/__init__.py 9 | 10 | 上网查找了许久,参考 11 | 12 | [pycharm的python_stubs](https://blog.csdn.net/u013128262/article/details/81491009) 13 | 14 | [PyCharm, what is python_stubs?](https://stackoverflow.com/questions/24266114/pycharm-what-is-python-stubs) 15 | 16 | `pycharm`自己解码了`cv2.so`文件,生成了类头文件以便更好的编程 -------------------------------------------------------------------------------- /docs/opencv/draw/fillPoly.md: -------------------------------------------------------------------------------- 1 | 2 | # [掩码]绘制多边形 3 | 4 | 进行多边形的绘制和填充 5 | 6 | ## 示例程序 7 | 8 | ``` 9 | import cv2 10 | import numpy as np 11 | 12 | img = cv2.imread('box.png') 13 | 14 | # binary mask 15 | coordinates = [] 16 | coordinate = np.array([[[100, 100], [300, 100], [200, 200], [100, 200]]]) 17 | coordinate2 = np.array([[[100, 100], [300, 200], [100, 300], [100, 200]]]) 18 | print(coordinate.shape) 19 | print(coordinate2.shape) 20 | coordinates.append(coordinate) 21 | coordinates.append(coordinate2) 22 | 23 | mask = np.zeros(img.shape[:2], dtype=np.int8) 24 | mask = cv2.fillPoly(mask, coordinates, 255) 25 | 26 | # 掩码实现 27 | image = cv2.add(img, np.zeros(np.shape(img), dtype=np.uint8), mask=mask) 28 | 29 | cv2.imshow('mask', mask) 30 | cv2.imshow('image', image) 31 | cv2.waitKey(0) 32 | ``` 33 | 34 | ## 出错 35 | 36 | ``` 37 | cv2.error: OpenCV(4.4.0) /tmp/pip-req-build-f9hglo4e/opencv/modules/imgproc/src/drawing.cpp:2395: error: (-215:Assertion failed) p.checkVector(2, CV_32S) >= 0 in function 'fillPoly' 38 | ``` 39 | 40 | **注意:每个多边形坐标点数组大小为(1, 4, 2),其数据格式为np.int** 41 | 42 | ## 相关阅读 43 | 44 | * [python opencv cv2在图片中画mask掩码/掩膜](https://blog.csdn.net/xjtdw/article/details/107073396) 45 | * [cv2.fillConvexPoly()与cv2.fillPoly()填充多边形](https://www.cnblogs.com/Ph-one/p/12082692.html) -------------------------------------------------------------------------------- /docs/opencv/draw/imgs/freetype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/draw/imgs/freetype.png -------------------------------------------------------------------------------- /docs/opencv/draw/imgs/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/draw/imgs/line.png -------------------------------------------------------------------------------- /docs/opencv/draw/imgs/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/draw/imgs/rectangle.png -------------------------------------------------------------------------------- /docs/opencv/draw/imgs/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/draw/imgs/text.png -------------------------------------------------------------------------------- /docs/opencv/draw/line.md: -------------------------------------------------------------------------------- 1 | 2 | # [line]绘制线段 3 | 4 | 使用`OpenCV`函数[line](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2)绘制两点之间的线段 5 | 6 | ## 函数解析 7 | 8 | ``` 9 | CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, 10 | int thickness = 1, int lineType = LINE_8, int shift = 0); 11 | ``` 12 | 13 | * `img`:绘制图像 14 | * `pt1`:起始点 15 | * `pt2`:终止点 16 | * `color`:线条颜色 17 | * `thickness`:线条粗细 18 | * `lineType`:线条绘制类型。参考[LineTypes](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#gaf076ef45de481ac96e0ab3dc2c29a777) 19 | * `shift`:点坐标中的小数位数 20 | 21 | ## 示例 22 | 23 | ``` 24 | #include 25 | #include 26 | 27 | using namespace std; 28 | using namespace cv; 29 | 30 | int main() { 31 | int width = 400; 32 | int height = 200; 33 | 34 | // 3通道8位大小图像 35 | Mat src = Mat(height, width, CV_8UC3); 36 | cout << src.size() << endl; 37 | 38 | // 过中心点的斜线 39 | line(src, Point(10, 10), Point(390, 190), Scalar(255, 0, 0), 2); 40 | // 过中心点的直线 41 | line(src, Point(10, 100), Point(390, 100), Scalar(0, 0, 255), 2); 42 | 43 | imshow("line", src); 44 | waitKey(0); 45 | 46 | return 0; 47 | } 48 | ``` 49 | 50 | 新建图像`src`,大小为`200x400`,绘制两条线段 51 | 52 | ![](./imgs/line.png) -------------------------------------------------------------------------------- /docs/opencv/draw/rectangle.md: -------------------------------------------------------------------------------- 1 | 2 | # [rectangle]绘制边框 3 | 4 | ## 定义 5 | 6 | ``` 7 | def rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None): 8 | ``` 9 | 10 | * `img`:图像 11 | * `pt1`:左上角坐标点 12 | * `pt2`:右下角坐标点 13 | * `color`:颜色 14 | * `thickness`:线条粗细程度 15 | * `lineType`:线条类型,参考[LineTypes](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#gaf076ef45de481ac96e0ab3dc2c29a777) 16 | 17 | **Note:在输入图像上进行边框绘制** 18 | 19 | ## 示例 20 | 21 | ``` 22 | import cv2 23 | import numpy as np 24 | 25 | if __name__ == '__main__': 26 | # 创建空白3通道图像 27 | img = np.ones((500, 500, 3)) * 255 28 | 29 | cv2.rectangle(img, (20, 20), (120, 120), (0, 0, 255), thickness=1) 30 | cv2.rectangle(img, (50, 100), (380, 450), (0, 255, 0), thickness=2) 31 | 32 | cv2.imshow('img', img) 33 | cv2.waitKey(0) 34 | ``` 35 | 36 | ![](./imgs/rectangle.png) 37 | 38 | ## 相关阅读 39 | 40 | * [opencv 绘图 cvLine cvRectangle cvCircle cvEllipse cvEllipseBox cvFillPoly cvConvexPoly cvPolyLine](https://blog.csdn.net/u012005313/article/details/46802565) 41 | 42 | * [ rectangle() ](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#ga07d2f74cadcf8e305e810ce8eed13bc9) 43 | -------------------------------------------------------------------------------- /docs/opencv/draw/text.md: -------------------------------------------------------------------------------- 1 | 2 | # [text]绘制文本 3 | 4 | ## 定义 5 | 6 | ``` 7 | def putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None): # 8 | ``` 9 | 10 | * `img`:输入图像 11 | * `text`:绘制文本 12 | * `org`:左下角坐标点 13 | * `fontFace`:字体,参考[HersheyFonts](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#ga0f9314ea6e35f99bb23f29567fc16e11) 14 | * `fontscale`:字体比例因子(*最后字体大小需要该因子乘以特定字体的基本大小*) 15 | * `color`:颜色 16 | * `thicknes`:粗细程度 17 | * `bottomLeftOrigin`:如果设置为`True`,那么`org`表示左上角坐标点 18 | 19 | ## 示例 20 | 21 | ``` 22 | import cv2 23 | import numpy as np 24 | 25 | if __name__ == '__main__': 26 | # 创建空白3通道图像 27 | img = np.zeros((500, 500, 3)) 28 | 29 | cv2.putText(img, 'OpenCV', (100, 100), 1, cv2.FONT_HERSHEY_PLAIN, (0, 0, 255), thickness=1) 30 | cv2.putText(img, 'OpenCV', (200, 150), 2, cv2.FONT_HERSHEY_PLAIN, (0, 255, 0), thickness=2) 31 | 32 | # 配合边框使用 33 | cv2.rectangle(img, (250, 200), (450, 400), (255, 0, 0), thickness=1) 34 | cv2.putText(img, '0.333', (250, 400), 1, cv2.FONT_HERSHEY_PLAIN, (255, 0, 0), thickness=1) 35 | # 使用左上角坐标点 36 | cv2.putText(img, '0.333', (250, 200), 1, cv2.FONT_HERSHEY_PLAIN, (255, 0, 0), thickness=1, bottomLeftOrigin=True) 37 | 38 | cv2.imshow('img', img) 39 | cv2.waitKey(0) 40 | ``` 41 | 42 | ![](./imgs/text.png) 43 | 44 | ## 相关阅读 45 | 46 | * [opencv 绘图 cvLine cvRectangle cvCircle cvEllipse cvEllipseBox cvFillPoly cvConvexPoly cvPolyLine](https://blog.csdn.net/u012005313/article/details/46802565) 47 | 48 | * [putText()](https://docs.opencv.org/4.1.0/d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576) 49 | -------------------------------------------------------------------------------- /docs/opencv/index.md: -------------------------------------------------------------------------------- 1 | 2 | # OpenCV概述 3 | 4 | `OpenCV`(`Open Source Computer Vision Library`,开源计算机视觉库),是一个基于`BSD`协议的计算机视觉库 5 | 6 | `OpenCV`支持多语言开发,包括`C++,Python和Java` 7 | 8 | `OpenCV`支持多平台开发,包括`Windows,Linux,Max OS,Ios和Android` 9 | 10 | 官网地址:[OpenCV](https://opencv.org/) 11 | 12 | ## opencv_contrib 13 | 14 | `OpenCV`将稳定功能和`API`接口的代码放置在`opencv`库,将新特征和新功能的代码放置在`opencv_contrib`库 15 | 16 | ## github 17 | 18 | * [opencv/opencv](https://github.com/opencv/opencv) 19 | 20 | * [opencv/opencv_contrib](https://github.com/opencv/opencv_contrib) 21 | -------------------------------------------------------------------------------- /docs/opencv/process/advanced/contour.md: -------------------------------------------------------------------------------- 1 | 2 | # 轮廓检测 3 | 4 | ## 引言 5 | 6 | 定位具体物体的轮廓形状。首先需要将图像转换成为二值图像,常用的方式是 7 | 8 | * `BGR -> GRAY -> THRESH -> FILTER` 9 | 10 | 然后就可以针对边缘信息进行物体定位,首先绘制出轮廓,然后将使用矩形框进行定位。关键函数如下: 11 | 12 | * `C++` 13 | * [cv::getStructuringElement](https://docs.opencv.org/4.x/d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc) 14 | * [cv::morphologyEx](https://docs.opencv.org/3.4/d4/d86/group__imgproc__filter.html#ga67493776e3ad1a3df63883829375201f) 15 | * [cv::findContour](https://docs.opencv.org/3.4/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a) 16 | * [cv::boundingRect](https://docs.opencv.org/3.4/d3/dc0/group__imgproc__shape.html#ga103fcbda2f540f3ef1c042d6a9b35ac7) 17 | 18 | ## 相关阅读 19 | 20 | * [Morphological Transformations](https://docs.opencv.org/3.4/d4/d76/tutorial_js_morphological_ops.html) 21 | * [Extract horizontal and vertical lines by using morphological operations](https://docs.opencv.org/4.x/dd/dd7/tutorial_morph_lines_detection.html) 22 | * [边缘检测,框出物体的轮廓(使用opencv-python)](https://zhuanlan.zhihu.com/p/38739563) -------------------------------------------------------------------------------- /docs/opencv/process/base/cartToPolar.md: -------------------------------------------------------------------------------- 1 | 2 | # [cartToPolar]二维向量的大小和角度 3 | 4 | `OpenCV`提供函数[cv::cartToPolar](https://docs.opencv.org/4.0.1/d2/de8/group__core__array.html#gac5f92f48ec32cacf5275969c33ee837d0)用于计算`2`维向量的大小和角度 5 | 6 | ## 函数解析 7 | 8 | ``` 9 | CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y, 10 | OutputArray magnitude, OutputArray angle, 11 | bool angleInDegrees = false); 12 | ``` 13 | 14 | * `x`:`x`轴坐标数组;这必须是单精度或双精度浮点数组 15 | * `y`:`y`轴坐标数组,其大小和类型必须与`x`相同 16 | * `magnitude`:输出与`x`相同大小和类型的大小数组 17 | * `angle`:与x具有相同大小和类型的角度的输出数组;角度以弧度(从`0`到`2*Pi`)或度(`0`到`360`度)度量 18 | * `angleInDegrees`:标志,指示结果是以弧度(默认情况下是以弧度)还是以度度量 19 | 20 | **注意:输入数组必须具有相同精度** 21 | 22 | 输入`x/y`均为`2`维向量,其实现如下: 23 | 24 | ![](./imgs/cartToPolar.png) 25 | 26 | 源码地址:`/path/to/modules/core/test/test_arithm.cpp` 27 | 28 | ## 示例 29 | 30 | ``` 31 | #include 32 | #include 33 | 34 | using namespace std; 35 | using namespace cv; 36 | 37 | int main() { 38 | Mat xx = Mat(2, 3, CV_32FC1, Scalar(6, 0, 0)); 39 | Mat yy = Mat(2, 3, CV_32FC1, Scalar(6, 0, 0)); 40 | 41 | cout << xx << endl; 42 | cout << yy << endl; 43 | 44 | Mat mag, angle; 45 | // 输出角度 等边直角三角形,小角=45度 46 | cartToPolar(xx, yy, mag, angle, true); 47 | cout << mag << endl; 48 | cout << angle << endl; 49 | } 50 | // out 51 | [6, 6, 6; 52 | 6, 6, 6] 53 | [6, 6, 6; 54 | 6, 6, 6] 55 | [8.485281, 8.485281, 8.485281; 56 | 8.485281, 8.485281, 8.485281] 57 | [44.990456, 44.990456, 44.990456; 58 | 44.990456, 44.990456, 44.990456] 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /docs/opencv/process/base/convertTo.md: -------------------------------------------------------------------------------- 1 | 2 | # [convertTo]数据转换 3 | 4 | 图像处理过程中经常需要缩放数据值以及转换数据类型,`OpenCV`提供了函数`cv::convertTo`来完成 5 | 6 | ## 函数解析 7 | 8 | ``` 9 | void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const; 10 | ``` 11 | 12 | * `m`:输出矩阵;如果在操作之前没有分配适当的大小或类型,则会根据操作重新分配 13 | * `rtype`:输出数据类型,如果为负,表示和原图一致 14 | * `alpha`:缩放因子 15 | * `beta`:增加到缩放后数据的因子 16 | 17 | 函数`convertTo`执行如下操作: 18 | 19 | ![](./imgs/convert-to.png) 20 | 21 | ## 示例 22 | 23 | ``` 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | using namespace cv; 30 | 31 | void print(const Mat &src, const Mat &dst) { 32 | cout << "数据类型" << endl; 33 | cout << src.type() << endl; 34 | cout << dst.type() << endl; 35 | 36 | cout << "结果" << endl; 37 | cout << src << endl; 38 | cout << dst << endl; 39 | } 40 | 41 | int main() { 42 | Mat src = Mat(1, 3, CV_8UC1); 43 | 44 | src.at(0) = 3; 45 | src.at(1) = 4; 46 | src.at(2) = 5; 47 | 48 | Mat dst; 49 | src.convertTo(dst, CV_32F, 0.5); 50 | print(src, dst); 51 | } 52 | ``` 53 | 54 | 转换成浮点类型,并进行缩放 55 | 56 | ``` 57 | 数据类型 58 | 0 59 | 5 60 | 结果 61 | [ 3, 4, 5] 62 | [1.5, 2, 2.5] 63 | ``` 64 | 65 | ## 相关阅读 66 | 67 | * [convertTo()](https://docs.opencv.org/4.1.0/d3/d63/classcv_1_1Mat.html#adf88c60c5b4980e05bb556080916978b) -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/Warp_Affine_Tutorial_Theory_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/Warp_Affine_Tutorial_Theory_0.jpg -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/X.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/affine-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/affine-1.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/affine-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/affine-2.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/affine-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/affine-matrix.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/affine-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/affine-result.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/compute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/compute.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/get-rotation-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/get-rotation-matrix.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/rotate-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/rotate-python.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/affine/warp-affine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/affine/warp-affine.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/cartToPolar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/cartToPolar.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/constraint_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/constraint_border.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/contrast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/contrast.jpg -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/convert-to.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/convert-to.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/kernel.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/normalize/norm-type-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/normalize/norm-type-1.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/normalize/norm-type-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/normalize/norm-type-2.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/replicate_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/replicate_border.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/sample-edge-second-derivative.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/sample-edge-second-derivative.jpg -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Base_Figure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Base_Figure.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Binary.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Binary_Inverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Binary_Inverted.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Truncate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Truncate.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Zero.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Zero_Inverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/Threshold_Tutorial_Theory_Zero_Inverted.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/thresh-binary-inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/thresh-binary-inv.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/thresh-binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/thresh-binary.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/thresh-tozero-inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/thresh-tozero-inv.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/thresh-tozero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/thresh-tozero.png -------------------------------------------------------------------------------- /docs/opencv/process/base/imgs/thresh/thresh-truncate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/base/imgs/thresh/thresh-truncate.png -------------------------------------------------------------------------------- /docs/opencv/process/base/保存图像数据为字节文件.md: -------------------------------------------------------------------------------- 1 | 2 | # 保存图像数据为字节文件 3 | 4 | 将`OpenCV Mat`结构中的`data`数组保存为字节文件 5 | 6 | ## 关键 7 | 8 | 1. 字节文件的读写; 9 | 2. `unsigned char *`和`char *`的转换 10 | 11 | ## 实现 12 | 13 | ``` 14 | #include "opencv2/opencv.hpp" 15 | #include 16 | #include 17 | 18 | using namespace cv; 19 | using namespace std; 20 | 21 | void bin_write() { 22 | std::string img_path = "../lena.jpg"; 23 | cv::Mat img = cv::imread(img_path, cv::IMREAD_COLOR); 24 | 25 | std::ofstream file; 26 | file.open("lena_512w_512h.bin", std::ios::out | std::ios::binary); 27 | 28 | long length = img.rows * img.cols * img.channels(); 29 | file.write(reinterpret_cast(img.data), length); 30 | file.close(); 31 | } 32 | 33 | void bin_read() { 34 | cv::Mat img(512, 512, CV_8UC3); 35 | long length = img.rows * img.cols * img.channels(); 36 | 37 | std::string bin_path = "lena_512w_512h.bin"; 38 | std::ifstream file; 39 | file.open(bin_path, std::ios::in | std::ios::binary); 40 | 41 | file.read(reinterpret_cast(img.data), length); 42 | file.close(); 43 | 44 | cv::imshow("img", img); 45 | cv::waitKey(0); 46 | } 47 | ``` -------------------------------------------------------------------------------- /docs/opencv/process/base/去除小黑点.md: -------------------------------------------------------------------------------- 1 | 2 | # 去除小黑点 3 | 4 | ## 问题 5 | 6 | 图片中有大的目标区域,也存在很多小黑点。如何才能去除小黑点? 7 | 8 | ## 解决 9 | 10 | 通过形态学处理进行解决。 11 | 12 | >膨胀(dilate):求局部最大值的操作。针对白色区域进行膨胀(扩大白色区域) 13 | 14 | >腐蚀(erode):求局部最小值的操作。针对白色区域进行腐蚀(缩小白色区域) 15 | 16 | >开运算(open):先膨胀,后腐蚀。能够去除孤立的小点 17 | 18 | >闭运算(close):先腐蚀,后膨胀。能够填充小裂缝 19 | 20 | 针对问题,推荐使用开运算,可以执行多次 21 | 22 | ## 相关阅读 23 | 24 | * [新手求助,如何用OpenCV去除小块的分散区域](https://bbs.csdn.net/topics/380058906) 25 | * [OpenCV学习笔记(五)——膨胀与腐蚀](https://blog.csdn.net/weixin_41695564/article/details/79928835) 26 | * [形态学操作:膨胀与腐蚀](https://blog.csdn.net/qq_40855366/article/details/81177174) -------------------------------------------------------------------------------- /docs/opencv/process/base/运行时间统计.md: -------------------------------------------------------------------------------- 1 | 2 | # 运行时间统计 3 | 4 | ## 操作 5 | 6 | `OpenCV`提供了函数[getTickCount](https://docs.opencv.org/master/db/de0/group__core__utils.html#gae73f58000611a1af25dd36d496bf4487)和[getTickFrequency](https://docs.opencv.org/master/db/de0/group__core__utils.html#ga705441a9ef01f47acdc55d87fbe5090c)来计算程序运行时间(单位:秒) 7 | 8 | ``` 9 | double t = (double) getTickCount(); 10 | // do something ... 11 | t = ((double) getTickCount() - t) / getTickFrequency(); 12 | ``` 13 | 14 | ## 相关阅读 15 | 16 | * [Performance Measurement and Improvement Techniques](https://docs.opencv.org/4.1.0/dc/d71/tutorial_py_optimization.html) -------------------------------------------------------------------------------- /docs/opencv/process/base/非局部均值去噪.md: -------------------------------------------------------------------------------- 1 | 2 | # 非局部均值去噪 3 | 4 | ## 实现 5 | 6 | 支持灰度和彩色图像处理 7 | 8 | ``` 9 | # 灰度图像 10 | denoise = cv2.fastNlMeansDenoising(blur, h=3, templateWindowSize=7, searchWindowSize=21) 11 | # 彩色图像 12 | color = cv.fastNlMeansDenoisingColored(img,None,10,10,7,21) 13 | ``` 14 | 15 | ## 相关阅读 16 | 17 | * [Image Denoising](https://docs.opencv.org/3.4/d5/d69/tutorial_py_non_local_means.html) 18 | * [NL-means:一种非局部均值图像降噪算法 || 论文翻译及代码实现](https://zhuanlan.zhihu.com/p/45966784) 19 | * [非局部均值去噪(NL-means)](https://www.cnblogs.com/luo-peng/p/4785922.html) -------------------------------------------------------------------------------- /docs/opencv/process/feature/Understanding-Features.md: -------------------------------------------------------------------------------- 1 | 2 | # 特征/特征检测/特征描述 3 | 4 | `OpenCV`提供了一篇很好的文章来介绍什么是特征、特征检测以及特征描述符:[Understanding Features](https://docs.opencv.org/master/df/d54/tutorial_py_features_meaning.html) 5 | 6 | ## 什么是特征 7 | 8 | 对计算机视觉而言,特征就是图像中的一部分区域 9 | 10 | ## 什么是好的特征 11 | 12 | 好的特征就是从该区域向图像任何方向移动时,其内容会发现最大的变化,比如角特征(`corner features`)或者斑点特征(`blob features`) 13 | 14 | ## 什么是特征检测 15 | 16 | 发现这些图像特征的方法就是特征检测(`Feature Detection`) 17 | 18 | ## 什么是特征描述 19 | 20 | 如何用计算机语言描述图像特征所在区域,使得计算机可以在其他图像上发现相同的特征,这一方法称为特征描述(`Feature Description`) 21 | 22 | ## 小结 23 | 24 | * 好的特征 = 图像中最独特的区域 25 | * 特征检测 = 发现图像中的特征 26 | * 特征描述 = 发现不同图像中相同的特征 27 | 28 | 之后就可以进行图像对齐、图像分类、图像检测等任务了 -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/matcher/knnmatch_sift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/matcher/knnmatch_sift.png -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/matcher/match_sift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/matcher/match_sift.png -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/sift/sift_dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/sift/sift_dog.jpg -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/sift/sift_keypoints-gray.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/sift/sift_keypoints-gray.jpg -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/sift/sift_keypoints.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/sift/sift_keypoints.jpg -------------------------------------------------------------------------------- /docs/opencv/process/feature/imgs/sift/sift_local_extrema.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/feature/imgs/sift/sift_local_extrema.jpg -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/Laplace_Operator_Tutorial_Theory_Previous.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/Laplace_Operator_Tutorial_Theory_Previous.jpg -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/Laplace_Operator_Tutorial_Theory_ddIntensity.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/Laplace_Operator_Tutorial_Theory_ddIntensity.jpg -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/canny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/canny.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/filter2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/filter2d.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/gaussian-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/gaussian-filter.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/gradient-compute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/gradient-compute.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/gradient-like-compute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/gradient-like-compute.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/gradient.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/kernel.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/laplacian-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/laplacian-1.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/laplacian-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/laplacian-2.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/laplacian-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/laplacian-3.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/laplacian-kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/laplacian-kernel.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/laplacian-math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/laplacian-math.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/replicate_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/replicate_border.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sample-edge-second-derivative.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sample-edge-second-derivative.jpg -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/scharr-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/scharr-1.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/scharr-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/scharr-2.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/scharr-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/scharr-3.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/scharr-kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/scharr-kernel.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sobel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sobel-1.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sobel-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sobel-2.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sobel-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sobel-3.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sobel-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sobel-horizontal.png -------------------------------------------------------------------------------- /docs/opencv/process/filter/imgs/sobel-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/opencv/process/filter/imgs/sobel-vertical.png -------------------------------------------------------------------------------- /docs/python/grammar/around.md: -------------------------------------------------------------------------------- 1 | 2 | # [around]四舍五入 3 | 4 | 函数[np.around](https://numpy.org/doc/1.18/reference/generated/numpy.around.html)能够对数据执行四舍五入操作 5 | 6 | ## 定义 7 | 8 | >numpy.around(a, decimals=0, out=None)[source] 9 | 10 | * `a`:输入数据,可以是单个数字,或者列表/数组 11 | * `decimals`:保留几位小数。默认不保留小数 12 | 13 | ## 示例 14 | 15 | ``` 16 | # 单个数字 17 | >>> np.around(3.33) 18 | 3.0 19 | # 数组 20 | >>> a = np.random.randn(3) 21 | >>> a 22 | array([ 0.02557499, -0.05847877, -1.53689999]) 23 | >>> 24 | >>> np.around(a) 25 | array([ 0., -0., -2.]) 26 | # 保留2位小数 27 | >>> np.around(a, decimals=2) 28 | array([ 0.03, -0.06, -1.54]) 29 | ``` -------------------------------------------------------------------------------- /docs/python/grammar/collections-defaultdict.md: -------------------------------------------------------------------------------- 1 | 2 | # [collections][defaultdict]更安全的dict 3 | 4 | `defaultdict`支持`dict`的用法,并且提供了更加安全的设置 5 | 6 | ## 默认值设置 7 | 8 | `defaultdict`内置了一个工厂函数,当访问不存在的键时,会自动生成一个内置类型的对象 9 | 10 | ``` 11 | # 设置内置类型为int 12 | from collections import defaultdict 13 | 14 | if __name__ == '__main__': 15 | a = defaultdict(int) 16 | print(a) 17 | # 当访问不存在键`a`时,得到0 18 | print(a['a']) 19 | ################# 输出 20 | defaultdict(, {}) 21 | 0 22 | ``` 23 | 24 | ## 相关阅读 25 | 26 | * [是时候用 defaultdict 和 Counter 代替 dictionary 了](https://zhuanlan.zhihu.com/p/68407137) 27 | 28 | * [1-2 collections中deque,defaultdict,OrderedDict](https://www.jianshu.com/p/291bb5641c56) 29 | 30 | * [Python 3 collections.defaultdict() 与 dict的使用和区别](https://www.cnblogs.com/herbert/archive/2013/01/09/2852843.html) 31 | -------------------------------------------------------------------------------- /docs/python/grammar/collections-deque.md: -------------------------------------------------------------------------------- 1 | 2 | # [collections][deque]双向队列 3 | 4 | `list`是单向队列,而`deque`是双向队列 5 | 6 | ## list方法 7 | 8 | `deque`支持`list`常用的用法,包括 9 | 10 | ``` 11 | >>> from collections import deque 12 | >>> a = deque(range(3)) 13 | >>> a 14 | deque([0, 1, 2]) 15 | # 队尾添加 16 | >>> a.append(4) 17 | >>> a 18 | deque([0, 1, 2, 4]) 19 | # 检索下标 20 | >>> a.index(2) 21 | 2 22 | # 队尾弹出 23 | >>> a.pop() 24 | 4 25 | >>> a 26 | deque([0, 1, 2]) 27 | # 读取指定下标值 28 | >>> a[2] 29 | 2 30 | ``` 31 | 32 | ## deque方法 33 | 34 | 除此之外,`deque`还支持前向操作 35 | 36 | ``` 37 | appendleft(x) 头部添加元素 38 | extendleft(iterable) 头部添加多个元素 39 | popleft() 头部返回并删除 40 | rotate(n=1) 旋转 41 | maxlen 最大空间,如果是无边界的,返回None 42 | ``` 43 | 44 | ## maxlen 45 | 46 | `deque`支持有限长度 47 | 48 | ``` 49 | >>> a = deque(range(3), maxlen=3) 50 | >>> a 51 | deque([0, 1, 2], maxlen=3) 52 | >>> a.append(4) 53 | >>> a 54 | deque([1, 2, 4], maxlen=3) 55 | >>> a.appendleft(22) 56 | >>> a 57 | deque([22, 1, 2], maxlen=3) 58 | ``` 59 | 60 | 当队列到达最大长度后,再次添加元素,会进行替换操作 61 | 62 | ## rotate 63 | 64 | 将序列队头/队尾元素进行移动 65 | 66 | ``` 67 | >>> a = deque(range(8)) 68 | >>> a 69 | deque([0, 1, 2, 3, 4, 5, 6, 7]) 70 | # 将队尾元素向队头移动 71 | >>> a.rotate(2) 72 | >>> a 73 | deque([6, 7, 0, 1, 2, 3, 4, 5]) 74 | # 将队头元素向队尾移动 75 | >>> a.rotate(-2) 76 | >>> a 77 | deque([0, 1, 2, 3, 4, 5, 6, 7]) 78 | ``` 79 | 80 | ## 相关阅读 81 | 82 | * [python3:deque和list的区别](https://blog.csdn.net/qq_34979346/article/details/83540389) 83 | 84 | * [python list与deque在存储超大数组的区别](https://blog.csdn.net/qq_37887537/article/details/93722103) 85 | -------------------------------------------------------------------------------- /docs/python/grammar/enumerate.md: -------------------------------------------------------------------------------- 1 | 2 | # [enumerate]遍历 3 | 4 | ## 使用 5 | 6 | ``` 7 | class enumerate(object) 8 | | enumerate(iterable, start=0) 9 | | 10 | | Return an enumerate object. 11 | | 12 | | iterable 13 | | an object supporting iteration 14 | ``` 15 | 16 | 遍历可迭代对象,同时返回数组下标和值 17 | 18 | ``` 19 | >>> import numpy as np 20 | >>> a = np.arange(30, 40) 21 | >>> a 22 | array([30, 31, 32, 33, 34, 35, 36, 37, 38, 39]) 23 | >>> for idx, item in enumerate(a, 0): 24 | ... print(idx, item) 25 | ... 26 | 0 30 27 | 1 31 28 | 2 32 29 | 3 33 30 | 4 34 31 | 5 35 32 | 6 36 33 | 7 37 34 | 8 38 35 | 9 39 36 | ``` 37 | 38 | 可以指定起始位置下标值(**Note:仅改变下标起始值,仍旧会完整遍历数组**) 39 | 40 | ``` 41 | >>> for idx, item in enumerate(a, 10): 42 | ... print(idx, item) 43 | ... 44 | 10 30 45 | 11 31 46 | 12 32 47 | 13 33 48 | 14 34 49 | 15 35 50 | 16 36 51 | 17 37 52 | 18 38 53 | 19 39 54 | ``` 55 | 56 | ## 相关阅读 57 | 58 | * [Python enumerate() 函数](https://www.runoob.com/python/python-func-enumerate.html) -------------------------------------------------------------------------------- /docs/python/grammar/f-strings.md: -------------------------------------------------------------------------------- 1 | 2 | # [py3.6][f-strings]字符串连接 3 | 4 | 最近接触到一种新的字符串连接方式:[f-strings](https://www.python.org/dev/peps/pep-0498/#how-to-denote-f-strings)。这是从`Python3.6`开始的一个新的语法糖 5 | 6 | ## 实现 7 | 8 | ``` 9 | str_demo = f'balabala {TEXT} balabala' 10 | ``` 11 | 12 | 在字符串引号前面添加前缀`f`,在字符串内部的大括号里面添加前面定义的变量`TEXT`。在编译期间,`Python`解释器会自动解析该字符串的连接操作,此操作类似于之前的`str.format()`方法 13 | 14 | ## 示例 15 | 16 | ``` 17 | >>> text='abcd' 18 | >>> text 19 | 'abcd' 20 | >>> f'this is {text}' 21 | 'this is abcd' 22 | >>> 23 | >>> num=100 24 | >>> f'num is {num}' 25 | 'num is 100' 26 | ``` -------------------------------------------------------------------------------- /docs/python/grammar/imgs/decorator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/python/grammar/imgs/decorator.png -------------------------------------------------------------------------------- /docs/python/grammar/imgs/tqdm-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/python/grammar/imgs/tqdm-1.gif -------------------------------------------------------------------------------- /docs/python/grammar/imgs/tqdm-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/python/grammar/imgs/tqdm-2.gif -------------------------------------------------------------------------------- /docs/python/grammar/imgs/tqdm-3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/python/grammar/imgs/tqdm-3.gif -------------------------------------------------------------------------------- /docs/python/grammar/imgs/xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/python/grammar/imgs/xml.png -------------------------------------------------------------------------------- /docs/python/grammar/itertools-product.md: -------------------------------------------------------------------------------- 1 | 2 | # [itertools][product]嵌套循环 3 | 4 | 可迭代对象输入的笛卡儿积。大致相当于生成器表达式中的嵌套循环 5 | 6 | ## product(A, B) 7 | 8 | 等同于`((x,y) for x in A for y in B)` 9 | 10 | ``` 11 | >>> from itertools import product 12 | >>> import numpy a snp 13 | >>> a = np.arange(3) 14 | >>> b = np.arange(5, 9) 15 | >>> a 16 | array([0, 1, 2]) 17 | >>> b 18 | array([5, 6, 7, 8]) 19 | >>> ((x, y) for x in a for y in b) 20 | at 0x7fb108a9fed0> 21 | >>> list(((x, y) for x in a for y in b)) 22 | [(0, 5), (0, 6), (0, 7), (0, 8), (1, 5), (1, 6), (1, 7), (1, 8), (2, 5), (2, 6), (2, 7), (2, 8)] 23 | >>> product(a,b) 24 | 25 | >>> list(product(a,b)) 26 | [(0, 5), (0, 6), (0, 7), (0, 8), (1, 5), (1, 6), (1, 7), (1, 8), (2, 5), (2, 6), (2, 7), (2, 8)] 27 | ``` 28 | 29 | ## product(A, repeat=2) 30 | 31 | 等同于`product(A, A)`,也就是`((x, y) for x in A for y in A)` 32 | 33 | ``` 34 | >>> product(a, a) 35 | 36 | >>> list(product(a, a)) 37 | [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 38 | >>> list(product(a, repeat=2)) 39 | [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 40 | ``` 41 | 42 | ## 相关阅读 43 | 44 | * [product](https://docs.python.org/zh-cn/3.7/library/itertools.html#itertools.product) -------------------------------------------------------------------------------- /docs/python/grammar/json.md: -------------------------------------------------------------------------------- 1 | 2 | # [json]文件读写 3 | 4 | ## 导入 5 | 6 | ``` 7 | import json 8 | ``` 9 | 10 | ## 示例 11 | 12 | 读取文件 13 | 14 | ``` 15 | import json 16 | 17 | if __name__ == '__main__': 18 | ... 19 | ... 20 | with open(file_path, 'r') as f: 21 | json_data = json.load(f) 22 | 23 | ``` 24 | 25 | 写入文件 26 | 27 | ``` 28 | import json 29 | 30 | if __name__ == '__main__': 31 | ... 32 | ... 33 | with open(file_path, 'w') as f: 34 | json.dump(json_data, f) 35 | ``` 36 | 37 | ## 相关阅读 38 | 39 | * [6.2 读写JSON数据](https://python3-cookbook.readthedocs.io/zh_CN/latest/c06/p02_read-write_json_data.html) -------------------------------------------------------------------------------- /docs/python/grammar/list.md: -------------------------------------------------------------------------------- 1 | 2 | # [list]排序 3 | 4 | ## 定义 5 | 6 | ``` 7 | list.sort(cmp=None, key=None, reverse=False) 8 | ``` 9 | 10 | * `cmp`:指定排序方法 11 | * `key`:指定比较元素 12 | * `reverse`:排序规则:`True`表示降序,`False`表示升序 13 | 14 | ## 示例一 15 | 16 | ``` 17 | import random 18 | 19 | if __name__ == '__main__': 20 | a = random.sample(range(10), 3) 21 | print(a) 22 | 23 | # 降序 24 | a.sort(reverse=True) 25 | print(a) 26 | # 升序 27 | a.sort() 28 | print(a) 29 | ######################3 输出 30 | [8, 1, 5] 31 | [8, 5, 1] 32 | [1, 5, 8] 33 | ``` 34 | 35 | ## 示例二 36 | 37 | 列表中包含列表,按子列表中指定元素进行排序 38 | 39 | ``` 40 | import random 41 | 42 | if __name__ == '__main__': 43 | a = [random.sample(range(10), 3), random.sample(range(10), 3), random.sample(range(10), 3)] 44 | print(a) 45 | 46 | # 按子列表中最后一个元素进行排序 47 | a.sort(key=lambda x: x[2], reverse=True) 48 | print(a) 49 | ######################## 输出 50 | [[0, 9, 5], [0, 2, 6], [5, 7, 0]] 51 | [[0, 2, 6], [0, 9, 5], [5, 7, 0]] 52 | ``` 53 | 54 | ## 示例三 55 | 56 | 列表中包含字典,按字典中指定元素进行排序。其操作和示例二类似 57 | 58 | ``` 59 | a.sort(key=lambda x: x['指定key'], reverse=True) 60 | ``` 61 | 62 | ## 相关阅读 63 | 64 | * [Python List sort()方法](https://www.runoob.com/python/att-list-sort.html) -------------------------------------------------------------------------------- /docs/python/grammar/monkey-patch.md: -------------------------------------------------------------------------------- 1 | 2 | # Monkey Patch 3 | 4 | ## 动态替换 5 | 6 | 今天听到一个很有意思的术语 - `Monkey Patch`,意思是在程序运行过程中替换某一模块实现,而不是在磁盘上替换相应的代码文件。 7 | 8 | >The definition of the term varies depending upon the community using it. In Ruby,[2] Python,[3] and many other dynamic programming languages, the term monkey patch only refers to dynamic modifications of a class or module at runtime, motivated by the intent to patch existing third-party code as a workaround to a bug or feature which does not act as desired. Other forms of modifying classes at runtime have different names, based on their different intents. For example, in Zope and Plone, security patches are often delivered using dynamic class modification, but they are called hot fixes.[citation needed] 9 | 10 | 除了`Monkey Patch`之外,还有相类似的名字,比如`Hot Fixes(热修复)`等等。 11 | 12 | 其实仔细一想,在脚本语言(比如`Python`)中,动态替换类、属性或者函数的操作非常普遍。 13 | 14 | ## 相关阅读 15 | 16 | * [Monkey patch](https://en.wikipedia.org/wiki/Monkey_patch) 17 | * [What is monkey patching?](https://stackoverflow.com/questions/5626193/what-is-monkey-patching) 18 | * [关于Monkey Patch猴子补丁](https://www.cnblogs.com/robert871126/p/10107258.html) -------------------------------------------------------------------------------- /docs/python/grammar/pprint.md: -------------------------------------------------------------------------------- 1 | 2 | # [pprint]更易读的打印 3 | 4 | 相比于`print`,`pprint`提供了更加易读的打印结果 5 | 6 | ## 使用 7 | 8 | ``` 9 | >>> import pprint 10 | >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] 11 | >>> stuff.insert(0, stuff) 12 | >>> print(stuff) 13 | [[...], 'spam', 'eggs', 'lumberjack', 'knights', 'ni'] 14 | >>> pprint.pprint(stuff) 15 | [, 16 | 'spam', 17 | 'eggs', 18 | 'lumberjack', 19 | 'knights', 20 | 'ni'] 21 | ``` 22 | 23 | ## 相关阅读 24 | 25 | * [pprint — Data pretty printer](https://docs.python.org/3/library/pprint.html) 26 | 27 | * [python中pprint模块](https://blog.csdn.net/ZEroJAVAson/article/details/88649650) 28 | -------------------------------------------------------------------------------- /docs/python/grammar/slice.md: -------------------------------------------------------------------------------- 1 | 2 | # [slice]扩展切片操作 3 | 4 | 切片操作是`Python`实现中最常用的功能之一,重新小结几种不同的切片操作 5 | 6 | ## 基本切片 7 | 8 | 基本切片语法如下: 9 | 10 | ``` 11 | list[start:stop] 12 | ``` 13 | 14 | 常用以下几种实现方式: 15 | 16 | * 缺省`start` 17 | * 语法:`list[:stop]` 18 | * 作用:取前`stop`个元素 19 | * 缺省`stop` 20 | * 语法:`list[start:]` 21 | * 作用:取`start`开始的所有元素 22 | * 同时缺省`start`和`stop` 23 | * 语法:`list[:]` 24 | * 作用:取整个列表的所有元素 25 | 26 | 通常情况下,下标`start`小于`stop`,如果出现`start`大于等于`stop`,那么返回空列表 27 | 28 | ## 扩展切片 29 | 30 | 扩展切片语法如下: 31 | 32 | ``` 33 | a[start:stop:step] 34 | ``` 35 | 36 | 增加了`step`参数,表示每隔多少个位置取一个元素,如果为空,默认为`1`,即取`[start, stop)`区间内所有的元素 37 | 38 | ## 另一种扩展切片:`...` 39 | 40 | 阅读源码过程中还发现了一个切片符号`...`,其实现如下: 41 | 42 | ``` 43 | >>> import numpy as np 44 | >>> a = np.random.randn(2, 3, 4) 45 | >>> a 46 | array([[[-1.08746212, -1.98456057, 0.31604132, 0.77781412], 47 | [ 0.09395506, 0.89095723, 0.33838468, 1.7124017 ], 48 | [ 0.91403118, -0.27132943, 2.10017449, -0.05663262]], 49 | 50 | [[ 0.38814181, 0.30023491, -0.0099694 , 0.53520844], 51 | [-2.01299842, -0.17652996, 0.261344 , 0.19216268], 52 | [ 0.15511314, -0.48549088, -0.30289901, 1.46871216]]]) 53 | >>> a[:, :, 3] 54 | array([[ 0.77781412, 1.7124017 , -0.05663262], 55 | [ 0.53520844, 0.19216268, 1.46871216]]) 56 | >>> a[..., 3] 57 | array([[ 0.77781412, 1.7124017 , -0.05663262], 58 | [ 0.53520844, 0.19216268, 1.46871216]]) 59 | ``` 60 | 61 | ## 相关阅读 62 | 63 | * [python 切片(slice)](https://blog.csdn.net/u012005313/article/details/48159477) 64 | 65 | * [[Python]切片完全指南(语法篇)](https://zhuanlan.zhihu.com/p/79541418) 66 | -------------------------------------------------------------------------------- /docs/python/grammar/tqdm.md: -------------------------------------------------------------------------------- 1 | 2 | # [tqdm]进度条 3 | 4 | [tqdm](https://github.com/tqdm/tqdm)提供了一个简易的方式实现进度条 5 | 6 | ## 安装 7 | 8 | ``` 9 | pip install tqdm 10 | ``` 11 | 12 | ## 示例 13 | 14 | `tqdm`提供了多个公式以实现进度条,常用的有以下几种方式 15 | 16 | 1. 基于可迭代对象 17 | 2. 手动设置迭代进度 18 | 19 | ### tqdm() 20 | 21 | ``` 22 | from tqdm import tqdm 23 | from time import sleep 24 | 25 | text = "" 26 | for char in tqdm(["a", "b", "c", "d"]): 27 | sleep(0.25) 28 | text = text + char 29 | print(text) 30 | ``` 31 | 32 | ![](./imgs/tqdm-1.gif) 33 | 34 | ### trange() 35 | 36 | ``` 37 | from time import sleep 38 | from tqdm import trange 39 | 40 | for i in trange(100): 41 | sleep(0.01) 42 | ``` 43 | 44 | ![](./imgs/tqdm-2.gif) 45 | 46 | ### with tqdm(total=xxx) as pbar 47 | 48 | ``` 49 | from tqdm import tqdm 50 | from time import sleep 51 | 52 | with tqdm(total=100) as pbar: 53 | for i in range(10): 54 | sleep(0.1) 55 | pbar.update(10) 56 | ``` 57 | 58 | ![](./imgs/tqdm-3.gif) 59 | 60 | ### pbar = tqdm(total=100) 61 | 62 | ``` 63 | from tqdm import tqdm 64 | from time import sleep 65 | 66 | pbar = tqdm(total=100) 67 | for i in range(10): 68 | sleep(0.1) 69 | pbar.update(10) 70 | pbar.close() 71 | ``` 72 | -------------------------------------------------------------------------------- /docs/python/grammar/xmltodict.md: -------------------------------------------------------------------------------- 1 | 2 | # [xmltodict]读取XML文件 3 | 4 | 之前学习过使用包[xml.etree.cElementTree](./[python]读取XML文件.md)来读取`XML`文件,今天发现一个新的包[xmltodict](https://pypi.org/project/xmltodict/),将`XML`文件转换成字典形式进行读取 5 | 6 | ## 安装 7 | 8 | ``` 9 | $ conda install xmltodict 10 | ``` 11 | 12 | ## 关键函数 13 | 14 | 解析给定的`XML`输入并将其转换为字典 15 | 16 | ``` 17 | def parse(xml_input, encoding=None, expat=expat, process_namespaces=False, 18 | namespace_separator=':', disable_entities=True, **kwargs): 19 | ``` 20 | 21 | 参数`xml_input`为字符串(`XML`文件,不是文件名)或者文件对象 22 | 23 | 输入字典,生成`XML`文件字符串 24 | 25 | ``` 26 | def unparse(input_dict, output=None, encoding='utf-8', full_document=True, 27 | short_empty_elements=False, 28 | **kwargs): 29 | ``` 30 | 31 | ## 示例 32 | 33 | 输入一个`xml`格式字符串,使用函数`parse`解析成字典;使用函数`unparse`将字典解析成`xml`格式字符串 34 | 35 | ``` 36 | import xmltodict 37 | 38 | xxxml_str = "OK HAHAHA" 39 | 40 | xml_parse_dict = xmltodict.parse(xxxml_str) 41 | print(xml_parse_dict) 42 | print(xml_parse_dict['source']['database']) 43 | 44 | dict_unparse_xml = xmltodict.unparse(xml_parse_dict) 45 | print(dict_unparse_xml) 46 | # 输出 47 | OrderedDict([('source', OrderedDict([('database', 'OK HAHAHA')]))]) 48 | OK HAHAHA 49 | 50 | OK HAHAHA 51 | ``` 52 | 53 | 还可以使用`parse`函数直接解析文件对象 54 | 55 | ``` 56 | import xmltodict 57 | 58 | with open('./data/image-localization-dataset/training_images/eggplant_36.xml', 'rb') as f: 59 | xml_parse_dict = xmltodict.parse(f) 60 | print(xml_parse_dict) 61 | ``` -------------------------------------------------------------------------------- /docs/python/tool/converage.md: -------------------------------------------------------------------------------- 1 | 2 | # [coverage]测试代码覆盖率 3 | 4 | 使用[ nedbat/coveragepy ](https://github.com/nedbat/coveragepy)计算测试代码覆盖率 -------------------------------------------------------------------------------- /docs/python/tool/pip.md: -------------------------------------------------------------------------------- 1 | 2 | # [pip]更新国内镜像源 3 | 4 | 有两种方式配置国内镜像源: 5 | 6 | 1. 参数配置 7 | 2. 文件配置 8 | 9 | ## 参数配置 10 | 11 | 添加`-i`参数,指定国内镜像源 12 | 13 | ``` 14 | $ pip install <软件名> -i https://pypi.tuna.tsinghua.edu.cn/simple 15 | ``` 16 | 17 | 可选的有 18 | 19 | ``` 20 | 阿里云http://mirrors.aliyun.com/pypi/simple/ 21 | 中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/ 22 | 豆瓣(douban)http://pypi.douban.com/simple/ 23 | 清华大学https://pypi.tuna.tsinghua.edu.cn/simple/ 24 | 中国科学技术大学http://pypi.mirrors.ustc.edu.cn/simple/ 25 | ``` 26 | 27 | ## 文件配置 28 | 29 | 修改配置文件`~/.pip/pip.conf`,添加 30 | 31 | ``` 32 | [global] 33 | index-url = https://pypi.doubanio.com/simple 34 | trusted-host = pypi.doubanio.com 35 | ``` 36 | 37 | ## 相关阅读 38 | 39 | * [python - pip换源,更换pip源到国内镜像](https://blog.csdn.net/xuezhangjun0121/article/details/81664260) 40 | * [Python pip 修改镜像源为豆瓣源](https://www.douban.com/note/672475302/) -------------------------------------------------------------------------------- /docs/python/tool/pnno.md: -------------------------------------------------------------------------------- 1 | 2 | # [pnno]转换json/dict数据为voc-xml 3 | 4 | 需要将标注数据保存为`VOC XML`格式,在网上查了一些资料。有多种方式可以实现,下面使用[martinblech/xmltodict](https://github.com/martinblech/xmltodict)将`json/dict`保存为`xml`文件 5 | 6 | ## 函数定义 7 | 8 | ### parse 9 | 10 | 使用`parse`读取`xml`文件,保存为`dict`数据 11 | 12 | ``` 13 | def parse(xml_input, encoding=None, expat=expat, process_namespaces=False, 14 | namespace_separator=':', disable_entities=True, **kwargs): 15 | ``` 16 | 17 | * `xml_input`:`xml`文件路径或者`file-like object` 18 | 19 | ### unparse 20 | 21 | 使用`unparse`将`dict`数据保存为`xml`文件 22 | 23 | ``` 24 | def unparse(input_dict, output=None, encoding='utf-8', full_document=True, 25 | short_empty_elements=False, 26 | **kwargs): 27 | ``` 28 | 29 | * `input_dict`:字典数据 30 | * `output`:默认为`None`,则函数将转换后的`xml`数据字符串返回;如果设置文件路径,则保存在本地 31 | 32 | ## 示例 33 | 34 | 参考:[python中xml和json数据相互转换](https://blog.csdn.net/qq_33196814/article/details/99992771) 35 | 36 | ## 集成 37 | 38 | 使用工具[ zjykzj/pnno](https://github.com/zjykzj/pnno)自动转换生成`VOC`格式`xml`文件 39 | 40 | ## 相关阅读 41 | 42 | * [Convert JSON to XML in Python](https://stackoverflow.com/questions/8988775/convert-json-to-xml-in-python/19474571) 43 | * [Python – JSON to XML](https://www.geeksforgeeks.org/python-json-to-xml/) 44 | * [How to convert JSON to XML using Python](https://www.codespeedy.com/how-to-convert-json-to-xml-using-python/) -------------------------------------------------------------------------------- /docs/pytorch/cuda/benchmark.md: -------------------------------------------------------------------------------- 1 | 2 | # [benchmark]训练加速 3 | 4 | 阅读工程源码时发现了一种加速训练的方法: 5 | 6 | ``` 7 | if torch.cuda.is_available(): 8 | # This flag allows you to enable the inbuilt cudnn auto-tuner to 9 | # find the best algorithm to use for your hardware. 10 | torch.backends.cudnn.benchmark = True 11 | ``` 12 | 13 | ## 原理 14 | 15 | 因为存在多种卷积实现算法,所以设置`true`将会启动内置`cudnn auto-tuner`,帮助寻找最优的计算算法,从而实现加速目的。其前提条件是每次输入的尺寸固定,如果不固定,那么找到的加速算法不一定适合不同大小的输入计算,不会得到加速效果 16 | 17 | ## 测试 18 | 19 | 参考:[torch.backends.cudnn.benchmark ?!](https://zhuanlan.zhihu.com/p/73711222) 20 | 21 | ## 相关阅读 22 | 23 | * [What does torch.backends.cudnn.benchmark do?](https://discuss.pytorch.org/t/what-does-torch-backends-cudnn-benchmark-do/5936) 24 | 25 | * [Can you use torch.backends.cudnn.benchmark = True after resizing images?](https://discuss.pytorch.org/t/can-you-use-torch-backends-cudnn-benchmark-true-after-resizing-images/40659) 26 | -------------------------------------------------------------------------------- /docs/pytorch/cuda/empty_cache.md: -------------------------------------------------------------------------------- 1 | 2 | # [empty_cache]清空显存 3 | 4 | 查看工程源码时发现在训练完成后,测试模型之前调用了函数[torch.cuda.empty_cache()](https://pytorch.org/docs/stable/cuda.html#torch.cuda.empty_cache) 5 | 6 | ``` 7 | logger.info('Start evaluating...') 8 | torch.cuda.empty_cache() # speed up evaluating after training finished 9 | do_evaluation(cfg, model, distributed=args.distributed) 10 | ``` 11 | 12 | 其作用是释放缓存分配器当前持有的所有未占用的缓存内存,以便这些内存可以在其他GPU应用程序中使用,并在`nvidia-smi`中可见 13 | 14 | ## 使用 15 | 16 | 对于何时使用该函数清空缓存内存,参考: 17 | 18 | [About torch.cuda.empty_cache()](https://discuss.pytorch.org/t/about-torch-cuda-empty-cache/34232) 19 | 20 | [What is torch.cuda.empty_cache do and where should i add it?](https://discuss.pytorch.org/t/what-is-torch-cuda-empty-cache-do-and-where-should-i-add-it/40975) 21 | 22 | [Why does torch.cuda.empty_cache() make the GPU utilization near 0 and slow down the training time?](https://discuss.pytorch.org/t/why-does-torch-cuda-empty-cache-make-the-gpu-utilization-near-0-and-slow-down-the-training-time/65196) 23 | 24 | [pytorch GPU显存释放的问题?](https://www.zhihu.com/question/68509057/answer/566619040) 25 | 26 | 并不推荐在实现中频繁调用该函数。仅在显存不足时进行调用即可 -------------------------------------------------------------------------------- /docs/pytorch/cuda/指定哪张卡运行.md: -------------------------------------------------------------------------------- 1 | 2 | # [CUDA_VISIBLE_DEVICES]指定哪张卡运行 3 | 4 | ## 使用 5 | 6 | 在多卡环境下,可以设置环境变量`CUDA_VISIBLE_DEVICES`来指定要运行的`GPU` 7 | 8 | ## 示例 9 | 10 | 单张卡 11 | 12 | ``` 13 | # 设置方式一 14 | CUDA_VISIBLE_DEVICES=0 python xxx.py 15 | # 设置方式二 16 | export CUDA_VISIBLE_DEVICES=0 17 | pytohn xxx.py 18 | ``` 19 | 20 | 多张卡 21 | 22 | ``` 23 | CUDA_VISIBLE_DEVICES='0,1' 24 | ``` 25 | 26 | ## 相关阅读 27 | 28 | * [CUDA Pro Tip: Control GPU Visibility with CUDA_VISIBLE_DEVICES](https://devblogs.nvidia.com/cuda-pro-tip-control-gpu-visibility-cuda_visible_devices/) -------------------------------------------------------------------------------- /docs/pytorch/cuda/监控显存使用.md: -------------------------------------------------------------------------------- 1 | 2 | # 监控显存使用 3 | 4 | `PyTorch`提供了两个函数用于显存查询: 5 | 6 | * [memory_allocated](https://pytorch.org/docs/stable/cuda.html#torch.cuda.memory_allocated) 7 | * [max_memory_allocated](https://pytorch.org/docs/stable/cuda.html?highlight=max_memory_allocated#torch.cuda.max_memory_allocated) 8 | 9 | ## memory_allocated 10 | 11 | >torch.cuda.memory_allocated(device=None) 12 | 13 | 查询指定`GPU`中使用的显存大小(字节) 14 | 15 | ## max_memory_allocated 16 | 17 | >torch.cuda.max_memory_allocated(device=None) 18 | 19 | 返回给定设备的张量占用的最大`GPU`内存(字节) -------------------------------------------------------------------------------- /docs/pytorch/grammar/AdaptiveMaxPool-AdaptiveAvgPool.md: -------------------------------------------------------------------------------- 1 | 2 | # [AdaptiveMaxPool][AdaptiveAvgPool]自适应池化层操作 3 | 4 | 空间金字塔池化操作解放了固定输入的限制,保证了输出固定大小,在`PyTorch`中使用`AdaptiveMaxPool`和`AdaptiveAvgPool`实现 5 | 6 | ## AdaptiveMaxPool 7 | 8 | 包含了一维/二维/三维实现 9 | 10 | * [AdaptiveMaxPool1d](https://pytorch.org/docs/stable/nn.html#adaptivemaxpool1d) 11 | * [AdaptiveMaxPool2d](https://pytorch.org/docs/stable/nn.html#adaptivemaxpool2d) 12 | * [AdaptiveMaxPool3d](https://pytorch.org/docs/stable/nn.html#adaptivemaxpool3d) 13 | 14 | ### 一维示例 15 | 16 | ``` 17 | >>> import torch 18 | >>> import torch.nn as nn 19 | >>> 20 | >>> input = torch.randn(1, 1, 8) 21 | >>> input 22 | tensor([[[ 1.6188, -0.0436, 1.8603, 0.9043, 0.1372, 0.6567, -0.5700, 23 | 0.8480]]]) 24 | >>> 25 | >>> m = nn.AdaptiveMaxPool1d(5) 26 | >>> m 27 | AdaptiveMaxPool1d(output_size=5) 28 | >>> 29 | >>> output = m(input) 30 | >>> output 31 | tensor([[[1.6188, 1.8603, 0.9043, 0.6567, 0.8480]]]) 32 | >>> output.size() 33 | torch.Size([1, 1, 5]) 34 | ``` 35 | 36 | 在定义`AdaptiveMaxPool1d`对象时确定固定输出大小即可 37 | 38 | ### 二维示例 39 | 40 | 二维操作和一维操作一样,设置输出大小即可 41 | 42 | ``` 43 | >>> input = torch.randn((1, 1, 8, 8)) 44 | >>> m = nn.AdaptiveMaxPool2d((3, 3)) 45 | >>> output = m(input) 46 | >>> output.size() 47 | torch.Size([1, 1, 3, 3]) 48 | >>> output 49 | tensor([[[[1.4030, 2.3893, 1.1493], 50 | [0.8610, 1.9903, 0.9673], 51 | [1.1998, 1.9903, 1.9642]]]]) 52 | ``` 53 | 54 | ## AdaptiveAvgPool 55 | 56 | 参考:[自适应平均池化层](https://blog.zhujian.life/posts/ba337bfa.html) -------------------------------------------------------------------------------- /docs/pytorch/grammar/clamp.md: -------------------------------------------------------------------------------- 1 | 2 | # [clamp]限制取值范围 3 | 4 | [torch.clamp](https://pytorch.org/docs/stable/torch.html#torch.clamp)和`numpy.clip`作用一致,用于限制数组取值范围 5 | 6 | ## 定义 7 | 8 | >torch.clamp(input, min, max, out=None) → Tensor 9 | 10 | $$ 11 | y_{i}=\left\{\begin{matrix} 12 | min & if x_{i} max 15 | \end{matrix}\right. 16 | $$ 17 | 18 | 如果要作用于`input`,则使用`torch.clamp_` 19 | 20 | ## 示例 21 | 22 | ``` 23 | >>> import torch 24 | >>> a = torch.arange(12).reshape(3,4) 25 | >>> a 26 | tensor([[ 0, 1, 2, 3], 27 | [ 4, 5, 6, 7], 28 | [ 8, 9, 10, 11]]) 29 | >>> 30 | >>> torch.clamp(a, 3, 5) 31 | tensor([[3, 3, 3, 3], 32 | [4, 5, 5, 5], 33 | [5, 5, 5, 5]]) 34 | ``` 35 | 36 | ## 相关阅读 37 | 38 | * [[numpy][clip]限制取值范围](../python/[numpy][clip]限制取值范围.md) -------------------------------------------------------------------------------- /docs/pytorch/grammar/conv-pool.md: -------------------------------------------------------------------------------- 1 | 2 | # [Conv][Pool]实现原理 3 | 4 | ## 实现 5 | 6 | `PyTorch`关于卷积层和池化层的实现参考: 7 | 8 | * [Conv2d](https://pytorch.org/docs/master/nn.html#conv2d) 9 | * [MaxPool2d](https://pytorch.org/docs/master/nn.html#maxpool2d) 10 | 11 | ## 原理 12 | 13 | 之前一直觉得卷积层和池化层的计算如下所示: 14 | 15 | $$ 16 | n_{out} = (n_{in}−F+2P)/S+1 (卷积层)\\ 17 | n_{out} = (n_{in}−F)/S+1 (池化层) 18 | $$ 19 | 20 | * $n_{out}$表示输出维度的特征数 21 | * $n_{in}$表示输入维度的特征数 22 | * $F$表示卷积核大小 23 | * $P$表示零填充大小 24 | * $S$表示步长 25 | 26 | 最近发现`PyTorch`并没有严格按照上述公式实现,其实现参考[A guide to convolution arithmetic for deeplearnin](https://arxiv.org/pdf/1603.07285.pdf)中$2.4$节以及第$3$节所示 27 | 28 | $$ 29 | n_{out} = \left \lfloor \frac {n_{in} + 2p - k}{s} \right \rfloor + 1 (卷积层) 30 | $$ 31 | 32 | $$ 33 | n_{out} = \left \lfloor \frac {n_{in} - k}{s} \right \rfloor + 1 (池化层) 34 | $$ 35 | 36 | 使用了一个向下取整(`floor`)计算,所以在`PyTorch`实现中,不同输入大小(比如`224`和`227`)能够得到相同大小的输出 -------------------------------------------------------------------------------- /docs/pytorch/grammar/imgs/alexnet-500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/grammar/imgs/alexnet-500.png -------------------------------------------------------------------------------- /docs/pytorch/grammar/imgs/alexnet-loss-500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/grammar/imgs/alexnet-loss-500.png -------------------------------------------------------------------------------- /docs/pytorch/grammar/imgs/mnist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/grammar/imgs/mnist.png -------------------------------------------------------------------------------- /docs/pytorch/grammar/imgs/spp-pretrained-acc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/grammar/imgs/spp-pretrained-acc.png -------------------------------------------------------------------------------- /docs/pytorch/grammar/imgs/spp-pretrained-loss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/grammar/imgs/spp-pretrained-loss.png -------------------------------------------------------------------------------- /docs/pytorch/grammar/index_fill.md: -------------------------------------------------------------------------------- 1 | 2 | # [index_fill]在给定维度填充指定val 3 | 4 | `PyTorch`提供了函数[index_fill_](https://pytorch.org/docs/stable/tensors.html?highlight=index_fill_#torch.Tensor.index_fill_)用于在张量的指定维度上填充指定`val` 5 | 6 | ## 定义 7 | 8 | >index_fill_(dim, index, val) → Tensor 9 | 10 | * `dim`:给定维度。`0`表示行,`1`表示列 11 | * `index`:`LongTensor`。给定维度下的指定下标 12 | * `val`:待填充值 13 | 14 | ## 示例 15 | 16 | 对于大小为$3\times 4$的张量 17 | 18 | ``` 19 | >>> import torch 20 | >>> a = torch.arange(12, dtype=torch.float).reshape(3, 4) 21 | >>> a 22 | tensor([[ 0., 1., 2., 3.], 23 | [ 4., 5., 6., 7.], 24 | [ 8., 9., 10., 11.]]) 25 | ``` 26 | 27 | 填充第`1/3`行,大小为`33` 28 | 29 | ``` 30 | >>> index=torch.LongTensor([0, 2]) 31 | >>> index 32 | tensor([0, 2]) 33 | >>> a.index_fill(0, index, 33) 34 | tensor([[33., 33., 33., 33.], 35 | [ 4., 5., 6., 7.], 36 | [33., 33., 33., 33.]]) 37 | ``` 38 | 39 | 填充第`2/3`列,大小为`-1` 40 | 41 | ``` 42 | >>> index=torch.LongTensor([1,2]) 43 | >>> index 44 | tensor([1, 2]) 45 | >>> a.index_fill(1, index, -1) 46 | tensor([[ 0., -1., -1., 3.], 47 | [ 4., -1., -1., 7.], 48 | [ 8., -1., -1., 11.]]) 49 | ``` -------------------------------------------------------------------------------- /docs/pytorch/grammar/nonzero.md: -------------------------------------------------------------------------------- 1 | 2 | # [nonzero]非零元素下标 3 | 4 | [torch.nonzero](https://pytorch.org/docs/stable/torch.html?highlight=nonzero#torch.nonzero)能够返回张量中所有非零元素下标 5 | 6 | ## 定义 7 | 8 | ``` 9 | torch.nonzero(input, *, out=None, as_tuple=False) → LongTensor or tuple of LongTensors 10 | ``` 11 | 12 | 返回一个`2`维张量,每一行表示一个元素的下标 13 | 14 | ## 测试 15 | 16 | ``` 17 | >>> import torch 18 | >>> a = torch.tensor([1, 1, 1, 0, 1]) 19 | >>> torch.nonzero(a) 20 | tensor([[0], 21 | [1], 22 | [2], 23 | [4]]) 24 | >>> torch.nonzero(a).shape 25 | torch.Size([4, 1]) 26 | ``` -------------------------------------------------------------------------------- /docs/pytorch/grammar/precision.md: -------------------------------------------------------------------------------- 1 | 2 | # 调整张量打印位数 3 | 4 | ## 引言 5 | 6 | 打印`Python Pytorch`结果,其输出总是保持`4`位有效小数 7 | 8 | ``` 9 | >>> import torch 10 | >>> a = torch.randn(3) 11 | >>> a 12 | tensor([0.7620, 0.4472, 0.5827]) 13 | >>> import numpy as np 14 | >>> b = np.random.randn(3) 15 | >>> b 16 | array([-0.35009024, -0.02696787, -0.89501692]) 17 | >>> c = torch.from_numpy(b) 18 | >>> c 19 | tensor([-0.3501, -0.0270, -0.8950], dtype=torch.float64) 20 | ``` 21 | 22 | ## 设置 23 | 24 | `Pytorch`默认输出`4`位有效小数,也可以设置输出更多位数。 25 | 26 | ``` 27 | >>> torch.set_printoptions(precision=8) 28 | >>> 29 | >>> c 30 | tensor([-0.35009024, -0.02696787, -0.89501692], dtype=torch.float64) 31 | ``` 32 | 33 | *默认情况下张量数据类型为浮点型(`torch.float32`),也就是`32`位有效数字(后续数字就不准确率)* 34 | 35 | ## 相关阅读 36 | 37 | * [为什么Pytorch中的Tensor只有四位小数呢?](https://www.zhihu.com/question/305576603) 38 | * [Pytorch中tensor的打印精度](https://blog.csdn.net/wangpeng246300/article/details/111355945) -------------------------------------------------------------------------------- /docs/pytorch/grammar/transpose-permute.md: -------------------------------------------------------------------------------- 1 | 2 | # [transpose][permute]维度转换 3 | 4 | `PyTorch`提供了两个函数用于维度转换 5 | 6 | * [transpose](https://pytorch.org/docs/stable/torch.html#torch.transpose) 7 | * [permute](https://pytorch.org/docs/stable/tensors.html?highlight=permute#torch.Tensor.permute) 8 | 9 | ## transpose 10 | 11 | >torch.transpose(input, dim0, dim1) → Tensor 12 | 13 | 函数`transpose`每次仅能调整两个维度 14 | 15 | ``` 16 | >>> import torch 17 | >>> a = torch.arange(24).reshape(2, 3, 4) 18 | >>> a.shape 19 | torch.Size([2, 3, 4]) 20 | # 切换第1维和第2维 21 | >>> torch.transpose(a, 1, 2).shape 22 | torch.Size([2, 4, 3]) 23 | # 切换第0维和第2维 24 | >>> torch.transpose(a, 2, 0).shape 25 | torch.Size([4, 3, 2]) 26 | ``` 27 | 28 | ## permute 29 | 30 | >permute(*dims) → Tensor 31 | 32 | 使用`permute`能够一次性调整多个维度 33 | 34 | ``` 35 | >>> import torch 36 | >>> a = torch.arange(24).reshape(2, 3, 4) 37 | >>> a.shape 38 | torch.Size([2, 3, 4]) 39 | >>> a.permute(2, 0, 1).shape 40 | torch.Size([4, 2, 3]) 41 | ``` -------------------------------------------------------------------------------- /docs/pytorch/index.md: -------------------------------------------------------------------------------- 1 | 2 | # 引言 3 | 4 | 之前操作过`torch`,是一个`lua`编写的深度学习训练框架,后来`facebook`发布了`pytorch`,使用`python`语言进行开发 5 | 6 | [pytorch](https://pytorch.org/)是在`torch`的基础上发展而来的,它继承了许多内容,包括各种包的命名和类的定义,比如张量(`tensor`) 7 | 8 | 9 | ## 目标 10 | 11 | * 替代`Numpy`进行`GPU`运算 12 | * 提供最大灵活性和速度的深度学习平台 13 | 14 | ## 安装 15 | 16 | 参考:[Start Locally](https://pytorch.org/get-started/locally/) 17 | 18 | 指定版本/操作系统/安装方式/`python`语言/`cuda`版本 19 | 20 | 当前配置: 21 | 22 | * `PyTorch Stable(1.0)` 23 | * `Ubuntu 16.04` 24 | * `Anacodna3 ` 25 | * `Python 3.6` 26 | * `CUDA 10.0` 27 | 28 | 安装命令如下: 29 | 30 | $ conda install pytorch torchvision cudatoolkit=9.0 -c pytorch 31 | 32 | ## 加载`torch` 33 | 34 | 命令行方式 35 | 36 | $ python 37 | Python 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34) 38 | [GCC 7.3.0] on linux 39 | Type "help", "copyright", "credits" or "license" for more information. 40 | >>> import torch 41 | >>> torch.__version__ 42 | '1.0.1.post2' 43 | >>> 44 | 45 | 文件方式 46 | 47 | from __future__ import print_function 48 | import torch -------------------------------------------------------------------------------- /docs/pytorch/tool/visualize.md: -------------------------------------------------------------------------------- 1 | 2 | # 可视化 3 | 4 | ## 相关阅读 5 | 6 | * [[PyTorch]Tensorboard可视化实现](https://blog.zhujian.life/posts/eb6f2b71.html) 7 | * [[PyTorch]Tensorboard使用实践](https://blog.zhujian.life/posts/f793688d.html) 8 | * [模型可视化工具和库](https://blog.zhujian.life/posts/d813343e.html) -------------------------------------------------------------------------------- /docs/pytorch/train/imgs/spp-pretrained-acc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/train/imgs/spp-pretrained-acc.png -------------------------------------------------------------------------------- /docs/pytorch/train/imgs/spp-pretrained-loss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/pytorch/train/imgs/spp-pretrained-loss.png -------------------------------------------------------------------------------- /docs/pytorch/train/为什么推荐使用static_dict方式保存模型.md: -------------------------------------------------------------------------------- 1 | 2 | # 为什么推荐使用static_dict方式保存模型 3 | 4 | 在官网教程[[译]保存和加载模型](./[译]保存和加载模型.md)中给出了多种模型使用方式,其中最常用的有 5 | 6 | 1. 保存/加载`static_dict` 7 | 2. 保存/加载完整模型 8 | 9 | 对于第一种方式,只保存训练好的模型的学习参数,但是加载时需要额外提供定义的模型结构;对于第二种方式,直接使用`PyTorch`的保存和加载函数即可,不过教程中也提到了第二种方式的缺陷,就是需要在调用时维护模型类文件的路径,否则会出错 10 | 11 | 之前一直使用第一种方式进行模型的读写,直到遇到了下面这个问题,才真正理解了第二种方式的缺陷 12 | 13 | ## ModuleNotFoundError: No module named 'models' 14 | 15 | 使用[ultralytics/yolov5](https://github.com/ultralytics/yolov5)的时候出现了如上错误。在网上查找了资料后发现这就是保存/加载完整模型带来的问题。参考 16 | 17 | * [torch.load() requires model module in the same folder #3678](https://github.com/pytorch/pytorch/issues/3678) 18 | * [ModuleNotFoundError: No module named 'models' #18325](https://github.com/pytorch/pytorch/issues/18325) 19 | * [Pytorch.load() error:No module named ‘model’](https://discuss.pytorch.org/t/pytorch-load-error-no-module-named-model/25821) 20 | 21 | ## 解析 22 | 23 | `PyTorch`集成了`Pickle`工具进行模型的保存和加载。如果直接保存完整模型,那么附带的需要在调用时维持和模型定义文件的相对位置,否则会出现错误 24 | 25 | ## 解决 26 | 27 | 解决方式就是维护调用文件和模型定义文件之间的相对位置,保证`Pickle`能够找到模型定义文件 28 | 29 | 1. 使用`sys.path`设置 30 | 31 | ``` 32 | import sys 33 | sys.path.insert(0, './yolov5') 34 | ``` 35 | 36 | 2. 设置`PYTHONPATH`环境变量 37 | 38 | ## 相关 39 | 40 | 在[ultralytics/yolov5](https://github.com/ultralytics/yolov5)提了一个问题 41 | 42 | * [ModuleNotFoundError: No module named 'models' #353](https://github.com/ultralytics/yolov5/issues/353) -------------------------------------------------------------------------------- /docs/pytorch/train/查询模型参数总数.md: -------------------------------------------------------------------------------- 1 | 2 | # 查询模型参数总数 3 | 4 | ## numel 5 | 6 | 函数`numel`作用是返回输入张量的元素总数 7 | 8 | ``` 9 | >>> import torch 10 | >>> 11 | >>> a = torch.randn((2,3,4)) 12 | >>> a.shape 13 | torch.Size([2, 3, 4]) 14 | >>> torch.numel(a) 15 | 24 16 | >>> a.numel() 17 | 24 18 | ``` 19 | 20 | ## 查询模型参数总数 21 | 22 | ``` 23 | net = Model() 24 | print('# Model parameters:', sum(param.numel() for param in net.parameters())) 25 | ``` 26 | 27 | ## 相关阅读 28 | 29 | * [torch.numel(input) → int](https://pytorch.org/docs/stable/torch.html?highlight=numel#torch.numel) 30 | * [5.查看网络总参数](https://www.jianshu.com/p/fcafcfb3d887) -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs>=1.1.2 2 | mkdocs-material>=7.0.5 3 | mkdocs-material-extensions>=1.0.1 -------------------------------------------------------------------------------- /docs/stb/index.md: -------------------------------------------------------------------------------- 1 | 2 | # 引言 3 | 4 | 最近发现一个非常实用的单文件库:[ nothings/stb](https://github.com/nothings/stb),仅需加入单个头文件即可完成图像加载(*获取字节流以及对应的宽/高/通道数等信息*)、图像保存等操作。 5 | 6 | 图像处理相关的操作包括: 7 | 8 | * `image loader`: [stb_image.h](https://github.com/nothings/stb/blob/master/stb_image.h) 9 | * `image writer`: [stb_image_write.h](https://github.com/nothings/stb/blob/master/stb_image_write.h) 10 | * `image resizer`: [stb_image_resize.h](https://github.com/nothings/stb/blob/master/stb_image_resize.h) 11 | 12 | ## 操作 13 | 14 | 下载`stb`仓库,将对应头文件加入自己工程,使用如下语法引入该头文件: 15 | 16 | ``` 17 | #define STB_IMAGE_IMPLEMENTATION 18 | #include "stb_image.h" 19 | ``` 20 | 21 | ## 示例 22 | 23 | 查看目录:`stb/` -------------------------------------------------------------------------------- /docs/torchvision/concatdataset.md: -------------------------------------------------------------------------------- 1 | 2 | # [torchvision][ConcatDataset]连接多个数据集 3 | 4 | `PyTorch`提供了类[torch.utils.data.ConcatDataset](https://pytorch.org/docs/stable/data.html#torch.utils.data.ConcatDataset),能够连接多个不同的数据集 5 | 6 | ## 定义 7 | 8 | >CLASS torch.utils.data.ConcatDataset(datasets) 9 | 10 | * `datasets`:是一个列表,保存了多个数据集对象 11 | 12 | ## 示例 13 | 14 | 连接`MNIST`和`CIFAR100` 15 | 16 | ``` 17 | from torchvision.datasets import MNIST 18 | from torchvision.datasets import CIFAR100 19 | from torch.utils.data import ConcatDataset 20 | 21 | import numpy as np 22 | 23 | if __name__ == "__main__": 24 | mnist_data = MNIST('./data', train=True, download=True) 25 | print('mnist: ', len(mnist_data)) 26 | cifar10_data = CIFAR100('./data', train=True, download=True) 27 | print('cifar: ', len(cifar10_data)) 28 | 29 | concat_data = ConcatDataset([mnist_data, cifar10_data]) 30 | print('concat_data: ', len(concat_data)) 31 | 32 | img, target = concat_data.__getitem__(133) 33 | print(np.array(img).shape) 34 | print(target) 35 | ``` 36 | 37 | 输出如下: 38 | 39 | ``` 40 | mnist: 60000 41 | Files already downloaded and verified 42 | cifar: 50000 43 | concat_data: 110000 44 | (28, 28) 45 | 9 46 | ``` -------------------------------------------------------------------------------- /docs/torchvision/imgs/cifar-sample-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/cifar-sample-4.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/fivecrop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/fivecrop.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/preprocess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/preprocess.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/sphx_glr_data_loading_tutorial_001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/sphx_glr_data_loading_tutorial_001.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/sphx_glr_data_loading_tutorial_004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/sphx_glr_data_loading_tutorial_004.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/voc-aeroplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/voc-aeroplane.png -------------------------------------------------------------------------------- /docs/torchvision/imgs/voc-dataloader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/docs/torchvision/imgs/voc-dataloader.png -------------------------------------------------------------------------------- /docs/torchvision/ten-crops.md: -------------------------------------------------------------------------------- 1 | 2 | # [Ten Crops]多样本检测 3 | 4 | 在检测阶段,采集一张样本中的多个裁剪,平均其预测结果,有助于更高的检测精度 5 | 6 | 完整实现参考`py/data_preprocessing/ten-crops.py` 7 | 8 | ## FiveCrops/TenCrops 9 | 10 | 常用的有`FiveCrops`和`TenCrops` 11 | 12 | * `FiveCrops`:裁剪图像中心和`4`个角 13 | * `TenCrops`:裁剪图像中心和`4`个角,以及翻转图像后的`5`个裁剪 14 | 15 | ## PyTorch实现 16 | 17 | `PyTorch`提供了函数`torchvision.transforms.FiveCrop`和`torchvision.transforms.TenCrop`。裁剪`5`张图像并显示 18 | 19 | ``` 20 | def plot(src, dsts): 21 | f = plt.figure() 22 | 23 | cols = 3 24 | rows = 2 25 | 26 | plt.subplot(rows, cols, 1) 27 | plt.title('src') 28 | plt.imshow(src) 29 | 30 | for i in range(rows): 31 | for j in range(cols): 32 | if (i * cols + j) == 5: 33 | break 34 | 35 | plt.subplot(rows, cols, i * cols + j + 2) 36 | plt.imshow(dsts[i * cols + j]) 37 | 38 | plt.show() 39 | 40 | 41 | def draw_five_crop(): 42 | src = Image.open('./data/butterfly.jpg') 43 | 44 | transform = transforms.Compose([ 45 | transforms.Resize(256), 46 | transforms.FiveCrop(224), # this is a list of PIL Images 47 | ]) 48 | 49 | dsts = transform(src) 50 | print(len(dsts)) 51 | plot(src, dsts) 52 | ``` 53 | 54 | ![](./imgs/fivecrop.png) 55 | 56 | ## 相关阅读 57 | 58 | * [PyTorch数据增强,TenCrop的用法](https://www.jianshu.com/p/aba1142c0453) 59 | 60 | * [How to properly do 10-crop testing on Imagenet?](https://discuss.pytorch.org/t/how-to-properly-do-10-crop-testing-on-imagenet/11341) 61 | 62 | * [[Pytorch]Pytorch中图像的基本操作(TenCrop)](https://blog.csdn.net/weixin_44538273/article/details/88406404) -------------------------------------------------------------------------------- /docs/torchvision/数据预处理.md: -------------------------------------------------------------------------------- 1 | 2 | # 数据预处理 3 | 4 | `PyTorch`提供了丰富的预处理函数,组合不同的预处理函数能够极大的扩充图像数据库 5 | 6 | 实现代码位于`py/data`目录下 7 | 8 | ## 预处理功能 9 | 10 | 1. 缩放(`Resize`) 11 | 2. 裁剪(`CenterCrop/RandomCrop`) 12 | 3. 翻转(`RandomHorizontalFlip/RandomVerticalFlip`) 13 | 4. 颜色抖动(`ColorJitter`) 14 | 5. 随机擦除(`RandomErasing`) 15 | 16 | ## 组合 17 | 18 | `Torchvision`提供了`Compose`函数来组合多种预处理功能 19 | 20 | ``` 21 | # 预处理顺序如下: 22 | # 1. 按较短边缩放 23 | # 2. 随机裁剪224x224 24 | # 3. 随机水平翻转 25 | # 4. 随机颜色抖动:亮度、对比度、饱和度、色调 26 | # 5. 转换成Tensor张量 27 | # 6. 随机擦除 28 | # 7. 转换成PIL Image 29 | transform = transforms.Compose([ 30 | transforms.Resize(224), 31 | transforms.RandomCrop(224), 32 | transforms.RandomHorizontalFlip(), 33 | transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.1), 34 | transforms.ToTensor(), 35 | transforms.RandomErasing(), 36 | transforms.ToPILImage() 37 | ]) 38 | ``` 39 | 40 | ![](./imgs/preprocess.png) 41 | 42 | ## 后续 43 | 44 | 更多预处理功能参考:[ ZJCV/ZTransforms](https://github.com/ZJCV/ZTransforms) 45 | 46 | ## 相关阅读 47 | 48 | * [深度学习入门之Pytorch——数据增强](https://blog.csdn.net/ 49 | weixin_40793406/article/details/84867143) 50 | 51 | * [深度神经网络模型训练中的最新tricks总结【原理与代码汇总】](https://zhuanlan.zhihu.com/p/66080948) 52 | -------------------------------------------------------------------------------- /imgs/VisionGuide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/imgs/VisionGuide.png -------------------------------------------------------------------------------- /libjpeg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | project(libjpeg) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | set(CMAKE_PREFIX_PATH /home/zj/opencv/opencv-4.2.0/install) 7 | find_package(OpenCV REQUIRED) 8 | # 打印OpenCV版本 9 | MESSAGE("OpenCV version: ${OpenCV_VERSION}") 10 | # 添加include地址 11 | include_directories(${OpenCV_INCLUDE_DIRS}) 12 | 13 | 14 | include_directories(/home/zj/repos/libjpeg-turbo/install/include) 15 | link_directories(/home/zj/repos/libjpeg-turbo/install/lib) 16 | 17 | add_executable(libjpeg main.cpp) 18 | target_link_libraries(libjpeg libturbojpeg.so ${OpenCV_LIBS}) 19 | #target_link_libraries(CImgDemo -lpthread -lX11) 20 | 21 | 22 | -------------------------------------------------------------------------------- /patches/simhei.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/patches/simhei.ttf -------------------------------------------------------------------------------- /py/.gitignore: -------------------------------------------------------------------------------- 1 | lr/__pycache__/ 2 | 3 | data/ 4 | 5 | .idea/ 6 | -------------------------------------------------------------------------------- /py/data_preprocessing/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 下午1:51 5 | @file: __init__.py.py 6 | @author: zj 7 | @description: 8 | """ -------------------------------------------------------------------------------- /py/data_preprocessing/color.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 下午2:41 5 | @file: color.py 6 | @author: zj 7 | @description: 随机改变图像的亮度、对比度和饱和度 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 15 | plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 16 | 17 | 18 | def plot(src, dst, dst2, dst3, dst4): 19 | f = plt.figure() 20 | 21 | plt.subplot(231) 22 | plt.title('原图') 23 | plt.imshow(src), plt.axis('off') 24 | 25 | plt.subplot(232) 26 | plt.title('随机亮度') 27 | plt.imshow(dst), plt.axis('off') 28 | 29 | plt.subplot(233) 30 | plt.title('随机对比度') 31 | plt.imshow(dst2), plt.axis('off') 32 | 33 | plt.subplot(234) 34 | plt.title('随机饱和度') 35 | plt.imshow(dst3), plt.axis('off') 36 | 37 | plt.subplot(235) 38 | plt.title('随机色调') 39 | plt.imshow(dst4), plt.axis('off') 40 | 41 | plt.show() 42 | 43 | 44 | if __name__ == '__main__': 45 | src = Image.open('../data/butterfly.jpg') 46 | 47 | # 随机改变亮度 48 | transform = transforms.Compose([ 49 | transforms.ColorJitter(brightness=1) 50 | ]) 51 | dst = transform(src) 52 | 53 | # 随机改变对比度 54 | transform2 = transforms.Compose([ 55 | transforms.ColorJitter(contrast=1) 56 | ]) 57 | dst2 = transform2(src) 58 | 59 | # 随机改变饱和度 60 | transform3 = transforms.Compose([ 61 | transforms.ColorJitter(saturation=1) 62 | ]) 63 | dst3 = transform3(src) 64 | 65 | # 随机改变色调 66 | transform4 = transforms.Compose([ 67 | transforms.ColorJitter(hue=0.5) 68 | ]) 69 | dst4 = transform4(src) 70 | 71 | plot(src, dst, dst2, dst3, dst4) 72 | -------------------------------------------------------------------------------- /py/data_preprocessing/compose.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 下午2:52 5 | @file: compose.py 6 | @author: zj 7 | @description: 组合实现多种图像预处理 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | if __name__ == '__main__': 15 | src = Image.open('../data/lena.jpg') 16 | 17 | # 预处理顺序如下: 18 | # 1. 按较短边缩放 19 | # 2. 随机裁剪224x224 20 | # 3. 随机水平翻转 21 | # 4. 随机颜色抖动:亮度、对比度、饱和度、色调 22 | transform = transforms.Compose([ 23 | transforms.Resize(224), 24 | transforms.RandomCrop(224), 25 | transforms.RandomHorizontalFlip(), 26 | transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.1), 27 | transforms.ToTensor(), 28 | transforms.RandomErasing(), 29 | transforms.ToPILImage() 30 | ]) 31 | 32 | cols = 3 33 | rows = 3 34 | for i in range(rows): 35 | for j in range(cols): 36 | plt.subplot(rows, cols, i * cols + j + 1) 37 | plt.imshow(transform(src)) 38 | plt.axis('off') 39 | plt.show() 40 | -------------------------------------------------------------------------------- /py/data_preprocessing/crop.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 下午2:15 5 | @file: crop.py 6 | @author: zj 7 | @description: 中心裁剪、随机裁剪 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 15 | plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 16 | 17 | 18 | def plot(src, dst, dst2): 19 | f = plt.figure() 20 | 21 | plt.subplot(311) 22 | h, w = src.size 23 | plt.title('原图 (w,h)=(%d, %d)' % (h, w)) 24 | plt.imshow(src), # plt.axis('off') 25 | 26 | plt.subplot(312) 27 | h, w = dst.size 28 | plt.title('中心裁剪 (w,h)=(%d, %d)' % (h, w)) 29 | plt.imshow(dst), # plt.axis('off') 30 | 31 | plt.subplot(313) 32 | h, w = dst2.size 33 | plt.title('随机裁剪 (w,h)=(%d, %d)' % (h, w)) 34 | plt.imshow(dst2), # plt.axis('off') 35 | 36 | plt.show() 37 | 38 | 39 | if __name__ == '__main__': 40 | src = Image.open('../data/butterfly.jpg') 41 | 42 | # 先缩放,再中心裁剪 43 | transform = transforms.Compose([ 44 | transforms.Resize(224), 45 | transforms.CenterCrop(224) 46 | ]) 47 | dst = transform(src) 48 | 49 | # 先缩放,再随机裁剪 50 | transform2 = transforms.Compose([ 51 | transforms.Resize(224), 52 | transforms.RandomCrop(224) 53 | ]) 54 | dst2 = transform2(src) 55 | 56 | plot(src, dst, dst2) 57 | -------------------------------------------------------------------------------- /py/data_preprocessing/erase.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/5/1 上午10:09 5 | @file: erase.py 6 | @author: zj 7 | @description: 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 15 | plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 16 | 17 | 18 | def plot(src, dst, dst2): 19 | f = plt.figure() 20 | 21 | plt.subplot(311) 22 | h, w = src.size 23 | plt.title('原图 (w,h)=(%d, %d)' % (h, w)) 24 | plt.imshow(src), # plt.axis('off') 25 | 26 | plt.subplot(312) 27 | h, w = dst.size 28 | plt.title('随机擦除1 (w,h)=(%d, %d)' % (h, w)) 29 | plt.imshow(dst), # plt.axis('off') 30 | 31 | plt.subplot(313) 32 | h, w = dst2.size 33 | plt.title('随机擦除2 (w,h)=(%d, %d)' % (h, w)) 34 | plt.imshow(dst2), # plt.axis('off') 35 | 36 | plt.show() 37 | 38 | 39 | if __name__ == '__main__': 40 | src = Image.open('../data/butterfly.jpg') 41 | 42 | # 随机擦除1 43 | transform = transforms.Compose([ 44 | transforms.ToTensor(), 45 | transforms.RandomErasing(), 46 | transforms.ToPILImage() 47 | ]) 48 | dst = transform(src) 49 | 50 | # 随机擦除2 51 | transform2 = transforms.Compose([ 52 | transforms.ToTensor(), 53 | transforms.RandomErasing(), 54 | transforms.ToPILImage() 55 | ]) 56 | dst2 = transform2(src) 57 | 58 | plot(src, dst, dst2) 59 | -------------------------------------------------------------------------------- /py/data_preprocessing/flip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 下午2:18 5 | @file: flip.py 6 | @author: zj 7 | @description: 水平/垂直翻转 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 15 | plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 16 | 17 | 18 | def plot(src, dst, dst2): 19 | f = plt.figure() 20 | 21 | plt.subplot(311) 22 | h, w = src.size 23 | plt.title('原图 (w,h)=(%d, %d)' % (h, w)) 24 | plt.imshow(src), # plt.axis('off') 25 | 26 | plt.subplot(312) 27 | h, w = dst.size 28 | plt.title('水平翻转 (w,h)=(%d, %d)' % (h, w)) 29 | plt.imshow(dst), # plt.axis('off') 30 | 31 | plt.subplot(313) 32 | h, w = dst2.size 33 | plt.title('垂直翻转 (w,h)=(%d, %d)' % (h, w)) 34 | plt.imshow(dst2), # plt.axis('off') 35 | 36 | plt.show() 37 | 38 | 39 | if __name__ == '__main__': 40 | src = Image.open('../data/butterfly.jpg') 41 | 42 | # 随机水平翻转 43 | transform = transforms.Compose([ 44 | # transforms.ToPILImage(), 45 | transforms.RandomHorizontalFlip() 46 | ]) 47 | dst = transform(src) 48 | 49 | # 随机竖直翻转 50 | transform2 = transforms.Compose([ 51 | # transforms.ToPILImage(), 52 | transforms.RandomVerticalFlip() 53 | ]) 54 | dst2 = transform2(src) 55 | 56 | plot(src, dst, dst2) 57 | -------------------------------------------------------------------------------- /py/data_preprocessing/resize.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/4/30 上午11:22 5 | @file: resize.py 6 | @author: zj 7 | @description: 缩放 8 | """ 9 | 10 | import torchvision.transforms as transforms 11 | from PIL import Image 12 | import matplotlib.pyplot as plt 13 | 14 | plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 15 | plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 16 | 17 | 18 | def plot(src, dst, dst2): 19 | f = plt.figure() 20 | 21 | plt.subplot(311) 22 | h, w = src.size 23 | plt.title('原图 (w,h)=(%d, %d)' % (h, w)) 24 | plt.imshow(src), # plt.axis('off') 25 | 26 | plt.subplot(312) 27 | h, w = dst.size 28 | plt.title('按较短边进行缩放 (w,h)=(%d, %d)' % (h, w)) 29 | plt.imshow(dst), # plt.axis('off') 30 | 31 | plt.subplot(313) 32 | h, w = dst2.size 33 | plt.title('指定长/宽 (w,h)=(%d, %d)' % (h, w)) 34 | plt.imshow(dst2), # plt.axis('off') 35 | 36 | plt.show() 37 | 38 | 39 | if __name__ == '__main__': 40 | src = Image.open('../data/butterfly.jpg') 41 | 42 | # 按较短边进行缩放 43 | transform = transforms.Compose([ 44 | transforms.Resize(224) 45 | ]) 46 | dst = transform(src) 47 | 48 | # 指定图像长宽 49 | transform2 = transforms.Compose([ 50 | transforms.Resize((224, 224)) 51 | ]) 52 | dst2 = transform2(src) 53 | 54 | plot(src, dst, dst2) 55 | -------------------------------------------------------------------------------- /py/lr/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | @date: 2020/5/2 下午2:36 5 | @file: __init__.py.py 6 | @author: zj 7 | @description: 8 | """ -------------------------------------------------------------------------------- /samples/GTestDemo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | project(GTestDemo) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | include_directories(/home/zj/repos/googletest/googletest/include) 7 | link_directories(/home/zj/repos/googletest/build/lib) 8 | set(gtest_lib libgmock.a libgmock_main.a libgtest.a libgtest_main.a) 9 | 10 | add_executable(GTestDemo gtest_main.cpp gtest_two.cpp) 11 | target_link_libraries(GTestDemo ${gtest_lib} pthread) 12 | -------------------------------------------------------------------------------- /samples/GTestDemo/gtest_main.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | #include "gtest/gtest.h" 6 | 7 | int sum(int a, int b) { return a + b; } 8 | 9 | TEST(TestDemo, First) { 10 | int res = sum(3, 5); 11 | 12 | EXPECT_EQ(res, 8); 13 | } 14 | 15 | int main(int argc, char *argv[]) { 16 | ::testing::InitGoogleTest(&argc, argv); 17 | int res = RUN_ALL_TESTS(); 18 | 19 | std::cout << "Hello, World!" << std::endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /samples/GTestDemo/gtest_two.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by zj on 2022/10/19. 3 | // 4 | #include "gtest/gtest.h" 5 | 6 | int Factorial(int num) { 7 | int res = 1; 8 | for (int i = 1; i <= num; i++) { 9 | res *= i; 10 | } 11 | 12 | return res; 13 | } 14 | 15 | // Tests factorial of 0. 16 | TEST(FactorialTest, HandlesZeroInput) { EXPECT_EQ(Factorial(0), 1); } 17 | 18 | // Tests factorial of positive numbers. 19 | TEST(FactorialTest, HandlesPositiveInput) { 20 | EXPECT_EQ(Factorial(1), 1); 21 | EXPECT_EQ(Factorial(2), 2); 22 | EXPECT_EQ(Factorial(3), 6); 23 | EXPECT_EQ(Factorial(8), 40320); 24 | } 25 | -------------------------------------------------------------------------------- /samples/OpenCVDemo/3rdparty/opencv: -------------------------------------------------------------------------------- 1 | /home/zj/opencv/opencv-4.9.0/install_Release -------------------------------------------------------------------------------- /samples/OpenCVDemo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24) 2 | project(OpenCVDemo) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # set opencv 7 | get_filename_component(ABSOLUTE_OpenCV_DIR ./3rdparty/opencv ABSOLUTE) 8 | IF (CMAKE_SYSTEM_NAME MATCHES "Linux") 9 | set(OpenCV_DIR ${ABSOLUTE_OpenCV_DIR}/lib/cmake/opencv4) 10 | ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Windows") 11 | set(OpenCV_DIR ${ABSOLUTE_OpenCV_DIR}) 12 | ENDIF () 13 | find_package(OpenCV REQUIRED) 14 | 15 | MESSAGE("OpenCV version: ${OpenCV_VERSION}") 16 | MESSAGE("OpenCV OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") 17 | MESSAGE("OpenCV OpenCV_LIBS: ${OpenCV_LIBS}") 18 | 19 | 20 | add_executable(OpenCVDemo main.cpp) 21 | target_link_libraries(OpenCVDemo ${OpenCV_LIBS}) 22 | -------------------------------------------------------------------------------- /samples/OpenCVDemo/cropped_lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/samples/OpenCVDemo/cropped_lena.jpg -------------------------------------------------------------------------------- /samples/OpenCVDemo/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/samples/OpenCVDemo/lena.jpg -------------------------------------------------------------------------------- /samples/OpenCVDemo/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "opencv2/opencv.hpp" 4 | 5 | int main() { 6 | // 读取图片 7 | cv::Mat image = cv::imread("../lena.jpg"); 8 | if (image.empty()) { 9 | std::cout << "无法读取图片,请确保文件路径正确" << std::endl; 10 | return -1; 11 | } 12 | 13 | // 获取图片的尺寸 14 | int width = image.cols; 15 | int height = image.rows; 16 | 17 | // 计算中心裁剪的区域 18 | int x = width / 4; // 裁剪区域的左上角 x 坐标 19 | int y = height / 4; // 裁剪区域的左上角 y 坐标 20 | int cropWidth = width / 2; // 裁剪区域的宽度 21 | int cropHeight = height / 2;// 裁剪区域的高度 22 | 23 | // 裁剪图片 24 | cv::Rect cropRegion(x, y, cropWidth, cropHeight); 25 | cv::Mat croppedImage = image(cropRegion); 26 | 27 | // 显示原始图片和裁剪后的图片 28 | cv::imshow("原始图片", image); 29 | cv::imshow("裁剪后的图片", croppedImage); 30 | cv::waitKey(0); 31 | 32 | // 保存裁剪后的图片 33 | cv::imwrite("../cropped_lena.jpg", croppedImage); 34 | 35 | std::cout << "Hello, World!" << std::endl; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /samples/plantuml/class.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam classAttributeIconSize 0 3 | 4 | ' class Dummy { 5 | ' String data 6 | ' void methods() 7 | ' } 8 | 9 | ' class Flight { 10 | ' +flightNumber: Integer 11 | ' -departureTime: Data 12 | 13 | ' # hahah(): void 14 | ' } 15 | 16 | ' ' 泛化 空心三角形+实线 17 | ' Class01 <|-- Class02 18 | ' ' 实现 空心三角形+虚线 19 | ' Class03 <|.. Class04 20 | ' ' 组合 实心菱形+实线 21 | ' Class05 *-- Class06 22 | ' ' 聚合 空心菱形+实线 23 | ' Class07 o-- Class08 24 | ' ' 关联 箭头+实线 25 | ' Class09 <-- Class10 26 | ' ' 依赖 箭头+虚线 27 | ' Class11 <.. Class12 28 | 29 | ' namespaceA.Class01 <|-- namespaceB.Class02 30 | 31 | ' class Dummy { 32 | ' {static} String id 33 | ' {abstract} void methods() 34 | ' {static} virtual void hi() override 35 | ' } 36 | 37 | ' Class01 "1" *-- "many" Class02 : contains 38 | 39 | ' Class03 o-- Class04 : aggregation 40 | 41 | ' Class05 --> "1" Class06 42 | 43 | ' class Dummy01 { 44 | ' String data 45 | ' void methods() 46 | ' } 47 | 48 | ' class Dummy02 { 49 | ' data: String 50 | ' methods(): void 51 | ' } 52 | 53 | ' class Dummy03 { 54 | ' String data 55 | ' void methods() override 56 | ' } 57 | 58 | class default { 59 | + int field01 60 | - float field02 61 | 62 | + void method01() 63 | - float method02() 64 | } 65 | 66 | class custom { 67 | + int field01 68 | ' 两格点号表示虚线 69 | .. 70 | - float field02 71 | ' 两格下划线表示实线 72 | __ 73 | ' 可以在线段中间添加文字 74 | .. 构造器 .. 75 | custom() 76 | __ override __ 77 | + void method01() 78 | - float method02() 79 | } 80 | 81 | @enduml -------------------------------------------------------------------------------- /samples/plantuml/common.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | scale 300*200 3 | title 第一行bababa\n第二行bababa 4 | 5 | class Hello { 6 | + hi: int 7 | } 8 | @enduml 9 | -------------------------------------------------------------------------------- /samples/plantuml/version.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | version 3 | @enduml -------------------------------------------------------------------------------- /stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | project(stb) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | add_executable(stb main.cpp) 7 | -------------------------------------------------------------------------------- /stb/assets/mnist_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZJDoc/VisionGuide/2bf535f664054a93bc830dde736c97d6cab8d5fb/stb/assets/mnist_0.png -------------------------------------------------------------------------------- /stb/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define STB_IMAGE_IMPLEMENTATION 4 | #include "stb_image.h" 5 | #define STB_IMAGE_WRITE_IMPLEMENTATION 6 | #include "stb_image_write.h" 7 | 8 | int main() { 9 | const char *file_name = "../assets/mnist_0.png"; 10 | 11 | // 分别获取宽 / 高 / 通道数 12 | int x, y, n; 13 | // 返回的data是一个字节数组,包含了解析的图像像素值 14 | unsigned char *data = stbi_load(file_name, &x, &y, &n, 0); 15 | std::cout << "width: " << x << " height: " << y << " channels: " << n << std::endl; 16 | 17 | // 写入文件,按保存格式选择 18 | // JPEG does ignore alpha channels in input data; quality is between 1 and 100. 19 | // Higher quality looks better but results in a bigger image. 20 | stbi_write_jpg("../assets/mnist_0_write_jpg.jpg", x, y, n, data, 100); 21 | // For PNG, "stride_in_bytes" is the distance in bytes from the first byte of 22 | // a row of pixels to the first byte of the next row of pixels. 23 | stbi_write_png("../assets/mnist_0_write_png.png", x, y, n, data, 0); 24 | 25 | // 释放字节数组 26 | stbi_image_free(data); 27 | 28 | std::cout << "Hello, World!" << std::endl; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /tools/createsamples/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/home/zhujian/opencv-3.4.4/install/**" 8 | ], 9 | "defines": [], 10 | "compilerPath": "/usr/bin/gcc", 11 | "cStandard": "c11", 12 | "cppStandard": "c++17", 13 | "intelliSenseMode": "clang-x64" 14 | } 15 | ], 16 | "version": 4 17 | } -------------------------------------------------------------------------------- /tools/createsamples/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "create", 8 | "type": "shell", 9 | "command": "g++ -o create -std=c++17 createsamples.cpp utility.cpp `pkg-config --libs --cflags opencv`", 10 | "args": [], 11 | "group": { 12 | "kind": "build", 13 | "isDefault": true 14 | } 15 | }, 16 | { 17 | "label": "create", 18 | "type": "shell", 19 | "command": "g++ -g -o create -std=c++17 createsamples.cpp utility.cpp `pkg-config --libs --cflags opencv`", 20 | "args": [], 21 | "group": { 22 | "kind": "test", 23 | "isDefault": true 24 | } 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /tools/createsamples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB SRCS *.cpp) 2 | ocv_add_application(opencv_createsamples 3 | MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio 4 | SRCS ${SRCS}) 5 | -------------------------------------------------------------------------------- /tools/traincascade/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/home/zhujian/opencv-3.4.4/install/include/**" 8 | ], 9 | "defines": [], 10 | "compilerPath": "/usr/bin/gcc", 11 | "cStandard": "c11", 12 | "cppStandard": "c++17", 13 | "intelliSenseMode": "clang-x64" 14 | } 15 | ], 16 | "version": 4 17 | } -------------------------------------------------------------------------------- /tools/traincascade/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "cctype": "cpp", 4 | "cmath": "cpp", 5 | "cstddef": "cpp", 6 | "cstdio": "cpp", 7 | "cstdlib": "cpp", 8 | "cstring": "cpp", 9 | "ctime": "cpp", 10 | "cwchar": "cpp", 11 | "atomic": "cpp", 12 | "strstream": "cpp", 13 | "chrono": "cpp", 14 | "cstdint": "cpp", 15 | "iosfwd": "cpp", 16 | "ratio": "cpp", 17 | "thread": "cpp", 18 | "cinttypes": "cpp", 19 | "typeindex": "cpp", 20 | "array": "cpp", 21 | "*.tcc": "cpp", 22 | "clocale": "cpp", 23 | "complex": "cpp", 24 | "cwctype": "cpp", 25 | "unordered_map": "cpp", 26 | "vector": "cpp", 27 | "exception": "cpp", 28 | "fstream": "cpp", 29 | "functional": "cpp", 30 | "initializer_list": "cpp", 31 | "iostream": "cpp", 32 | "istream": "cpp", 33 | "limits": "cpp", 34 | "new": "cpp", 35 | "ostream": "cpp", 36 | "numeric": "cpp", 37 | "sstream": "cpp", 38 | "stdexcept": "cpp", 39 | "streambuf": "cpp", 40 | "system_error": "cpp", 41 | "type_traits": "cpp", 42 | "tuple": "cpp", 43 | "typeinfo": "cpp", 44 | "utility": "cpp" 45 | } 46 | } -------------------------------------------------------------------------------- /tools/traincascade/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual -Winconsistent-missing-override -Wsuggest-override) 2 | file(GLOB SRCS *.cpp) 3 | ocv_add_application(opencv_traincascade 4 | MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d 5 | SRCS ${SRCS}) 6 | -------------------------------------------------------------------------------- /tools/traincascade/imagestorage.h: -------------------------------------------------------------------------------- 1 | #ifndef _OPENCV_IMAGESTORAGE_H_ 2 | #define _OPENCV_IMAGESTORAGE_H_ 3 | 4 | 5 | class CvCascadeImageReader 6 | { 7 | public: 8 | bool create( const std::string _posFilename, const std::string _negFilename, cv::Size _winSize ); 9 | void restart() { posReader.restart(); } 10 | bool getNeg(cv::Mat &_img) { return negReader.get( _img ); } 11 | bool getPos(cv::Mat &_img) { return posReader.get( _img ); } 12 | 13 | private: 14 | class PosReader 15 | { 16 | public: 17 | PosReader(); 18 | virtual ~PosReader(); 19 | bool create( const std::string _filename ); 20 | bool get( cv::Mat &_img ); 21 | void restart(); 22 | 23 | short* vec; 24 | FILE* file; 25 | int count; 26 | int vecSize; 27 | int last; 28 | int base; 29 | } posReader; 30 | 31 | class NegReader 32 | { 33 | public: 34 | NegReader(); 35 | bool create( const std::string _filename, cv::Size _winSize ); 36 | bool get( cv::Mat& _img ); 37 | bool nextImg(); 38 | 39 | cv::Mat src, img; 40 | std::vector imgFilenames; 41 | cv::Point offset, point; 42 | float scale; 43 | float scaleFactor; 44 | float stepFactor; 45 | size_t last, round; 46 | cv::Size winSize; 47 | } negReader; 48 | }; 49 | 50 | #endif 51 | --------------------------------------------------------------------------------