SlideShare a Scribd company logo
1 of 7
Download to read offline
培训任务一
I. 前言
此任务的难度会比原来高一些,因为我认为现在的视觉组需要的不是调opencv库的人 或
是 调试员。所以我希望新人可以掌握以下能力:
OpenCV 基本用法:主要集中在:
core.hpp(数据类型 / Mat)
highgui.hpp(窗口生成)
imgproc.hpp(图形绘制)
Eigen库基本用法
Matrix<Type, row, col> 的相关操作,如norm/dot/cWiseAbs等等
个人认为,这个任务可以帮助新人接触一些有一定数学性的代码,对之后的研发工作有
好处。
线性代数(向量操作为主)
多种情况的考虑,逻辑需要很完备(之后会提到)
II. 预备知识
DF(Distance Field)距离场 / SDF (Signed Distance Field) 有向距离场
可以说,SDF/DF(Distance Field 距离场)的理解与理解灯条优化算法有非常多的联
系之处。灯条模型实际上就是一个线段的距离场(虽然我以前也不知道这个概念)。
2.1 Distance Field
灯条模型V4版本就是线段距离场的变体(使用sigmoid对DF进行了非线性变换)。空间
中一个点到一个 线段(注意不是直线,所以有端点效应)的最短距离,形成一个场。空间
中每一个点都有这样一个值。如下图所示:
Figure 1. 线段DF示意图
生成这个图片的代码非常简单:
import matplotlib.pyplot as plt
import numpy as np
def distanceField(sp, ep):
   brx, bry = ep + np.array([25, 25])
   direct = (ep - sp).astype(np.float64)
   direct /= np.linalg.norm(direct)
   result = np.zeros((bry, brx))
   for i in range(bry):
       for j in range(brx):
           s2p = (np.array([j, i]) - sp).astype(np.float64)
           e2p = (np.array([j, i]) - ep).astype(np.float64)
           over_e = (e2p.dot(direct) >= 0)
           over_s = (s2p.dot(direct) <= 0)
           positive = (s2p.dot(normal) > 0)
           dist = 0.0
           if (over_e == False and over_s == False):
               dist = np.sqrt(np.linalg.norm(s2p) ** 2 -
(direct.dot(s2p)) ** 2)
           elif (over_e == True):
               dist = np.linalg.norm(e2p)
           else:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
具体就不细说了,看Python代码很好懂。做的就是求最小距离的事情。
2.2 Signed Distance Field
很多时候,单纯的DF还满足不了要求。有的时候,我们需要判定一个点是否在一个封闭
图形的 内外,或者是,一个点是否在某段有向曲线 / 折线的其中一边,DF是没有内外 / 方向
信息的。一个非常简单的例子就是:单位圆的SDF数学表达式:
上式可以得到,在圆的内部,SDF值为负,外部SDF值为正。边界上为0。那么对于线段
而言,其SDF可以通过对2.1中代码的简单修改得到,结果如下图:
               dist = np.linalg.norm(s2p)
           result[i, j] = dist
   return result
def visualization(sp, ep, result):
   img = np.zeros_like(result)
   plt.imshow(result, cmap = 'inferno')
   plt.plot([sp[0], ep[0]], [sp[1], ep[1]], c = 'w')
   plt.colorbar()
   plt.show()
if __name__ == "__main__":
   sp = np.array([25, 18])
   ep = np.array([100, 88])
   res = distanceField(sp, ep)
   visualization(sp, ep, res)
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Figure 2. 线段SDF示意图
依赖库 作用
OpenCV 4 不要再用OpenCV3了 一律换4
Eigen (libeigen3-dev) ROS自带,矩阵计算
OpenMP(可选) SDF是适合并行的
请读者思考一下,为什么会出现不连续的点?(猜一下实现)。
III. 任务要求
3.1 依赖
3.2 任务具体目标
使用上述库实现 折线端的SDF。折线段在此处定义为:
三条线段前后两夹角一个钝角一
个锐角
三条线段前后两夹角一个钝角一
个锐角
首尾射线相交问
题
3.2.1 生成折线段
包含了 四个点,三段线段的折线
此线段的形态有三个要求:
三条线段前后两夹角一个钝角一个锐角
首尾射线不应该相交(比如前两张图,射线没有相交),而第三幅图射线有相交。相交
不是说不可以,只是会比较麻烦。
4个点应该是随机生成的(当然是按照顺序生成四个点,满足以上条件即可)
3.2.2 生成SDF
生成SDF的cv::Mat大小限制为(600,400),也就是说,线段端点不能在外面。并且
注意:
首尾两个端点不可以在图像边界上。
SDF要求是:
求(600,400)大小的Mat中,每个点到折线段的有向距离。
有向距离定义如下:
线段首先有方向,由线段方向定正负,不过所有线段的正负方向定义必须保持一致,
比如p1->p2为线段的方向。一种定义方式如下(可以任意):
Figure 3. 线段以及方向定义
首线段(头部无限延伸) 尾线段(尾部无限延伸)
方向(正负号) * 点到折线段的 最小距离(也就是要找一个距离最近的线段或者点求
距离)。参考Figure 1.跑道形状,特别注意连接处的样子。
特别注意,首尾两端需要特殊处理:由于Figure 2展示了,线段SDF会产生正负号跳
变导致不连续,故首尾两条线段只需要求取 射线的SDF即可,即在某一方向无限延
伸:
首线段:向着线段反方向无限延伸的射线SDF
尾线段:向着线段正方向无线延伸的射线SDF
中间线段:正常,跑道形状的有限SDF
3.2.3 绘制SDF
OpenCV三通道绘制,正负号使用不同的颜色,而颜色的intensity(值大小)对应了距
离。
Figure 4. SDF实际效果
IV. 效果展示
 

More Related Content

Similar to signed distance function

Spark调研串讲
Spark调研串讲Spark调研串讲
Spark调研串讲jie cao
 
密碼學漏洞與他們的產地 Crypto fail and where to find them
密碼學漏洞與他們的產地   Crypto fail and where to find them密碼學漏洞與他們的產地   Crypto fail and where to find them
密碼學漏洞與他們的產地 Crypto fail and where to find themJohn L Chen
 
Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計Wei-Yu Chen
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)Kris Mok
 
深入理解Andorid重难点
深入理解Andorid重难点深入理解Andorid重难点
深入理解Andorid重难点Bin Shao
 
Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)悦 温
 
Hadoop学习总结
Hadoop学习总结Hadoop学习总结
Hadoop学习总结ordinary2012
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closureswang hongjiang
 
C++工程实践
C++工程实践C++工程实践
C++工程实践Shuo Chen
 

Similar to signed distance function (9)

Spark调研串讲
Spark调研串讲Spark调研串讲
Spark调研串讲
 
密碼學漏洞與他們的產地 Crypto fail and where to find them
密碼學漏洞與他們的產地   Crypto fail and where to find them密碼學漏洞與他們的產地   Crypto fail and where to find them
密碼學漏洞與他們的產地 Crypto fail and where to find them
 
Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)
 
深入理解Andorid重难点
深入理解Andorid重难点深入理解Andorid重难点
深入理解Andorid重难点
 
Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)
 
Hadoop学习总结
Hadoop学习总结Hadoop学习总结
Hadoop学习总结
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 
C++工程实践
C++工程实践C++工程实践
C++工程实践
 

signed distance function

  • 1. 培训任务一 I. 前言 此任务的难度会比原来高一些,因为我认为现在的视觉组需要的不是调opencv库的人 或 是 调试员。所以我希望新人可以掌握以下能力: OpenCV 基本用法:主要集中在: core.hpp(数据类型 / Mat) highgui.hpp(窗口生成) imgproc.hpp(图形绘制) Eigen库基本用法 Matrix<Type, row, col> 的相关操作,如norm/dot/cWiseAbs等等 个人认为,这个任务可以帮助新人接触一些有一定数学性的代码,对之后的研发工作有 好处。 线性代数(向量操作为主) 多种情况的考虑,逻辑需要很完备(之后会提到) II. 预备知识 DF(Distance Field)距离场 / SDF (Signed Distance Field) 有向距离场 可以说,SDF/DF(Distance Field 距离场)的理解与理解灯条优化算法有非常多的联 系之处。灯条模型实际上就是一个线段的距离场(虽然我以前也不知道这个概念)。 2.1 Distance Field 灯条模型V4版本就是线段距离场的变体(使用sigmoid对DF进行了非线性变换)。空间 中一个点到一个 线段(注意不是直线,所以有端点效应)的最短距离,形成一个场。空间 中每一个点都有这样一个值。如下图所示:
  • 2. Figure 1. 线段DF示意图 生成这个图片的代码非常简单: import matplotlib.pyplot as plt import numpy as np def distanceField(sp, ep):    brx, bry = ep + np.array([25, 25])    direct = (ep - sp).astype(np.float64)    direct /= np.linalg.norm(direct)    result = np.zeros((bry, brx))    for i in range(bry):        for j in range(brx):            s2p = (np.array([j, i]) - sp).astype(np.float64)            e2p = (np.array([j, i]) - ep).astype(np.float64)            over_e = (e2p.dot(direct) >= 0)            over_s = (s2p.dot(direct) <= 0)            positive = (s2p.dot(normal) > 0)            dist = 0.0            if (over_e == False and over_s == False):                dist = np.sqrt(np.linalg.norm(s2p) ** 2 - (direct.dot(s2p)) ** 2)            elif (over_e == True):                dist = np.linalg.norm(e2p)            else: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  • 3. 具体就不细说了,看Python代码很好懂。做的就是求最小距离的事情。 2.2 Signed Distance Field 很多时候,单纯的DF还满足不了要求。有的时候,我们需要判定一个点是否在一个封闭 图形的 内外,或者是,一个点是否在某段有向曲线 / 折线的其中一边,DF是没有内外 / 方向 信息的。一个非常简单的例子就是:单位圆的SDF数学表达式: 上式可以得到,在圆的内部,SDF值为负,外部SDF值为正。边界上为0。那么对于线段 而言,其SDF可以通过对2.1中代码的简单修改得到,结果如下图:                dist = np.linalg.norm(s2p)            result[i, j] = dist    return result def visualization(sp, ep, result):    img = np.zeros_like(result)    plt.imshow(result, cmap = 'inferno')    plt.plot([sp[0], ep[0]], [sp[1], ep[1]], c = 'w')    plt.colorbar()    plt.show() if __name__ == "__main__":    sp = np.array([25, 18])    ep = np.array([100, 88])    res = distanceField(sp, ep)    visualization(sp, ep, res) 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
  • 4. Figure 2. 线段SDF示意图 依赖库 作用 OpenCV 4 不要再用OpenCV3了 一律换4 Eigen (libeigen3-dev) ROS自带,矩阵计算 OpenMP(可选) SDF是适合并行的 请读者思考一下,为什么会出现不连续的点?(猜一下实现)。 III. 任务要求 3.1 依赖 3.2 任务具体目标 使用上述库实现 折线端的SDF。折线段在此处定义为:
  • 5. 三条线段前后两夹角一个钝角一 个锐角 三条线段前后两夹角一个钝角一 个锐角 首尾射线相交问 题 3.2.1 生成折线段 包含了 四个点,三段线段的折线 此线段的形态有三个要求: 三条线段前后两夹角一个钝角一个锐角 首尾射线不应该相交(比如前两张图,射线没有相交),而第三幅图射线有相交。相交 不是说不可以,只是会比较麻烦。 4个点应该是随机生成的(当然是按照顺序生成四个点,满足以上条件即可) 3.2.2 生成SDF 生成SDF的cv::Mat大小限制为(600,400),也就是说,线段端点不能在外面。并且 注意: 首尾两个端点不可以在图像边界上。 SDF要求是: 求(600,400)大小的Mat中,每个点到折线段的有向距离。 有向距离定义如下: 线段首先有方向,由线段方向定正负,不过所有线段的正负方向定义必须保持一致, 比如p1->p2为线段的方向。一种定义方式如下(可以任意):
  • 6. Figure 3. 线段以及方向定义 首线段(头部无限延伸) 尾线段(尾部无限延伸) 方向(正负号) * 点到折线段的 最小距离(也就是要找一个距离最近的线段或者点求 距离)。参考Figure 1.跑道形状,特别注意连接处的样子。 特别注意,首尾两端需要特殊处理:由于Figure 2展示了,线段SDF会产生正负号跳 变导致不连续,故首尾两条线段只需要求取 射线的SDF即可,即在某一方向无限延 伸: 首线段:向着线段反方向无限延伸的射线SDF 尾线段:向着线段正方向无线延伸的射线SDF 中间线段:正常,跑道形状的有限SDF 3.2.3 绘制SDF OpenCV三通道绘制,正负号使用不同的颜色,而颜色的intensity(值大小)对应了距 离。