slope estimation(곡선 길이 및 곡률 계산)
13 Jan 2022 | Machine Vision
with curavture, we are able to define an angle of a slope plane. the way to do is using plane parameter can get curvature.
the other one to detemine a slope plane,
set one vertical line and dot product normal vector, can define a angle of plane.
Consider a car driving along a curvy road. The tighter the curve, the more difficult the driving is. In math we have a number, the curvature, that describes this “tightness”. If the curvature is zero then the curve looks like a line near this point. While if the curvature is a large number, then the curve has a sharp bend.
Normal vector마다 곡률을 구할 수 있느데, 한번 해보자
2d case
Fomular
k(t) = (x'y'' - x''y') / (x' * x' + y' * y')^(3/2)
Eigen::MatrixXf m(2,7);
m = [[1,1],[1.5,2],[2,3],[2.5,3.5],[3,4],[3.5,4.25],[4,4.5]]; //원래는 블라캣이다.
Eigen::Vector2f Gradient(7);
// Step 1 : Gradient(vector)
for(int idx = 0; idx < m.cols()-1; idx++)
{
Gradient[idx] = m.col(idx)-m.col(idx+1);
// Gradient stored result
// [[0.5 1. ]
// [0.5 1. ]
// [0.5 0.75 ]
// [0.5 0.5 ]
// [0.5 0.375]
// [0.5 0.25 ]
// [0.5 0.25 ]]
}
// Step 2 : 곡률 길이
std::vector<float> distance(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
distance(idx) = sqrt(Gradient[idx].x() * Gradient[idx].x() + Gradient[idx].y() * Gradient[idx].y());
// distance result
// [1.11803399 1.11803399 0.90138782 0.70710678 0.625 0.55901699
// 0.55901699]
}
// Step 3: 벡터들에 대한 탄젠트 계산하기
Eigen::Vector2f Tangent(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Tangent[idx].x() = Gradient[idx].x() / distance(idx);
Tangent[idx].y() = Gradient[idx].y() / distance(idx);
}
// STEP 4: 탄젠트의 구성요소를 분리하고 기울기를 계산하여 법선 벡터를 찾는다.
std::vector<float> Gradient_distance(7)
Eigen::Vector2f G_Gradient(7);
for(int idx = 0; idx < Gradient.size()-1; idx++)
{
Gradient_distance[idx] = distance[idx] - distance[idx+1];
G_Gradient[idx] = Gradient[idx] - Gradient[idx+1];
}
// STEP 5 : estimation Curve Rate of Vector
std::vector<float> curvature(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
curavture[idx] = abs(G_Gradient.x() * Gradient.y() - Gradient.x() * G_Gradient.y())/((Gradient.x() * Gradient.x() + Gradient.y() * Gradient.y())**1.5);
// Curvature Result
// [0. 0.04472136 0.17067698 0.26516504 0.256 0.17888544
// 0. ]
}
3D Case
https://www.youtube.com/watch?v=NlcvU67YWpQ
Fomular
r'(t).cross(r''(t))= A;
k(t) = (sqrt(A.dot(A))) / (sqrt(r'.dot(r'))^3
Eigen::MatrixXf m(3,7);
m = [[1,1,1],[1.5,2,2],[2,3,3],[2.5,3.5,4],[3,4,5],[3.5,4.25,6],[4,4.5,7]]; //원래는 블라캣이다.
Eigen::Vector3f Gradient(7);
// Step 1 : Gradient(vector)
for(int idx = 0; idx < m.cols()-1; idx++)
{
Gradient[idx] = m.col(idx)-m.col(idx+1); // r'(t)
// Gradient stored result
// [[0.5 1. , 1]
// [0.5 1. , 1]
// [0.5 0.75 , 0.75]
// [0.5 0.5 , 0.5]
// [0.5 0.375, 0.375]
// [0.5 0.25 , 0.25]
// [0.5 0.25 , 0.25]]
}
// Step 2 : 곡률 길이
std::vector<float> distance(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
distance(idx) = sqrt(Gradient[idx].x() * Gradient[idx].x() + Gradient[idx].y() * Gradient[idx].y() + Gradient[idx].z() * Gradient[idx].z());
// distance result
// [1.5 1.5 1,17260394 0.8660254038 0.7288689869 0.6123724357
// 0.6123724357]
}
// Step 3: 벡터들에 대한 탄젠트 계산하기
Eigen::Vector3f Tangent(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Tangent[idx].x() = Gradient[idx].x() / distance(idx);
Tangent[idx].y() = Gradient[idx].y() / distance(idx);
Tangent[idx].z() = Gradient[idx].z() / distance(idx);
}
// STEP 4: 탄젠트의 구성요소를 분리하고 기울기를 계산하여 법선 벡터를 찾는다.
std::vector<float> Gradient_distance(7)
Eigen::Vector3f G_Gradient(7);
for(int idx = 0; idx < Gradient.size()-1; idx++)
{
Gradient_distance[idx] = distance[idx] - distance[idx+1];
G_Gradient[idx] = Gradient[idx] - Gradient[idx+1];
}
// STEP 5 : estimation Curve Rate of Vector
std::vector<float> curvature(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Eigen::Vector3f Temp_Normal_vector;
Temp_Normal_vector = Gradient[idx].cross(G_Gradient[idx]);
curavture[idx] = sqrt(Temp_Normal_vector.dot(Temp_Normal_vector))/(sqrt(Gradient[idx].dot(Gradient[idx])))**3;
// Curvature Result
// [0. 0.04472136 0.17067698 0.26516504 0.256 0.17888544
// 0. ]
}
slope를 구할때도 많이 쓰이며, lidar에서는 포인트 클라우드 Feature Extraction을 위해 사용이 된다.
참고자료
about 2D
https://www.delftstack.com/ko/howto/numpy/curvature-formula-numpy/
all about curavture
https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Vector_Calculus/2%3A_Vector-Valued_Functions_and_Motion_in_Space/2.3%3A_Curvature_and_Normal_Vectors_of_a_Curve
https://openstax.org/books/calculus-volume-3/pages/3-3-arc-length-and-curvature
with curavture, we are able to define an angle of a slope plane. the way to do is using plane parameter can get curvature.
the other one to detemine a slope plane,
set one vertical line and dot product normal vector, can define a angle of plane.
Consider a car driving along a curvy road. The tighter the curve, the more difficult the driving is. In math we have a number, the curvature, that describes this “tightness”. If the curvature is zero then the curve looks like a line near this point. While if the curvature is a large number, then the curve has a sharp bend.
Normal vector마다 곡률을 구할 수 있느데, 한번 해보자
2d case
Fomular
k(t) = (x'y'' - x''y') / (x' * x' + y' * y')^(3/2)
Eigen::MatrixXf m(2,7);
m = [[1,1],[1.5,2],[2,3],[2.5,3.5],[3,4],[3.5,4.25],[4,4.5]]; //원래는 블라캣이다.
Eigen::Vector2f Gradient(7);
// Step 1 : Gradient(vector)
for(int idx = 0; idx < m.cols()-1; idx++)
{
Gradient[idx] = m.col(idx)-m.col(idx+1);
// Gradient stored result
// [[0.5 1. ]
// [0.5 1. ]
// [0.5 0.75 ]
// [0.5 0.5 ]
// [0.5 0.375]
// [0.5 0.25 ]
// [0.5 0.25 ]]
}
// Step 2 : 곡률 길이
std::vector<float> distance(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
distance(idx) = sqrt(Gradient[idx].x() * Gradient[idx].x() + Gradient[idx].y() * Gradient[idx].y());
// distance result
// [1.11803399 1.11803399 0.90138782 0.70710678 0.625 0.55901699
// 0.55901699]
}
// Step 3: 벡터들에 대한 탄젠트 계산하기
Eigen::Vector2f Tangent(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Tangent[idx].x() = Gradient[idx].x() / distance(idx);
Tangent[idx].y() = Gradient[idx].y() / distance(idx);
}
// STEP 4: 탄젠트의 구성요소를 분리하고 기울기를 계산하여 법선 벡터를 찾는다.
std::vector<float> Gradient_distance(7)
Eigen::Vector2f G_Gradient(7);
for(int idx = 0; idx < Gradient.size()-1; idx++)
{
Gradient_distance[idx] = distance[idx] - distance[idx+1];
G_Gradient[idx] = Gradient[idx] - Gradient[idx+1];
}
// STEP 5 : estimation Curve Rate of Vector
std::vector<float> curvature(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
curavture[idx] = abs(G_Gradient.x() * Gradient.y() - Gradient.x() * G_Gradient.y())/((Gradient.x() * Gradient.x() + Gradient.y() * Gradient.y())**1.5);
// Curvature Result
// [0. 0.04472136 0.17067698 0.26516504 0.256 0.17888544
// 0. ]
}
3D Case
https://www.youtube.com/watch?v=NlcvU67YWpQ
Fomular
r'(t).cross(r''(t))= A;
k(t) = (sqrt(A.dot(A))) / (sqrt(r'.dot(r'))^3
Eigen::MatrixXf m(3,7);
m = [[1,1,1],[1.5,2,2],[2,3,3],[2.5,3.5,4],[3,4,5],[3.5,4.25,6],[4,4.5,7]]; //원래는 블라캣이다.
Eigen::Vector3f Gradient(7);
// Step 1 : Gradient(vector)
for(int idx = 0; idx < m.cols()-1; idx++)
{
Gradient[idx] = m.col(idx)-m.col(idx+1); // r'(t)
// Gradient stored result
// [[0.5 1. , 1]
// [0.5 1. , 1]
// [0.5 0.75 , 0.75]
// [0.5 0.5 , 0.5]
// [0.5 0.375, 0.375]
// [0.5 0.25 , 0.25]
// [0.5 0.25 , 0.25]]
}
// Step 2 : 곡률 길이
std::vector<float> distance(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
distance(idx) = sqrt(Gradient[idx].x() * Gradient[idx].x() + Gradient[idx].y() * Gradient[idx].y() + Gradient[idx].z() * Gradient[idx].z());
// distance result
// [1.5 1.5 1,17260394 0.8660254038 0.7288689869 0.6123724357
// 0.6123724357]
}
// Step 3: 벡터들에 대한 탄젠트 계산하기
Eigen::Vector3f Tangent(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Tangent[idx].x() = Gradient[idx].x() / distance(idx);
Tangent[idx].y() = Gradient[idx].y() / distance(idx);
Tangent[idx].z() = Gradient[idx].z() / distance(idx);
}
// STEP 4: 탄젠트의 구성요소를 분리하고 기울기를 계산하여 법선 벡터를 찾는다.
std::vector<float> Gradient_distance(7)
Eigen::Vector3f G_Gradient(7);
for(int idx = 0; idx < Gradient.size()-1; idx++)
{
Gradient_distance[idx] = distance[idx] - distance[idx+1];
G_Gradient[idx] = Gradient[idx] - Gradient[idx+1];
}
// STEP 5 : estimation Curve Rate of Vector
std::vector<float> curvature(7);
for(int idx = 0; idx < Gradient.size(); idx++)
{
Eigen::Vector3f Temp_Normal_vector;
Temp_Normal_vector = Gradient[idx].cross(G_Gradient[idx]);
curavture[idx] = sqrt(Temp_Normal_vector.dot(Temp_Normal_vector))/(sqrt(Gradient[idx].dot(Gradient[idx])))**3;
// Curvature Result
// [0. 0.04472136 0.17067698 0.26516504 0.256 0.17888544
// 0. ]
}
slope를 구할때도 많이 쓰이며, lidar에서는 포인트 클라우드 Feature Extraction을 위해 사용이 된다.
참고자료
about 2D
https://www.delftstack.com/ko/howto/numpy/curvature-formula-numpy/
all about curavture
https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Vector_Calculus/2%3A_Vector-Valued_Functions_and_Motion_in_Space/2.3%3A_Curvature_and_Normal_Vectors_of_a_Curve
https://openstax.org/books/calculus-volume-3/pages/3-3-arc-length-and-curvature
Comments