muh*_* uk 3 opencv image-processing convex-hull convexity-defects
OpenCV函数中convexityDefects()用于计算轮廓的凸度缺陷的算法是什么?
请描述和说明该算法的高级操作,以及其输入和输出。
根据文档,输入是两个坐标列表:
contour 定义原始轮廓(下图为红色)convexhull 定义与该轮廓相对应的凸包(下图为蓝色)该算法以以下方式工作:
如果轮廓线或船体包含少于3个点,则轮廓线始终是凸形的,不需要进行更多处理。该算法可确保以相同方向访问轮廓和船体。
注意:在进一步的解释中,我假定它们的方向相同,并且忽略了有关将浮点深度表示为整数的详细信息。
然后,对于每对相邻的船体的点(H[i],H[i+1]),限定所述凸包的一个边缘,计算轮廓上的每个点从边缘的距离C[n]即之间谎言H[i]和H[i+1](不包括C[n] == H[i+1])。如果距离大于零,则存在缺陷。存在缺陷时,记录i,,i+1最大距离和n最大位置所在的轮廓点的索引()。
距离的计算方法如下:
dx0 = H[i+1].x - H[i].x
dy0 = H[i+1].y - H[i].y
if (dx0 is 0) and (dy0 is 0) then
scale = 0
else
scale = 1 / sqrt(dx0 * dx0 + dy0 * dy0)
dx = C[n].x - H[i].x
dy = C[n].y - H[i].y
distance = abs(-dy0 * dx + dx0 * dy) * scale
Run Code Online (Sandbox Code Playgroud)
就矢量而言,可能更容易可视化:
C:缺陷向量从H[i]到C[n]H:从H[i]到的船体边缘向量H[i+1]H_rot:船体边缘矢量H旋转90度U_rot:方向的单位向量 H_rotH分量是[dx0, dy0],所以旋转90度会给出[-dy0, dx0]。
scale是用来寻找U_rot从H_rot,但由于分歧比乘法更昂贵的计算,逆用作优化。在循环结束之前也会对其进行预先计算,C[n]以避免重新计算每次迭代。
| H| = sqrt(dx0 * dx0 + dy0 * dy0)
U_rot = H_rot/ | H| = H_rot*scale
然后,之间的点积C和U_rot给出从缺陷点到船体边缘的垂直距离,和abs()用于获取在任何方向的正幅值。
距离= abs(U_rot。C)= abs(-dy0 * dx + dx0 * dy)*比例
在上图所示的场景中,在第一次迭代中,边由H[0]和定义H[1]。寿审查该边缘轮廓点C[0],C[1]和C[2](自C[3] == H[1])。
C[1]和处都有缺陷C[2]。处的缺陷C[1]最深,因此算法将记录下来(0, 1, 1, 50)。
下一条边由H[1]和H[2]以及相应的轮廓点定义C[3]。没有缺陷,因此没有任何记录。
下一条边由H[2]和H[3]以及相应的轮廓点定义C[4]。没有缺陷,因此没有任何记录。
由于C[5] == H[3],最后一个轮廓点可以忽略-那里没有缺陷。