最近在看霍夫变换,觉得网上的大多文章都晦涩难懂,甚至错漏百出,所以在弄懂之后决定自己写一篇。
对于直线检测来说, 所谓的霍夫变换可以理解为一种映射关系,(theta, r)与直线 y = kx + b的映射关系。且这种映射为一对一的映射。
下面来说明(theta, r)与直线的映射关系。
如上图所示,每一条直线都有一条过笛卡尔坐标系坐标原点的垂线,且对于每条直线来说,这条垂线是唯一的,而这条垂线,我们就用(theta, r)来表示,其中theta为该垂线与x轴所成的夹角,r 为该垂线的长度(原点到直线的距离)。反之,当给定垂线时,直线也是唯一的,因为它确定了直线必过的一个点以及直线的斜率(已知直线上一点(x, y)和k, 则可求出b,k和b唯一即直线唯一)。
好了,上面是背景,说明了可以用(theta,r)唯一表示一条直线,下面讲怎么利用这个关系在图像里面提取直线。
假设我在坐标系中找到了3个点,我想知道这三个点能确定几条直线。初中数学的做法是先任意选两个点确定一条直线,再判断第三个点是否在这条直线上。如果在,说明三个点共线,不在说明三个点两两确定了3条直线。
对于坐标系中的一个点,过该点的直线有无数条,我们每隔30度取一条直线(具体如何取样自己根据实际情况确定),近似认为代表了过该点的所有直线,且每条直线唯一对应一个(theta, r)。对于三个点来说,若三个点同时拥有同一个(theta, r),则代表有一条直线同时经过这三个点。
说白了就是分别把过三个点的所有直线算一遍,如果过三个点的所有直线有一样的,就说明有一条直线同时过这三个点了·······看完有没有觉得这个方法也···emmm···你懂的···
至于为啥用(theta, r)而不是斜率k和截距b来表示一条直线,是因为利用y = kx + b来表示直线时,存在斜率k无穷大的情况,无法计算。并且theta为0到2*pi, 且对于直线来说r一定小于等于b,所以计算的数值也相对较小。
下面来说明(theta, r)与直线的映射关系。
如上图所示,每一条直线都有一条过笛卡尔坐标系坐标原点的垂线,且对于每条直线来说,这条垂线是唯一的,而这条垂线,我们就用(theta, r)来表示,其中theta为该垂线与x轴所成的夹角,r 为该垂线的长度(原点到直线的距离)。反之,当给定垂线时,直线也是唯一的,因为它确定了直线必过的一个点以及直线的斜率(已知直线上一点(x, y)和k, 则可求出b,k和b唯一即直线唯一)。
好了,上面是背景,说明了可以用(theta,r)唯一表示一条直线,下面讲怎么利用这个关系在图像里面提取直线。
假设我在坐标系中找到了3个点,我想知道这三个点能确定几条直线。初中数学的做法是先任意选两个点确定一条直线,再判断第三个点是否在这条直线上。如果在,说明三个点共线,不在说明三个点两两确定了3条直线。
对于坐标系中的一个点,过该点的直线有无数条,我们每隔30度取一条直线(具体如何取样自己根据实际情况确定),近似认为代表了过该点的所有直线,且每条直线唯一对应一个(theta, r)。对于三个点来说,若三个点同时拥有同一个(theta, r),则代表有一条直线同时经过这三个点。
说白了就是分别把过三个点的所有直线算一遍,如果过三个点的所有直线有一样的,就说明有一条直线同时过这三个点了·······看完有没有觉得这个方法也···emmm···你懂的···
至于为啥用(theta, r)而不是斜率k和截距b来表示一条直线,是因为利用y = kx + b来表示直线时,存在斜率k无穷大的情况,无法计算。并且theta为0到2*pi, 且对于直线来说r一定小于等于b,所以计算的数值也相对较小。