OpenCV
OpenCV 部分库函数整理。
 1. 寻找(二值)图像块轮廓:findContours()
1  | 
  | 
image:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过 Canny、拉普拉斯等边缘检测算子处理过的二值图像。contours:定义为vector<vector<cv::Point>> contours,是一个双重向量,向量内每个元素保存了一组由连续的 Point 点构成的点的集合的向量,每一组 Point 点集就是一个轮廓。contours 的大小为轮廓的数量。hierarchy:定义为vector<Vec4i> hierarchy,Vec4i的定义为typedef Vec<int, 4> Vec4i,即向量内每一个元素包含了 4 个 int 型变量的向量。hierarchy 向量内每个元素保存了一个包含 4 个 int 整型的数组。 hiararchy 内的元素和轮廓向量 contours 内的元素是一一对应:hierarchy 内每一个元素的 4 个 int 型变量——hierarchy[i][0] ~ hierarchy[i][3],分别表示第 i 个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~ hierarchy[i][3]的相应位被设置为默认值-1。mode:轮廓的检索模式:CV_RETR_EXTERNAL:只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;CV_RETR_LIST:检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,即不存在父轮廓或内嵌轮廓,所以 hierarchy 向量内所有元素的第 3、4 个分量都会被置为 -1;CV_RETR_CCOMP:检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;CV_RETR_TREE:检测所有轮廓,所有轮廓建立一个等级树结构,外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
method:轮廓的近似方法:CV_CHAIN_APPROX_NONE:保存物体边界上所有连续的轮廓点到 contours 内;CV_CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入 contours 内,拐点与拐点之间直线段上的信息点不予保留;CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS:使用 teh-Chinl chain 近似算法。
offset:Point 偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,Point 可以是负值。- ref:https://blog.csdn.net/dcrmg/article/details/51987348
 
2. 图像二值化
- 图像二值化一般需要先将图像转化为灰度图
 - ref:https://blog.csdn.net/weixin_40087859/article/details/115278361
 
 2.1  图像颜色转化:cvtColor()
1  | 
  | 
- 
src:原始图像,格式为 8-bit unsigned / 16-bit unsigned / single-precision floating-point。 - 
dst:目标图像:size 与 depth 和原始图像要相等。 - 
code:色彩空间转换码。常用转换码包括:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20cv::COLOR_BGR2BGRA // add alpha channel to RGB or BGR image
cv::COLOR_RGB2RGBA
cv::COLOR_BGRA2BGR
cv::COLOR_RGBA2RGB
cv::COLOR_BGR2RGBA
cv::COLOR_RGB2BGRA
cv::COLOR_RGBA2BGR
cv::COLOR_BGRA2RGB
cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_BGRA2RGBA
cv::COLOR_RGBA2BGRA
cv::COLOR_BGR2GRAY
cv::COLOR_RGB2GRAY // RGB to grayscale
cv::COLOR_GRAY2BGR
cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGRA
cv::COLOR_GRAY2RGBA
cv::COLOR_BGRA2GRAY
cv::COLOR_RGBA2GRAY - 
dstCn:目标图像的通道数,此参数为 0 时,目标图像的通道数由原始图像自动生成。 - 
ref:https://blog.csdn.net/duwangthefirst/article/details/79956616
 
 2.2  二值化:threshold()
1  | 
  | 
- 
src:源图像,可以为 8 位的灰度图,也可以为 32 位的彩色图像。 - 
dst:输出图像。 - 
thresh:阈值。 - 
maxval:dst 中的最大值。 - 
type:阈值类型,包含:1
2
3
4
5
6
7
8cv::THRESH_BINARY // 二值化
cv::THRESH_BINARY_INV // 二值化
cv::THRESH_TRUNC
cv::THRESH_TOZERO
cv::THRESH_TOZERO_INV
cv::THRESH_MASK
cv::THRESH_OTSU // 使用 OTSU 算法选择最佳阈值
cv::THRESH_TRIANGLE // 使用 Triangle 算法选择最佳阈值 - 
ref:https://blog.csdn.net/u012566751/article/details/77046445
 
3. 判断点是否在多边形(轮廓)内
1  | 
  | 
contour:类型为vector<cv::Point>,即多边形的轮廓。pt:需要判断的点。measureDist:设置为 true 时,返回值为点到最近的多边形轮廓的距离,若返回正值,则表示点在多边形内部;若返回负值,则点在多边形外部;若返回 0,则点在多边形上。设置为 false 时,若返回值为 +1,则表示点在多边形内部;返回值为 -1,点在多边形外;返回 0,点在多边形上。
4. 图像的条件复制
1  | 
  | 
m:目标矩阵,如果源矩阵和目标矩阵大小不同,则重新分配目标矩阵的大小。mask:和源矩阵大小相同,其中非零元素的坐标表示源图像中需要被复制到目标图像的像素坐标。类型应为CV_8U,可以有 1 个或多个通道。
5. 计算本质矩阵
5.1 本质矩阵-1
1  | 
  | 
points1:从第一张图像来的 个 2D 点,点坐标为浮点数。points2:与points1相同格式和数量的第二张图像的 2D 点。cameraMatrix:相机内参矩阵。函数假设points1和points2为来自同一相机内参的特征点。method:计算本质矩阵的方法:cv::RANSACcv::LMEDS
prob:用于 RANSAC 法和 LMedS 法,表示预期计算得到的矩阵的置信度。threshold:用于 RANSAC 法的参数,表示点到极线到像素距离阈值,如果大于此值,则点被视为离群点,通常设为 1.0 - 3.0。maxIters:最大迭代次数。mask:输出 个元素,每个元素对应一个点是否为离群点,是则值为 0,否则值为 1。用于 RANSAC 法和 LMedS 法。
5.2 本质矩阵-2
1  | cv::Mat cv::findEssentialMat(  | 
- 重载函数,仅与第一个函数的参数不同,即不手动设置迭代最大上限。
 
5.3 本质矩阵-3
1  | cv::Mat cv::findEssentialMat(  | 
- 
focal:相机焦距,此函数假设points1和points2来自同意相机焦距和原点。 - 
pp:相机原点。 - 
根据上述参数计算相机内参:
 - 
其他参数同上。
 
5.4 本质矩阵-4
1  | cv::Mat cv::findEssentialMat(  | 
- 前一函数的重载,不手动设置迭代最大上限。
 
5.5 本质矩阵-5
1  | cv::Mat cv::findEssentialMat(  | 
- 函数计算来自两个不同相机的图像间的本质矩阵。
 distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。
5.6 本质矩阵-6
1  | cv::Mat cv::findEssentialMat(  | 
- 前一函数的重载。
 
6. 计算基础矩阵
6.1 基础矩阵-1
1  | 
  | 
points1:从第一张图像来的 个 2D 点,点坐标为浮点数。points2:与points1相同格式和数量的第二张图像的 2D 点。method:计算基础矩阵的方法:cv::FM_7POINT:7 点法,;cv::FM_8POINT:8 点法,;cv::RANSACcv::LEMDS
ransacReprohThreshold:用于 RANSAC 法的参数,表示点到极线到像素距离阈值,如果大于此值,则点被视为离群点,通常设为 1.0 - 3.0。confidence:用于 RANSAC 法和 LMedS 法,表示预期计算得到的矩阵的置信度。maxIters:最大迭代次数。mask:优化的输出掩码。
6.2 基础矩阵-2
1  | cv::Mat findFundamentalMat(  | 
- 前一函数的重载函数,不手动设置最大迭代次数。
 
6.3 基础矩阵-3
1  | cv::Mat findFundamentalMat(  | 
- 前一函数的重载函数,
mask为必传参数。 
6.4 基础矩阵-4
1  | cv::Mat findFundamentalMat(  | 
- 前一函数的重载函数。
 
7. 单应矩阵
7.1 单应矩阵-1
1  | 
  | 
- 
srcPoints:从源图像来的点,是一个类型为cv::CV_32FC2的矩阵或vector<cv::Point2f>的向量。 - 
dstPoints:来自目标图像的点,类型同上。 - 
method:计算单应矩阵的方法:- 
0:使用所有点通过最小二乘法计算。
 - 
cv::RANSAC - 
cv::LMEDS - 
cv::RHO 
 - 
 - 
ransacReprojThreshold:判断点为内点(inlier)的最大重投影误差,即如果则第 个点为离群点。如果特征点为像素坐标,则通常值设为 1.0 - 10.0。
 - 
confidence:预期计算得到的矩阵的置信度。 - 
maxIters:最大迭代次数。 - 
mask:输出 个元素,每个元素对应一个点是否为离群点,是则值为 0,否则值为 1。用于 RANSAC 法和 LMedS 法。 
7.2 单应矩阵-2
1  | cv::Mat cv::findHomographyMat(  | 
- 前一函数的重载函数。
 
7.3 单应矩阵-3
1  | cv::Mat cv::findHomographyMat(  | 
- 重载函数。
 
8. 本质矩阵进行位姿求解
8.1 本质矩阵求解位姿-1
1  | 
  | 
points1:从第一张图像来的 个 2D 点,点坐标为浮点数。points2:与points1相同格式和数量的第二张图像的 2D 点。cameraMatrix:相机内参矩阵。函数假设图像来自两个不同的相机。distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。E:输出的本质矩阵。R:输出的旋转矩阵,结果表述为 ,即将第 2 张图像的相机坐标转为第 1 张图像的相机坐标。t:输出的平移向量,结果表述为 。method:计算本质矩阵的方法:cv::RANSACcv::LMEDS
prob:用于 RANSAC 法和 LMedS 法,表示预期计算得到的矩阵的置信度。threshold:用于 RANSAC 法的参数,表示点到极线到像素距离阈值,如果大于此值,则点被视为离群点,通常设为 1.0 - 3.0。maxIters:最大迭代次数。mask:作为输入如果非空,则标识了根据输入本质矩阵所规定的points1和points2中的内点(inliers),只有这些点参与求解位姿。输出 个元素,每个元素对应一个点是否为离群点,是则值为 0,否则值为 1。用于 RANSAC 法和 LMedS 法。
8.2 本质矩阵求解位姿-2
1  | int cv::recoverPose(  | 
- 根据给定的本质矩阵求解位姿。
 E:输入的本质矩阵。points1:从第一张图像来的 个 2D 点,点坐标为浮点数。points2:与points1相同格式和数量的第二张图像的 2D 点。cameraMatrix:相机内参矩阵。函数假设图像来自相同的相机。R:输出的旋转矩阵,结果表述为 ,即将第 2 张图像的相机坐标转为第 1 张图像的相机坐标。t:输出的平移向量,结果表述为 。method:计算本质矩阵的方法:cv::RANSACcv::LMEDS
mask:作为输入如果非空,则标识了根据输入本质矩阵所规定的points1和points2中的内点(inliers),只有这些点参与求解位姿。输出 个元素,每个元素对应一个点是否为离群点,是则值为 0,否则值为 1。用于 RANSAC 法和 LMedS 法。
8.3 本质矩阵求解位姿-3
1  | int cv::recoverPose(  | 
- 前一函数的重载函数,利用给定的参数计算相机内参矩阵:
 
8.4 本质矩阵求解位姿-4
1  | int cv::recoverPose(  | 
distanceThresh:用于过滤距离过远的点。triangulatedPoints:三角化求解得到的 3D 点。
9. PnP
9.1 普通 PnP
1  | 
  | 
- 
objectPoints:对象坐标系下的点,大小为 或 。通常可以可以使用vector<cv::Point3d>。 - 
imagePoints:对应的相机坐标系下的图像点,大小为 或 。通常可以可以使用vector<cv::Point2d>。 - 
cameraMatrix:相机内参矩阵。 - 
distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。 - 
rvec:输出旋转矩阵对应的旋转向量,将对象坐标系下的点转为相机坐标系。使用下方法转为矩阵形式:1
2
3
4
5
6
7
void cv::Rodrigues(
InputArray src, // 旋转向量
OutputArray dst, // 旋转矩阵
OutputArray jacobian = cv::NoArray()
);jacobian:可选输出的雅可比矩阵,大小为 或 ,表示输出矩阵相对输入向量的部分导。 - 
tvec:输出的位姿的平移向量部分。 - 
useExtrinsicGuess:用于cv::SOLVEPNP_ITERATIVE的参数,若为 true,则用给定的旋转和初始值进行优化求解。 - 
flags:求解 PnP 问题的方式:1
2
3
4
5
6
7
8
9cv::SOLVEPNP_ITERATIVE
cv::SOLVEPNP_P3P
cv::SOLVEPNP_AP3P
cv::SOLVEPNP_EPNP
cv::SOLVEPNP_DLS
cv::SOLVEPNP_IPPE
cv::SOLVEPNP_IPPE_SQUARE
cv::SOLVEPNP_UPNP
cv::SOLVEPNP_SQPNP 
9.2 通用算法求解 PnP
1  | 
  | 
- 
objectPoints:对象坐标系下的点,大小为 或 。通常可以可以使用vector<cv::Point3d>。 - 
imagePoints:对应的相机坐标系下的图像点,大小为 或 。通常可以可以使用vector<cv::Point2d>。 - 
cameraMatrix:相机内参矩阵。 - 
distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。 - 
rvecs:输出旋转矩阵对应的旋转向量,将对象坐标系下的点转为相机坐标系。使用下方法转为矩阵形式:1
2
3
4
5
6
7
void cv::Rodrigues(
InputArray src, // 旋转向量
OutputArray dst, // 旋转矩阵
OutputArray jacobian = cv::NoArray()
);jacobian:可选输出的雅可比矩阵,大小为 或 ,表示输出矩阵相对输入向量的部分导。 - 
tvecs:输出的位姿的平移向量部分。 - 
useExtrinsicGuess:用于cv::SOLVEPNP_ITERATIVE的参数,若为 true,则用给定的旋转和初始值进行优化求解。 - 
flags:求解 PnP 问题的方式:1
2
3
4
5
6
7
8
9cv::SOLVEPNP_ITERATIVE
cv::SOLVEPNP_P3P
cv::SOLVEPNP_AP3P
cv::SOLVEPNP_EPNP
cv::SOLVEPNP_DLS
cv::SOLVEPNP_IPPE
cv::SOLVEPNP_IPPE_SQUARE
cv::SOLVEPNP_UPNP
cv::SOLVEPNP_SQPNP - 
rvec:当使用cv::SOLVEPNP_ITERATIVE且useExtrinsicGuess = true时的迭代初始旋转向量。 - 
tvec:当使用cv::SOLVEPNP_ITERATIVE且useExtrinsicGuess = true时的迭代初始平移向量。 - 
reprojectionError:根据求解得到的位姿计算得到的图像点和 3D 对象点的重投影 RMS 误差。 
9.3 RANSAC 法求解 PnP
9.3.1 RANSAC 法-1
1  | 
  | 
- 
objectPoints:对象坐标系下的点,大小为 或 。通常可以可以使用vector<cv::Point3d>。 - 
imagePoints:对应的相机坐标系下的图像点,大小为 或 。通常可以可以使用vector<cv::Point2d>。 - 
cameraMatrix:相机内参矩阵。 - 
distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。 - 
rvec:输出旋转矩阵对应的旋转向量,将对象坐标系下的点转为相机坐标系。使用下方法转为矩阵形式:1
2
3
4
5
6
7
void cv::Rodrigues(
InputArray src, // 旋转向量
OutputArray dst, // 旋转矩阵
OutputArray jacobian = cv::NoArray()
);jacobian:可选输出的雅可比矩阵,大小为 或 ,表示输出矩阵相对输入向量的部分导。 - 
tvec:输出的位姿的平移向量部分。 - 
useExtrinsicGuess:用于cv::SOLVEPNP_ITERATIVE的参数,若为 true,则用给定的旋转和初始值进行优化求解。 - 
iterationsCount:迭代次数。 - 
reprojectionError:用于 RANSAC 法的参数,表示点到极线到像素距离阈值,如果大于此值,则点被视为离群点。 - 
confidence:用于 RANSAC 法,表示预期计算得到的矩阵的置信度。 - 
inliers:输出包含objectPoints和imagePoints的内点(inliers)的索引向量。 - 
flags:求解 PnP 问题的方式:1
2
3
4
5
6
7
8
9cv::SOLVEPNP_ITERATIVE
cv::SOLVEPNP_P3P
cv::SOLVEPNP_AP3P
cv::SOLVEPNP_EPNP
cv::SOLVEPNP_DLS
cv::SOLVEPNP_IPPE
cv::SOLVEPNP_IPPE_SQUARE
cv::SOLVEPNP_UPNP
cv::SOLVEPNP_SQPNP 
9.3.2 RANSAC 法-2
1  | bool cv::solvePnPRansac(  | 
- 前一函数的重载函数。
 
9.4 RefineLM 法求解 PnP
1  | 
  | 
- 
objectPoints:对象坐标系下的点,大小为 或 。通常可以可以使用vector<cv::Point3d>。 - 
imagePoints:对应的相机坐标系下的图像点,大小为 或 。通常可以可以使用vector<cv::Point2d>。 - 
cameraMatrix:相机内参矩阵。 - 
distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。 - 
rvec:输出旋转矩阵对应的旋转向量,将对象坐标系下的点转为相机坐标系。使用下方法转为矩阵形式:1
2
3
4
5
6
7
void cv::Rodrigues(
InputArray src, // 旋转向量
OutputArray dst, // 旋转矩阵
OutputArray jacobian = cv::NoArray()
);jacobian:可选输出的雅可比矩阵,大小为 或 ,表示输出矩阵相对输入向量的部分导。 - 
tvec:输出的位姿的平移向量部分。 - 
criteria:结束 LM 迭代法的标准。 
9.5 RefineVVS 法求解 PnP
1  | 
  | 
- 
objectPoints:对象坐标系下的点,大小为 或 。通常可以可以使用vector<cv::Point3d>。 - 
imagePoints:对应的相机坐标系下的图像点,大小为 或 。通常可以可以使用vector<cv::Point2d>。 - 
cameraMatrix:相机内参矩阵。 - 
distCoeffs:畸变系数,为 4、5、8、12 和 14 元素的向量(),若向量为空(NULL),则为 0 畸变。 - 
rvec:输出旋转矩阵对应的旋转向量,将对象坐标系下的点转为相机坐标系。使用下方法转为矩阵形式:1
2
3
4
5
6
7
void cv::Rodrigues(
InputArray src, // 旋转向量
OutputArray dst, // 旋转矩阵
OutputArray jacobian = cv::NoArray()
);jacobian:可选输出的雅可比矩阵,大小为 或 ,表示输出矩阵相对输入向量的部分导。 - 
tvec:输出的位姿的平移向量部分。 - 
criteria:结束 LM 迭代法的标准。 - 
VVSlambda:等价于阻尼高斯-牛顿法中的 增益。 
10. DNN 的使用
1  | 
  | 
 10.1  forward() 的调用
1  | cv::Mat cv::dnn::Net::forward(  | 
- 返回网络 
outputName层的第一个输出。 
1  | void cv::dnn::Net::forward(  | 
outputBlobs:包含特定层的所有输出。outputName:需要获取输出的输出层名。
1  | void cv::dnn::Net::forward(  | 
outputBlobs:包含特定层的第一个输出。outputNames:需要获取输出的几个输出层名。
1  | void cv::dnn::Net::forward(  | 
outputBlobs:包含特定层的所有输出。outputNames:需要获取输出的几个输出层名。