边缘检测
参考资料:https://www.jianshu.com/p/2334bee37de5
Sobel 算子
一阶差分
-1, 0, 1
-2, 0, 2
-1, 0, 1
这就是 Sobel 边缘检测算子,偏 x 方向的。(类似二元函数的偏导数,偏x,偏y)。下面是sobel 偏 y 方向的算子。
-1, -2, -1
0, 0, 0
1, 2, 1
分别计算偏 x 方向的 Gx,偏 y 方向的 Gy,求绝对值,压缩到 [0, 255]
区间,即 G(x, y) = Gx + Gy 就是 sobel 边缘检测后的图像了
拉普拉斯算子
拉普拉斯是用二阶差分计算边缘的,看连续函数的情况下
在一阶微分图中极大值或极小值处,认为是边缘。
在二阶微分图中极大值和极小值之间的过 0 点,被认为是边缘。
二维 f '(x, y) = -4 f(x, y) + f(x-1, y) + f(x+1, y) + f(x, y-1) + f(x, y+1),提取模板如下
0, 1, 0
1, -4, 1
0, 1, 0
考虑两个斜对角的情况
1, 1, 1
1, -8, 1
1, 1, 1
Canny 算子
SolvePnP
参考资料:https://blog.csdn.net/cocoaqin/article/details/77848588
单目相机观测的世界是球形的,获得一个平面到相机的距离需要一个平面上的至少3个点,3个点可以确定一个与球形相切的平面。
我们将使用二维码作为标志物,通过二维码四个角点,通过P4P求解相机的位姿及空间坐标。
bool solvePnP(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int flags=ITERATIVE )
objectPoints:特征点的世界坐标,坐标值需为float型,不能为double型,可以为mat类型,也可以直接输入vector
imagePoints:特征点在图像中的像素坐标,可以输入mat类型,也可以直接输入vector,注意输入点的顺序要与前面的特征点的世界坐标一一对应
cameraMatrix:相机内参矩阵
distCoeffs:相机的畸变参数【Mat_(5, 1)】
rvec:输出的旋转向量
tvec:输出的平移矩阵
最后的输入参数有三个可选项:
CV_ITERATIVE,默认值,它通过迭代求出重投影误差最小的解作为问题的最优解。
CV_P3P则是使用非常经典的Gao的P3P问题求解算法。
CV_EPNP使用文章《EPnP: Efficient Perspective-n-Point Camera Pose Estimation》中的方法求解。
霍夫变换
参考资料:https://www.cnblogs.com/php-rearch/p/6760683.html
笛卡尔坐标系中一条直线,对应霍夫空间的一个点。反过来同样成立(霍夫空间的一条直线,对应笛卡尔坐标系的一个点):
笛卡尔A、B两个点,对应霍夫空间的情形:
可以看出如果笛卡尔坐标系的点共线,这些点在霍夫空间对应的直线交于一点:这也是必然,共线只有一种取值可能。
如果不止一条直线呢?再看看多个点的情况(有两条直线):
其实(3,2)与(4,1)也可以组成直线,只不过它有两个点确定,而图中A、B两点是由三条直线汇成,这也是霍夫变换的后处理的基本方式:选择由尽可能多直线汇成的点。看看,霍夫空间:选择由三条交汇直线确定的点(中间图),对应的笛卡尔坐标系的直线(右图)。
到这里问题似乎解决了,已经完成了霍夫变换的求解,但是如果像下图这种情况呢?
k=∞是不方便表示的,而且q怎么取值呢,这样不是办法。因此考虑将笛卡尔坐标系换为:极坐标表示。
在极坐标系下,其实是一样的:极坐标的点→霍夫空间的直线,只不过霍夫空间不再是[k,q]的参数,而是
的参数,给出对比图: