![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
c++
文章平均质量分 63
zsffuture
hello world
展开
-
pcl--第四节 采样一致性算法RANSAC
RANSAC是“RANdom SAmple Consensus”(随机抽样共识或采样一致性)的缩写,它是一种迭代方法,用于从包含异常值的一组数据中估计数学模型的参数。该算法由Fischler和Bolles于1981年发布。RANSAC算法假定我们要查看的所有数据均由内部值和异常值组成。可以用带有一组特定参数值的模型来解释离群值,而离群值在任何情况下都不适合该模型。其过程可以从数据中估计所选模型的最佳参数。RANSAC是一种随机参数估计算法。原创 2023-09-15 19:45:00 · 219 阅读 · 0 评论 -
c/c++子函数内使用malloc或者new申请一块内存供外部使用
在实际应用中,笔者编写了类似的例子,用形参指针去调用malloc函数,使用gcc编译,编译时不会报错,但是运行时会报段错误,产生段错误的因素很多,但本次运行的段错误确实跟形参指针调用malloc函数有关,当然也不是说形参指针不能调用malloc函数去申请动态内存,只是不能使用上述例子中的方式。函数体中只是修改了形参_p的内容,对于实参p没有任何影响。c语言中函数参数传递都是值传递,值传递分为数值传递和指针传递,因此指针传递也是一次赋值拷贝的过程。当指针作为函数的形参时,不要用该指针去申请动态内存。原创 2023-03-01 18:51:05 · 588 阅读 · 0 评论 -
使用cmake在win10编译yolov5+tensorRT+cuda+cudnn+protobuf代码进行混合编译
从Linux下载下来的工程代码,这里建议直接使用vs系列打开不要用vscode打开,vscode对win下的cmake不友好,主要体现在报错机制无法直接定位,题主的环境是vs2022通过cmake可以快速的进行定位bug,并可以快速解决(vscode 的cmake在Linux下还是比较友好的,但是通常如果在Linux下为什么 不研究makefile呢?这里进行之前需要把protobuf在win10下编译,可以参考。这个问题是win中需要包含。原创 2023-02-28 14:47:27 · 1388 阅读 · 0 评论 -
使用vs2022编译yolov5+tensorRT+cuda+cudnn代码进行混合编译
首先依赖有cuda、cudnn、tensorrt、protobuf,从Linux的代码直接移植过来这些库是没法使用的,需要下载对应win的下的版本,其中cuda、cudnn和tensorrt直接从官方下载即可,但是protobuf需要自己编译一下(原创 2023-02-22 09:23:03 · 1094 阅读 · 0 评论 -
c++多线程高性能版本
高性能c++ 多线程原创 2022-06-01 23:12:59 · 554 阅读 · 1 评论 -
c++11 --- 智能指针(shared_ptr)
1. 智能指针的初始化// 1. 智能指针的初始化 shared_ptr<myclass> p(new myclass); shared_ptr<myclass> p2 = p; shared_ptr<int> ptr; //未初始化的智能指针,可以通过reset进行初始化 ptr.reset(new int(1)); // 应该优先使用make_shared构造智能指针,更高效 shared_ptr<mycl原创 2022-05-31 19:45:30 · 1191 阅读 · 0 评论 -
深度学习c++部署高性能优化的技巧
图片预处理的高性能实现int input_batch = 1; int input_channel = 3; int input_height = 224; int input_width = 224; int input_numel = input_batch * input_channel * input_height * input_width; float* input_data_host = nullptr; float* input_data原创 2022-05-28 14:57:05 · 578 阅读 · 0 评论 -
C++11可变模版参数的妙用
泛化之美--C++11可变模版参数的妙用1概述C++11的新特性--可变模版参数(variadictemplates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数、任意类型的参数。相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进。然而由于可变模版参数比较抽象,使用起来需要一定的技巧,所以它也是C++11中最难理解和掌握的特性之一。虽然掌握可变模版参数有一定难度,但是它却是C++11中最有意思的一个特性,本文希望..原创 2022-05-22 22:16:23 · 215 阅读 · 0 评论 -
tensorRT--- 认识onnx
1、ONNX的本质,是一种Protobuf格式文件2、Protobuf则通过onnx-ml.proto编译得到onnx-ml.pb.h和onnx-ml.pb.cc或onnx_ml_pb2.py3、然后用onnx-ml.pb.cc和代码来操作onnx模型文件,实现增删改4、onnx-ml.proto则是描述onnx文件如何组成的,具有什么结构,他是操作onnx经常参照的东西https://github.com/onnx/onnx/blob/main/onnx/onnx-ml.proto.原创 2022-05-22 15:15:22 · 351 阅读 · 0 评论 -
tensorRT--- 动态shape
动态shape,即编译时指定可动态的范围[L-H],推理时可以允许 L <= shape <= H重点提炼:1.OptimizationProfile是一个优化配置文件,用来指定输入的shape可以变换的范围的,不要被优化两个字蒙蔽了双眼2.如果onnx的输入某个维度是-1,表示该维度动态,否则表示该维度是明确的,明确维度的minDims, optDims, maxDims一定是一样的// tensorRT include#include <NvIn.原创 2022-05-22 15:00:29 · 611 阅读 · 0 评论 -
tensorRT---inference
这里主要讲推理,我们关注的基础中的基础对吗重点提炼:1.bindings是tensorRT对输入输出张量的描述,bindings = input-tensor + output-tensor。比如input有a,output有b, c, d,那么bindings = [a, b, c, d],bindings[0] = a,bindings[2] = c。此时看到engine->getBindingDimensions(0)你得知道获取的是什么2.enqueueV2是异步推理,加入到s原创 2022-05-21 11:46:19 · 431 阅读 · 0 评论 -
tensorRT---helloworld
// tensorRT include#include <NvInfer.h>#include <NvInferRuntime.h>// cuda include#include <cuda_runtime.h>// system include#include <stdio.h>class TRTLogger : public nvinfer1::ILogger{ public: virtual void lo.原创 2022-05-21 10:44:24 · 225 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(认识thrust,认识cuda的错误机制)
thrust#include <stdio.h>#include <thrust/host_vector.h>#include <thrust/device_vector.h>#include <thrust/sort.h>#include <iostream>using namespace std;__host__ __device__int sort_func(int a, int b){ return a &g原创 2022-05-01 20:40:57 · 258 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(YOLOv5后处理)
Yolov5是目标检测中比较经典的模型,学习对其后处理进行解码是非常有必要的。在这里我们仅使用核函数对Yolov5推理的结果进行解码并恢复成框,掌握后处理所解决的问题,以及对于性能的考虑经验之谈:1.对于后处理的代码研究,可以把PyTorch的数据通过转换成numpy后,tobytes再写到文件,然后再到c++中读取的方式,能够快速进行问题研究和排查,此时不需要tensorRT推理也可以做后处理研究。这也叫变量控制法2.fast_nms_kernel会在极端情况少框,但是这个极端情况一般原创 2022-05-01 20:09:06 · 493 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(共享内存、Warpaffine)
共享内存1.共享内存因为更靠近计算单元,所以访问速度更快2.共享内存通常可以作为访问全局内存的缓存使用3.可以利用共享内存实现线程间的通信4.通常与__syncthreads同时出现,这个函数是同步block内的所有线程,全部执行到这一行才往下走5.使用方式,通常是在线程id为0的时候从global memory取值,然后syncthreads,然后再使用#include <cuda_runtime.h>#include <stdio.h>#.原创 2022-05-01 18:07:23 · 287 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(kernel-function)
1.核函数是cuda编程的关键2.通过xxx.cu创建一个cudac程序文件,并把cu交给nvcc编译,才能识别cuda语法3.__global__表示为核函数,由host调用。__device__表示为设备函数,由device调用4.__host__表示为主机函数,由host调用。__shared__表示变量为共享变量5.host调用核函数:function<<<gridDim, blockDim, sharedMemorySize, stream>>>原创 2022-04-30 20:40:39 · 183 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(stream---流操作)
1.流是一种基于context之上的任务管道抽象,一个context可以创建n个流2.流是异步控制的主要方式3.nullptr表示默认流,每个线程都有自己的默认流串行同步执行状态从上面可以发现主程序是女朋友,当女朋友发出“想吃苹果了”则会去调用子函数过程如:“想吃苹果”-->“买苹果”-->“出门”-->“买苹果”-->“回来了”-->“拿到东西”,这个过程女朋友只能等到买回苹果,中间什么也不做,这就是串行同步执行状态,那么并行同步执行状态是怎么做.原创 2022-04-30 16:01:13 · 629 阅读 · 0 评论 -
tensorRT---认识cuda RuntimeAPI(memory、Pinned Memory)
1.对于runtimeAPI,与driver最大区别是懒加载2.即,第一个runtime API调用时,会进行cuInit初始化,避免驱动api的初始化窘境3.即,第一个需要context的API调用时,会进行context关联并创建context和设置当前context,调用cuDevicePrimaryCtxRetain实现4.绝大部分api需要context,例如查询当前显卡名称、参数、内存分配、释放等 1.CUDA Runtime是封装了CUDA Driv...原创 2022-04-30 12:27:20 · 280 阅读 · 0 评论 -
CMakelist---rknn提供的样例很好,收藏一下
cmake_minimum_required(VERSION 3.4.1)project(rknn_yolov5_demo_linux)set(CMAKE_SYSTEM_NAME Linux)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")if (CMAKE_C_COMPILER MATCHES "aarch64") set(LIB_ARCH lib64).原创 2022-04-27 23:00:00 · 651 阅读 · 0 评论 -
NMS 原理和c++实现,已测试通过
NMS(非极大抑制)是深度学习目标检测中常用的小算法,用来过滤掉同一个物体上的那些置信度较低的bbboxes,最后只剩下该目标检测框集中最大置信度的那个。算法原理说它是小算法的原因是其原理很简单。1)先对输入检测框按置信度由高到低排序2)挑选第一个检测框(即最高置信度,记为A)和其它检测框(记为B)进行iou计算3)如果iou大于nmsThreshold, 那就将B清除掉4)跳转到2)从剩余得框集里面找置信度最大得框和其它框分别计算iou5)直到所有框都过滤完。代码实现.原创 2022-04-27 21:45:00 · 3378 阅读 · 0 评论 -
c++11新特性的使用---可变模板参数、type_traits、function综合使用
DLL帮助类c++中手动调用dll是比较繁琐的,调用过程是:加载dll后还要定义一个对应的函数指针类型,接着调用GetProAddress获取函数地址,在转成函数指针,最后调用该函数如下例子:#include "MyDLL.h"#include <iostream>#include <windows.h>void TestDll(){ typedef int(*pMax)(int a, int b); typedef int(*pGet)(int a);原创 2022-04-02 16:27:29 · 1237 阅读 · 0 评论 -
c++11新特性的使用---可变模板参数、lambda、type_traits、optional综合使用
通过惰性求值类的实现综合采用了可变模板参数、lambda、type_traits、optional进行实现该类功能是:当初始化某个对象时,该对象引用了一个大对象,这个对象的创建需要较长的时间,同时有大量的堆内存分配,这样可以会使得整体的初始化变的很慢,尤其是UI应用时会导致用户体验差,其实很多时候并不用马上就获取大数据,只是在需要的时候获取即可,这种场景就很适合延迟加载。目前C++中还没有类似的Lazy<T>惰性求值类,实现思路比较简单,借助lamda表达式,将函数封装到lamda表达式原创 2022-04-02 15:25:22 · 2299 阅读 · 0 评论 -
linux下c++版本线程池的实现
该版本的是来源c语言版本的修改,只是对其进行了封装,这里不过得解释原理,大家可以看这篇文章下面将直接上代码,同时这里需要主要的是使用的线程函数是linux自带的不是c++的自带线程函数,后续会使用c++提供一个线程池版本目录任务队列头文件源文件线程池线程池头文件线程池源文件测试代码任务队列头文件#ifndef __TASKQUEUE__H#define __TASKQUEUE__H#include<queue>#include<.原创 2022-04-01 11:32:54 · 1950 阅读 · 0 评论 -
linux下c语言版线程池
1. 线程池原理我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务呢?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先..原创 2022-03-30 16:38:11 · 3025 阅读 · 0 评论 -
ubuntu vscode通过cmake配置c++和VS2019一样 进行调试
之前的linux下vscode配置c++,使其和Visual Studio2019一样调试文章和本篇类似,配置vscode使其和vs2019进行调试和编译,但是之前的文章不是很实用,是通过命令行的形式进行配置的,这样的方法针对小工程还好,如果是复杂很大的工程就显得很复杂了,那么有没有更好的方法呢?答案是有,这里大家可以参考官网的文章,官网的例子很简单,我这里是比较复杂的项目,同时也会讲解的配置过程中遇到的问题。1.ubuntu下的cmake版本问题 之所以说这个问题,等后面我们都配...原创 2021-12-08 18:45:00 · 3509 阅读 · 2 评论 -
linux下vscode配置c++,使其和Visual Studio2019一样调试
linux下c++编译的方式 在win下visual studio为我们进行了大量的封装,同时设计了大量的容易操作的配置和界面,使得开发人员不过太过关注底层的编译链接过程,只需要关注代码本身即可,提升了开发的效率,但是在linux下就不一样了,linux下的编译和链接需要我们自己动手做,因此你会发现linux下会有很多种方式进行编译链接,这样只聊三种集Makefile、cmake和vscode:Makefile 这里来源不介绍了,直接给教程,可以看这篇文章cmak...原创 2021-12-06 19:15:00 · 4895 阅读 · 2 评论 -
cmake使用教(三)构建动态库、静态库和安装共享库
前两节简单的介绍了,cmake的简单使用和install的过程,本节将详细介绍构建动态库和静态库,以及共享动态库和静态库的过程文件存放方式:创建test根目录,然后创建lib和build,在根目录下创建CMakeLists.txt,,在lib目录下创建CMakeLists.txt、hello.cpp、hello.h, 其中hello.cpp、hello.h内容如下:hello.h#ifndef HELLO_H#define HELLO_H#include<iostream&.原创 2021-12-02 20:30:00 · 4188 阅读 · 0 评论 -
c++11 多线程编程(六)------条件变量(Condition Variable)
互斥锁std::mutex是一种最常见的线程间同步的手段,但是在有些情况下不太高效。假设想实现一个简单的消费者生产者模型,一个线程往队列中放入数据,一个线程往队列中取数据,取数据前需要判断一下队列中确实有数据,由于这个队列是线程间共享的,所以,需要使用互斥锁进行保护,一个线程在往队列添加数据的时候,另一个线程不能取,反之亦然。用互斥锁实现如下:#include <iostream>#include <deque>#include <thread>#incl原创 2021-12-01 22:45:00 · 271 阅读 · 0 评论 -
c++11 多线程编程(五)------unique_lock
互斥锁保证了线程间的同步,但是却将并行操作变成了串行操作,这对性能有很大的影响,所以我们要尽可能的减小锁定的区域,也就是使用细粒度锁。这一点lock_guard做的不好,不够灵活,lock_guard只能保证在析构的时候执行解锁操作,lock_guard本身并没有提供加锁和解锁的接口,但是有些时候会有这种需求。看下面的例子。class LogFile { std::mutex _mu; ofstream f;public: LogFile() { f.原创 2021-12-01 22:00:00 · 211 阅读 · 0 评论 -
c++11 多线程编程(四)------ 死锁(Dead Lock)
死锁如果你将某个mutex上锁了,却一直不释放,另一个线程访问该锁保护的资源的时候,就会发生死锁,这种情况下使用lock_guard可以保证析构的时候能够释放锁,然而,当一个操作需要使用两个互斥元的时候,仅仅使用lock_guard并不能保证不会发生死锁,如下面的例子:#include <iostream>#include <thread>#include <string>#include <mutex>#include <fstrea原创 2021-12-01 21:30:00 · 354 阅读 · 0 评论 -
c++11 多线程编程(三)------ 竞争和互斥锁
竞争条件并发代码中最常见的错误之一就是竞争条件(race condition)。而其中最常见的就是数据竞争(data race),从整体上来看,所有线程之间共享数据的问题,都是修改数据导致的,如果所有的共享数据都是只读的,就不会发生问题。但是这是不可能的,大部分共享数据都是要被修改的。而c++中常见的cout就是一个共享资源,如果在多个线程同时执行cout,你会发发现很奇怪的问题:#include <iostream>#include <thread>#includ原创 2021-12-01 20:45:00 · 560 阅读 · 0 评论 -
c++11 多线程编程(二)------ 线程类构造函数深入理解
构造函数的参数std::thread类的构造函数是使用可变参数模板实现的,也就是说,可以传递任意个参数,第一个参数是线程的入口函数,而后面的若干个参数是该函数的参数。第一参数的类型并不是c语言中的函数指针(c语言传递函数都是使用函数指针),在c++11中,增加了可调用对象(Callable Objects)的概念,总的来说,可调用对象可以是以下几种情况:函数指针 重载了operator()运算符的类对象,即仿函数 lambda表达式(匿名函数) std::function函数指针示例原创 2021-12-01 19:15:00 · 419 阅读 · 0 评论 -
c++11 多线程编程(一)------初始
什么是并发并发在生活中随处可见,边走路边说话,边听歌边写代码。计算机术语中的"并发",指的是在单个系统里同时执行多个独立的活动,而不是顺序的一个接一个的执行。对于单核CPU来说,在某个时刻只可能处理一个任务,但它却不是完全执行完一个任务再执行一个下一任务,而是一直在任务间切换,每个任务完成一点就去执行下一个任务,看起来就像任务在并行发生,虽然不是严格的同时执行多个任务,但是我们仍然称之为并发(concurrency)。真正的并发是在在多核CPU上,能够真正的同时执行多个任务,称为硬件并发(hardwar原创 2021-12-01 18:15:00 · 302 阅读 · 0 评论 -
yolov5 解码使用GPU进行加速
YOLOv5原理方面这里不再过多阐述,直接从输出头开始,然后设计如编解码:1.yolov5系列的原始输出是3个head头,上图画的是输入为608*608的分辨率的图,如果输入改为640*640分辨率的图片,那么输出的3个头分别对应三个8、16、32下采样的输出分别为80*80*255、40*40*255、20*20*255,其中对应的数字意义如上图所示。2.那么80*80*255、40*40*255、20*20*255数字分别代表什么意思,其中B是batch..原创 2021-11-23 19:30:00 · 9637 阅读 · 6 评论 -
双线性插值算法实现和opencv、matlab结果不一致问题
最近在编程时用到了双线性插值算法,对图像进行缩放。网上有很多这方面的资料,介绍的也算明白。但是,这些文章只介绍了算法,并没有具体说怎么实现以及怎么实现最好,举个例子,你可以按照网上文章的算法自己写一个双线性插值程序,用它对一张图片进行处理,然后再用matlab或者openCV的resize函数对同一张图片进行处理,得到的结果是不一样的,如果源图片较小,效果差距就更大。以下是对于双线性插值的讲解以及上述现象的解释:1.双线性插值假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:转载 2021-11-02 10:21:04 · 756 阅读 · 0 评论 -
VS单步调试的无法进入断点、行号错乱等问题解决方法
Visual Studio有时候会出现单步调试时候,断点处变成不可命中,始终提示“当前不会命中断点。源代码与原始版本不同。”或者就算能进入断点,单步调试时实际执行的代码与源码行号不匹配的问题。通常原因是因为代码中有非ASCII字符等原因。尤其是使用了拷贝的网页上的代码,或者使用了老外写的代码,容易出现这类问题。解决方法:1、在VS中打开该文件,打开另存为(Save as)对话框。2、点击对话框中“保存(Save)”按钮右边的向下三角形按钮。3、编码方式(Encoding)选择 UTF-8.转载 2021-10-29 13:51:57 · 1286 阅读 · 1 评论 -
python实现warpaffine,配上原理和代码
代码来源:https://github.com/shouxieai/tensorRT_Pro# 实现一个仿射变换,采用双线性插值方式实现一个warpaffinedef pyWarpAffine(image, M, dst_size, constant=(0,0,0)): M = cv.invertAffineTransform(M) # 求仿射变换的逆矩阵,因为我们是把目的图片作为输入图片,因此需要使用逆矩阵求取原始图片的点 cons...原创 2021-10-28 18:02:07 · 1639 阅读 · 0 评论 -
windows 下编译libcurl,通过url下载图片数据
windows 下编译libcurl因为linux平台采用了libcurl,有一个程序移植到到windows平台,再linux采用libcurl。在windows下准备也采用该库。在网上搜索了几位同行写的,步骤上面有缺失。本文将以详细的步骤,介绍libcurl的编译。下面是步骤:1. 下载源代码,直接从github上clone仓库,就可以了。 git clonehttps://github.com/curl/curl.git2. 选择版本 我采用了版本:...转载 2021-09-07 11:29:39 · 539 阅读 · 0 评论 -
C++通过url直接下载图片并保存
#include <windows.h>#include"down.h"#include <urlmon.h>#include <tchar.h>#include <string>#include <iostream>using namespace std;#pragma comment(lib,"urlmon.lib")#pragma comment(lib,"ws2_32.lib")#void down(string url.原创 2021-08-31 12:23:03 · 2501 阅读 · 2 评论 -
python调用c++深度学习模型生成的dll(传入图片,返回多个结果)
这里主要通过python调用c++深度学习模型,传入图片,c++处理,并返回结果,python接收结果,这个过程的接口如何设计转换。python端代码接口# 定义dll返回的结果类型,这里应该和c++中定义的返回结构体一一对应class Result_process(Structure): _fields_ = [ ('count', c_int), ('ID', c_int), ('score',c_float), (.原创 2021-08-05 11:06:00 · 1549 阅读 · 7 评论