Я хотел бы рассчитать карту глубины формы гауссовой и средней кривизны, чтобы узнать геометрические фигуры, но я не уверен, как это реализовать.
Я рассчитываю гауссову и среднюю кривизну по первой и второй фундаментальной форме.
Сначала я извлекаю трехмерные точки из карты глубины, используя встроенную матрицу камеры.
Затем я вычисляю каждую частную производную и вычисляю первую и вторую фундаментальные формы.
Значение результата для изображений глубины практически равно нулю, даже если поверхность не является плоской. Я учел шум глубинных изображений, поэтому я также попытался использовать модель САПР, форма которой более плавная.
Это правильный способ вычисления гауссовой и средней кривизны? Если у вас есть какие-то советы, пожалуйста, дайте их мне. Спасибо.
Я слежу за PDF http://web.cs.iastate.edu/~cs577/handouts/gaussian-curvature.pdf
Мой код следующий
cv::Mat SampleModelLoader::calculateCurvature(const cv::Mat depthMat)
{
cv::Mat invK = intrinsicMat.inv(); // camera parameter
cv::Mat vertexMat = cv::Mat(cv::Size(width, height), CV_32FC3);
for (int irow = 0; irow < height; ++irow)
{
for (int icol = 0; icol < width; ++icol)
{
cv::Mat pos2D = (cv::Mat_<float>(3, 1) << icol, irow, 1.0f);
float depth = depthMat.at<float>(irow, icol);
cv::Mat pos3D = depth * invK * pos2D;
vertexMat.at<cv::Vec3f>(irow, icol) = cv::Vec3f(
pos3D.at<float>(0, 0),
pos3D.at<float>(1, 0),
pos3D.at<float>(2, 0)
);
}
}
cv::Mat curvatureMat = cv::Mat::zeros(cv::Size(width, height), CV_32FC1);
for (int irow = 1; irow < height-1; ++irow)
{
for (int icol = 1; icol < width-1; ++icol)
{
if (depthMat.at<float>(irow, icol) == 0
|| depthMat.at<float>(irow, icol - 1) == 0
|| depthMat.at<float>(irow, icol + 1) == 0
|| depthMat.at<float>(irow - 1, icol) == 0
|| depthMat.at<float>(irow + 1, icol) == 0
|| depthMat.at<float>(irow + 1, icol + 1) == 0
|| depthMat.at<float>(irow + 1, icol - 1) == 0
|| depthMat.at<float>(irow - 1, icol + 1) == 0
|| depthMat.at<float>(irow - 1, icol - 1) == 0
)
continue;
// partial derivative
cv::Vec3f Xu = cv::normalize(vertexMat.at<cv::Vec3f>(irow, icol + 1) - vertexMat.at<cv::Vec3f>(irow, icol - 1));
cv::Vec3f Xv = cv::normalize(vertexMat.at<cv::Vec3f>(irow + 1, icol) - vertexMat.at<cv::Vec3f>(irow - 1, icol));
cv::Vec3f Xuu = cv::normalize(vertexMat.at<cv::Vec3f>(irow, icol + 1) + vertexMat.at<cv::Vec3f>(irow, icol - 1)
- 2 * vertexMat.at<cv::Vec3f>(irow, icol));
cv::Vec3f Xuv = cv::normalize(cv::normalize(vertexMat.at<cv::Vec3f>(irow + 1, icol + 1) - vertexMat.at<cv::Vec3f>(irow + 1, icol - 1))
- cv::normalize(vertexMat.at<cv::Vec3f>(irow - 1, icol + 1) - vertexMat.at<cv::Vec3f>(irow - 1, icol - 1)));
cv::Vec3f Xvv = cv::normalize(vertexMat.at<cv::Vec3f>(irow + 1, icol) + vertexMat.at<cv::Vec3f>(irow - 1, icol)
- 2 * vertexMat.at<cv::Vec3f>(irow, icol));
cv::Vec3f normal = cv::normalize(cv::normalize(Xv).cross(cv::normalize(Xu)));
// first fundamental form
float E = 1.0f + Xu.dot(Xu);
float F = Xu.dot(Xv);
float G = 1.0f + Xv.dot(Xv);
// second fundamental form
float L = Xuu.dot(normal);
float M = Xuv.dot(normal);
float N = Xvv.dot(normal);
// gaussian and mean curvature
float K = (L * N - M * M) / (E * G - F * F); // gaussian
float H = (L * G - 2 * M * F + N * E) / (2 * (E * G - F * F)); // mean
curvatureMat.at<float>(irow, icol) = H;
}
}
return curvatureMat;
}