Как рассчитать гауссову и среднюю кривизну из карты глубины - PullRequest
0 голосов
/ 15 января 2019

Я хотел бы рассчитать карту глубины формы гауссовой и средней кривизны, чтобы узнать геометрические фигуры, но я не уверен, как это реализовать.

Я рассчитываю гауссову и среднюю кривизну по первой и второй фундаментальной форме.

Сначала я извлекаю трехмерные точки из карты глубины, используя встроенную матрицу камеры. Затем я вычисляю каждую частную производную и вычисляю первую и вторую фундаментальные формы.

Значение результата для изображений глубины практически равно нулю, даже если поверхность не является плоской. Я учел шум глубинных изображений, поэтому я также попытался использовать модель САПР, форма которой более плавная.

Это правильный способ вычисления гауссовой и средней кривизны? Если у вас есть какие-то советы, пожалуйста, дайте их мне. Спасибо.

Я слежу за 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;
}
...