- 博客(147)
- 资源 (15)
- 收藏
- 关注

原创 OpenCV实战之人脸美颜美型算法
更重要的是,课程中通过需求分析——功能定义——原理设计——编程实战的流程来让你掌握比较复杂的图像算法开发流程剖析与实施的技能,这将会在你后续的科研/项目开发过程中发挥更大的作用。人脸美颜美型是一个综合性较高的算法,包括基于机器学习的人脸与关键点检测,与常见传统图像处理方法,如图像滤波,图像融合,形态学操作、图像变形等。鉴于此,笔者设计了一套基于OpenCV实现的一套比较完整的人脸美颜美型算法,实现包括磨皮、美白、大眼、瘦脸、下巴收放、瘦鼻等功能,算法效果如下几张动图所示。
2022-11-12 15:53:11
5498
8
原创 毫米波雷达标定(2)
前面文章中介绍了产线上毫米波雷达的标定原理和流程,这篇文章则主要介绍其在线标定方法。相对于产线标定,在线标定具备使用自然场景而不是依赖特定标靶的优点,但因此其标定精度会相对差一点。在线标定一般应用于售出产品的维护场景,如果其标定结果精度可以满足使用要求则无需再做更为精密但人力成本更高的产线标定/售后标定。毫米波雷达的在线标定方法只会计算其偏航角数据,如下介绍两种基于自然行车场景下的毫米波雷达标定方法。
2025-03-24 18:01:18
57
原创 毫米波雷达标定(1)
RADAR(Radio Detecting And Ranging)是指利用毫米波信号(30-300GHz)来探测和测量目标的雷达系统,其中毫米波是微波的一个子频段。在汽车领域,使用的毫米波雷达主要在24GHz,77GHz和79GHz三个频段。毫米波雷达工作频率越高,波长就越短,分辨率就越高。因此,与24GHz雷达相比,工作频率在76-81GHz的毫米波雷达,物体分辨准确度,测速和测距精确度都会进一步提高,能检测行人和自行车,且设备体积更小,更便于在车辆上安装和部署。按照探测距离,毫米波雷达可分为。
2025-03-19 13:45:17
45
原创 基于消失点标定前视相机外参
我们希望标定得到相机坐标系相对于车辆坐标系的外参。把车辆停放于两条平行的道路标志线中间,且确保车身与道路标志线平行,此时车辆坐标系和世界坐标系的X/Y/Z坐标也是平行关系,即它们之间只存在平移。2)计算得到的实际上是相机坐标系和道路线所在的世界坐标系之间的旋转角,在道路线所在世界坐标系和车辆坐标系满足只存在平移不存在旋转的条件时,它们也是相机坐标系到车辆坐标系的旋转角。如下图所示,绕Z轴旋转的角度为roll(滚转角),绕Y轴旋转的角度为yaw(偏航角/横摆角),绕X轴旋转的角度为pitch(俯仰角)。
2025-03-16 17:40:59
259
原创 OpenCalib(八)随机搜索优化算法简介及应用
OpenCalib在标定激光雷达到相机的外参计算代码中引入了随机搜索优化计算,其代码位于SensorsCalibration\lidar2camera\auto_calib\src\optimizer.cpp。同时相比基于梯度优化的方法,在问题空间存在多个局部极值的情况下,随机搜索算法有时候陷入局部极值的概率会更小。在实际计算中,可灵活调用上述函数,通过不同的参数设置组合(循环次数、变量搜索范围)达到更优的效果,譬如Optimizer::Calibrate()中如下进行随机搜索计算。
2025-03-13 14:59:36
36
原创 Windows平台使用NDK交叉编译OpenCV
2)-DCMAKE_MAKE_PROGRAM="D:/SDK/android-ndk-r27-windows/android-ndk-r27/prebuilt/windows-x86_64/bin/make.exe",设置了构建工具使用NDK中自带的make命令。1)NDK r27中clang版本较高,语法要求更加严格,会将一部分代码编译时报错,这里通过添加-DCMAKE_C_FLAGS="-Wno-error=implicit-function-declaration"来规避。
2025-03-10 15:34:32
181
原创 OpenCalib(七)二维码检测
前面无论是对棋盘格标靶还是圆形标靶检测时,一般都需要将所有标靶全部检出,这样才能根据标靶的分布确定每个标靶的相对位置。举个例子,对于5x5分布的棋盘格,如果我们只检出4x4排列的棋盘格,那么它在整个棋盘格中可能存在4种分布,此时我们无法确认检测结果中各个棋盘格角点对应的世界坐标,进而无法完成外参计算。而在实际应用场景中经常出现因光照、遮挡、脏污等导致的标靶检测不全的情况,此时无法确定标靶的相对位置,导致标定失败。究其原因,在于标靶的特征相同,无法相互区分。
2025-02-24 16:18:25
47
原创 OpenCalib(六)圆形标靶检测
OpenCalib提供了圆形标靶的检测方案,将检出的圆形区域中心作为角点输出。标靶如下图所示,具备如下特征:1)中心区域两个圆形为黑色;2)中间区域圆形按照5*4等距平行排列;3)两侧各有一个5*1的圆形排列。这些特征都将作为约束用来筛选备选点,以排除噪声的影响。
2025-02-21 15:47:04
47
原创 OpenCalib(五)竖直棋盘格标靶检测
除了水平棋盘格标靶,OpenCalib还支持竖直棋盘格标靶的检测。其形状如下,一般用于前视摄像头的标定。
2025-02-20 13:39:54
40
原创 OpenCalib(四)水平棋盘格标靶检测
OpenCalib中实现了不依赖OpenCV的多种标靶检测算法,支持棋盘格、圆形、AprilTag、aruco marker等多种标靶,如下图所示。下面开始对相关代码进行详细解读,首先介绍水平棋盘格标靶检测算法。算法流程示意图如上图所示,大致分为三步。1)棋盘格检测对原始图像做一些预处理,包括二值化、膨胀,得到了互相分离的一些棋盘格;之后进行轮廓检测,拟合得到包络四边形2)棋盘格聚类左右棋盘格成“品”字型排列,利用这个特性对上述得到的四边形进行筛选,算法中主要通过四边形中心点之间的距离做相关计算。
2025-02-18 16:29:10
54
原创 OpenCalib(三)相机内参标定
OpenCalib中提供了针孔相机模型相机内参标定和结果校验的方案,包括相关算法、标靶尺寸信息等,其代码位于camera_intrinsic文件夹。具体包括如下内容:1)基于针孔相机模型标定相机内参和畸变系数(k1/k2/p1/p2/k3形式)2)提供一种量化校验相机内参标定精度的方法3)提供上述方法中用到的标靶图像和尺寸信息。
2025-02-17 11:22:26
113
原创 OpenCalib(二)环境搭建
Eigen的相关头文件都被安装到了/usr/local/include/eigen3目录下,但是很多三方库(如OpenCV等)在包含头文件时都写作"#include <Eigen/Core>"的形式,此时会报找不到头文件的错误。处理这个问题有多种方法:1)修改相关库/程序的编译选项,将/usr/local/include/eigen3加入头文件的搜索路径,2)将Eigen的安装文件拷贝到系统搜索目录中,3)构造软链接。这里使用了方法3,即执行如下命令。通过cmake编译安装,这里安装的是3.3.7版本。
2025-02-13 18:09:27
154
原创 OpenCalib(一)简介
上海AI实验室和商汤联合发布的一篇文章《OpenCalib: A Multi-sensor Calibration Toolbox for Autonomous Driving》,其中介绍并发布的OpenCalib。它是一个支持车载常见的各种传感器标定的工具集,包括手动标定、自动标定、工程标定和在线标定。附带的还有一个基准数据集,用于评估和提升标定精度。代码地址为自动驾驶中需要使用各种传感器来采集数据,常见的传感器包括IMU、GNSS、激光雷达、相机、毫米波雷达、轮速计。
2025-02-13 10:13:06
105
原创 使用mingw+CMake在Windows平台编译OpenCV
其中的bin文件夹中包含了gcc和g++的可执行程序,打开后发现存在多个类似名称的文件,如"c++.exe"、"g++.exe"、“x86_64-w64-mingw32-g++.exe”等。实际对比后发现"c++.exe"、"g++.exe"、“x86_64-w64-mingw32-g++.exe”这三个文件完全相同,因此使用其中任意一个设为c++编译器均可正常工作。之后分别指定C和C++的文件路径,对应到MingW的bin文件夹中的gcc.exe和g++.exe,点击Finish按钮。
2024-11-26 10:38:22
1152
原创 基于LUT表对鱼眼图像进行畸变校正
当然也可以进行图像的畸变校正操作,已知相机的焦距为fx/fy,光心为cx/cy,像素大小为p(单位mm/pixel)对于畸变校正结果图中像素点(u,v),其对应的原图中的像素坐标(u',v')的计算流程描述如下。1)假设无畸变相机成像模型的焦距和光心与原相机相同,计算得到无畸变相机成像模型中归一化平面坐标(X,Y,Z),其中X=(u-cx)/fx,Y=(v-cy)/fy,Z=1。这里x'/y'的单位为像素。
2024-11-06 11:20:26
160
原创 AprilTag在相机标定中的应用简介
相机标定用的标靶类型多样,常见的形式有棋盘格标靶和圆形标靶。今天要介绍的AprilTag比较特别,它是一种编码形式的标靶。其官网为AprilTag,它是一套视觉基准系统,包含标靶编解码方法(Tag生成)和检测算法(Tag检测),可用于AR、机器人、相机标定等领域。如下图所示这些机器人上搭载的就是AprilTag标靶,通过检测标靶上的靶点,可实现观测相机与机器人之间外参的计算,即机器人的定位&观测。
2024-10-31 20:55:46
538
原创 块匹配算法简介(上)
图像中的运动估计方法大致分为两类:光流法和块匹配算法(BMA,Block Matching Algorithm)。本文将介绍BMA的相关内容,包括基本原理、相似度计算准则与常见的几种搜索方法,如三步法、四步法、钻石搜索法等。
2024-09-20 14:48:04
484
原创 HS光流法原理与实现
人眼观察到物体运动时,物体会在视网膜平面上形成一系列连续变化的图像“流过”视网膜,好像一种光的“流”,所以被称为光流。光流基于像素点定义,所有光流的集合称为光流场。通过对光流场分析,可以得到物体相对于观察者的运动信息。计算光流场的方法有很多,常见的有LK光流法、HS光流法等,本文介绍HS光流法的原理与编程实现。
2024-09-10 16:49:45
264
原创 OpenCV中使用金字塔LK光流法(下)
接下来通过一个demo来调用calcOpticalFlowPyrLK()实现光流计算,需要注意的是该方法适用于具有丰富特征的像素点的光流计算,平坦区域的像素点往往会得到误差较大的结果。代码如下,首先调用cv::goodFeaturesToTrack()在图像一种检测角点,之后调用cv::calcOpticalFlowPyrLK()计算角点在图像二中的位置,最后绘制光流结果。如下有两张图像,第二张相对于第一张整体向左移动,我们尝试在第一张图像中挑选一些特征点,计算它们在图像二中的位置,它们的差异就是光流。
2024-08-30 10:46:04
326
原创 OpenCV中使用金字塔LK光流法(上)
有关金字塔LK光流法的原理,可参考这篇文章。这里我们讲解OpenCV中实现的金字塔LK光流法的相关API,并通过一个demo来学习如何使用它。首先介绍一些API,它们是光流法流程中会用到的功能函数,之后再介绍calcOpticalFlowPyrLK()。
2024-08-29 16:59:58
327
原创 OpenCV中的圆形标靶检测——findCirclesGrid()(四)
至此我们完成了基于层次聚类的圆斑标靶检测算法的分析,后面将开始基于距离向量方法的讲解。中分析的函数源码及其注释张贴出来,具体如下。
2024-07-29 10:14:31
372
原创 OpenCV中的圆形标靶检测——findCirclesGrid()(三)
由于是鸟瞰视角,我们可以计算得到索引为(i,j)的标靶的理论位置,在附近搜索距离最近的实际存在的斑点作为其对应的标靶并记录该斑点在斑点集中的索引。调整后确保点0-点1指向标靶宽度方向,点1-点2指向标靶的高度方向。这里的“外部点”定义为与由于是非对称标靶多出的额外两个凸包点(绿色圆圈圈出)连成的直线成平行关系的边包含的点,它们用于确定标靶分布的宽度方向。该函数会基于上述得到的排序的点,结合标靶的分布尺寸计算得到单应变换矩阵,然后使用该矩阵将之前检出的标靶点转换为鸟瞰视角下的结果,示意效果如下图所示。
2024-06-19 18:24:58
576
原创 OpenCV中的圆形标靶检测——findCirclesGrid()(二)
本章我们开始讲解基于层次聚类的标靶检测算法。现在开始分析代码的具体实现,如下所示可以看到cv::findCirclesGrid()内部会调用cv::findCirclesGrid2(),而在cv::findCirclesGrid2()内部先使用SimpleBlobDetector进行圆斑检测,然后使用CirclesGridClusterFinder算法类执行基于层次聚类的标靶检测。如下图所示为对称标靶和非对称标靶的检测结果,其中左侧的标靶中人为加了5个干扰点,可以看到检测结果并未受到影响。
2024-06-18 19:28:38
663
原创 OpenCV中的圆形标靶检测——findCirclesGrid()(一)
如前所述,OpenCV中可以使用findCirclesGrid()实现圆形标靶的检测,该函数的计算流程分为1)斑点形状的检测,和2)基于规则的斑点形状的过滤与定位。2)上述两种算法中,第一种对应的实现函数为上面代码段中的第一个findCirclesGrid(),第二种是上面代码段中的findCirclesGrid2(实际上它也包含第一种算法的实现,通过flags来区分)在前面的章节中我们已经介绍了第一步中使用到的SimpleBlobDetector算法类,现在开始介绍第二部分的相关内容。
2024-06-13 14:07:48
1236
原创 OpenCV中的圆形标靶检测——斑点检测算法(二)
然后随着阈值的递增每次都会检出一批斑点,算法内部使用启发式方法将它们归类,使得属于同一个物理世界中斑点的检测结果成为一组,同一组内的检测结果按照半径从大到小排列,如下图所示。至此我们完成了斑点检测算法原理与实现的剖析,之后将开始分析OpenCV中是如何将这些信息作为输入,结合标靶中圆斑的分布信息进行进一步的过滤,最终实现圆形标靶的检测流程。前面的章节中我们已经大致介绍了算法流程,也对一些算法中用到的相关概念做了简要介绍,同时给出了算法调用的API,现在我们开始算法检测接口实现源码的分析。
2024-06-04 10:56:45
439
原创 OpenCV中的圆形标靶检测——斑点检测算法(一)
在上一节内容中我们简要描述了OpenCV中实现圆形标靶检测的API的使用方法,其处理流程可大致分为1)斑点形状的检测,和2)基于规则的斑点形状的过滤与定位。接下来我们开始进行SimpleBlobDetector的剖析,首先会介绍一些算法计算中使用到的相关图形学概念,之后大致介绍算法的计算流程,然后分析SimpleBlobDetector的接口和参数,最后结合算法流程分析算法的内部实现。实际标定场景中,标靶成像会受到光照、噪点、镜头畸变等因素的影响,导致待检测的圆斑并不是高区分度的正圆,如下图所示。
2024-06-03 14:09:05
922
1
原创 基于单目相机的标靶三维定位——编程实现
实际运行效果如下图所示,可以观察到标靶坐标系X轴向右,Y轴向下,Z轴向里。当标靶向右移动时,计算得到的X变大,反之变小;接下来实现一个完整的功能函数,以摄像头图像和相机内参为输入,不断计算并显示棋盘格标靶所在坐标系原点相对于相机坐标系的三维坐标;上一章内容中我们描述了基于单目相机实现标靶三维定位的原理,关键步骤为1)计算得到相机的内参和畸变系数;3)计算标靶坐标系到相机坐标系的变换矩阵。首先我们实现一个函数,输入为包含棋盘格的图像,相机内参,输出为标靶坐标系相对于相机坐标系的变换信息,具体实现如下。
2024-04-15 17:49:00
826
2
原创 基于单目相机的标靶三维定位——原理阐述
我们已知棋盘格标靶的各个角点位于棋盘格坐标系的坐标(单位mm,Z为0),同时通过角点检测可得到它们对应的像素坐标,且已知相机的内参与畸变系数,那么我们可以求解得到标靶坐标系到相机坐标系的变换矩阵Tcw。对于标靶左上角角点,它在标靶坐标系的坐标为Pw(0,0,0),则该角点在相机坐标系下的坐标Pc=Tcw*Pw,即得到了它相对于相机坐标系的三维位置。
2024-04-11 20:34:13
589
原创 普通相机标定——执行与结果验证
作者用的相机分辨率为1280x720,执行程序的输出结果如下,输出信息包括相机的内参与畸变系数,同时将每幅图像的平均重投影误差也打印了出来。在采集了一定量的数据之后,从中挑选10张左右的图像,使得棋盘格在各张图像上具备不同的位姿,且整体上能够覆盖尽量多的视野,如下图所示。如下图所示标定结束后会新增《corner》和《undistorted》文件夹,分别存放成功检测角点的每幅图像的角点绘制结果和对应的使用了标定得到的内参进行畸变校正得到的校正结果,以查看确定角点检测与畸变校正的正确性。
2024-04-08 18:32:05
199
原创 windows平台编译opencv4.9.0
参考网上的一种做法,这里把如下文件中https://raw.githubusercontent.com/开头的下载地址前面都增加“https://mirror.ghproxy.com/”变成“https://mirror.ghproxy.com/https://raw.githubusercontent.com/”开头。然后就会生成OpenCV.sln,使用VS2017打开它,分别在Debug和Release模式下进行编译和安装,编译产物会存放在build/vs2017_x64/install文件夹下。
2024-03-01 16:33:20
869
原创 普通相机标定——核心函数编写
这里我们实现一个校验相机内参标定结果的函数,其原理为利用相机标定得到的外参、内参、畸变系数,将棋盘格角点从世界坐标映射到像素坐标,然后对比上述像素坐标与检测得到的像素坐标的差异。该函数实现利用采集好的标定图像进行相机内参的标定,同时调用上述实现的ComputeReprojectionErrors校验标定结果,实现如下。现在我们已经完成了标定图像的采集,如下图所示;接下来就要完成相机的内参标定了。中已经对它们做了简要介绍,这里不再赘述。
2024-01-26 16:38:37
204
原创 普通相机标定——功能函数编写
如之前章节内容所述,相机内参标定的流程包括1)采集一些包含棋盘格的相机图像,2)检测棋盘格角点,3)标定计算相机内参与畸变系数,4)验证标定精度与效果。本章我们将开始具体的编程开发,首先完成一些功能性函数的实现。注:相关代码在Windows平台运行。
2023-12-29 16:22:36
547
原创 普通相机标定——OpenCV函数讲解(下)
至此OpenCV中有关标定的基础函数基本上介绍完毕,我们后面需要组合使用上述函数完成相关的功能,包括角点检测,相机内参标定,相机外参标定,世界坐标系、相机坐标系、像素坐标系之间的映射计算等。@param objectPoints 世界坐标系下的坐标, 3xN/Nx3的一通道数据或者1xN/Nx1的三通道数据,譬如vector<Point3f>,N是点数。@param newCameraMatrix 畸变校正后图像的相机内参矩阵,默认与输入的内参矩阵相等;@param src 存在畸变的输入图像。
2023-12-22 18:07:20
981
原创 9. 使用Pthreads实现线程池(二)
首先定义存储任务信息的结构体,我们可以将其抽象为函数指针和参数,如下所示// 函数指针void *arg;// 函数参数接下来定义线程池的结构体,包含线程池的资源和状态等属性,如下所示// 工作线程数量// 任务队列的容量// 加入的任务数量// 将要保存任务信息的队列索引// 将要取出任务信息的队列索引// 线程池状态变量操作的互斥锁// 任务队列有空闲空间的信号// 任务队列中有待处理任务的信号// 工作线程数组指针// 任务队列,环形缓冲区形式// 销毁标志。
2023-12-07 20:52:50
343
原创 9. 使用Pthreads实现线程池(一)
线程池初始化时也会创建一个管理线程,它的主要职责是监视工作负载状态,动态调整线程数量来尽量快速地处理任务,同时尽量降低资源的无效占用。基本思想就是提前创建一些工作线程,将加入的任务分配给它们做处理,并根据任务/线程的数量情况动态地增删线程,确保任务处理效率和系统资源占用之间达到比较好的平衡。这里我们定义一个简化版本的线程池,其调用流程如下:构造线程池——加入任务——开始执行——销毁线程池。在接收到有任务要处理的信号后被唤醒并竞争任务,竞争到任务的线程做具体处理,没有竞争到任务的线程则会继续进入休眠。
2023-12-07 19:54:28
534
原创 ARM架构&性能优化简介
这里加速比S=1/(1-a+a/k),假如我们对某个占比60%的代码进行3倍加速,那么整体的加速比为1/(1-0.6+0.6/3)=1.6667,比3小了将近一半!比如一个应用程序A,系统运行总时间是T,某一部分执行时间为t,t与T的比值是a(t / T = a,也就是说 t = aT), 该部分性能提升k倍时执行时间为 t’ = aT / k。Amdahl 定律是计算机系统中的一个重要定律,核心思想是:我们对计算机系统的某一部分加速的时候,该加速部分对系统整体性能的影响取决于该部分的重要性和加速程度。
2023-11-10 17:33:06
677
原创 1. Pthreads专栏简介
以前硬件供应商一般都会提供相应硬件专用的线程库,使得代码的可移植性成为另开发者头疼的一个问题。在UNIX系统中,IEEE POSIX 1003.1c标准已经定义了基于C的标准化线程编程接口规范,遵守该规范实现的线程库称为POSIX threads,或者Pthreads。本专栏围绕着Pthreads展开,从API的详细介绍到使用Pthreads进行开发实战,助你入门多线程编程。教程首先介绍了线程的概念,产生的背景和设计思想,之后围绕着线程管理,互斥变量,和条件变量展开。
2023-11-07 20:46:41
325
opengl_test.zip
2019-07-19
《无人驾驶车辆 模型预测控制》随书代码
2017-12-05
meanShift视频目标跟踪 C++实现源代码
2017-11-06
PCL1.8 All-in-one安装包百度云下载地址
2017-10-11
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人