HuajianUP / Photo-SLAM

[CVPR 2024] Photo-SLAM: Real-time Simultaneous Localization and Photorealistic Mapping for Monocular, Stereo, and RGB-D Cameras
GNU General Public License v3.0
376 stars 38 forks source link

Errors in OBRextractor::ComputePyramid() function #6

Closed Eragonlrc closed 5 months ago

Eragonlrc commented 5 months ago

After building the project on Ubuntu 22.04LTS with the same versions of the dependencies as mentioned in README, I'm trying to run the examples/tum_mono.cpp with args:

"args": ["../ORB-SLAM3/Vocabulary/ORBvoc.txt", 
                     "../cfg/ORB_SLAM3/Monocular/TUM/tum_freiburg1_desk.yaml",
                     "../cfg/gaussian_mapper/Monocular/TUM/tum_mono.yaml",
                     "../data/TUM/rgbd_dataset_freiburg1_desk",
                     "../results/tum_mono_$i/rgbd_dataset_freiburg1_desk",
                     "no_viewer"],

but got error report bellow:

[Gaussian Mapper]CUDA available! Training on GPU. [Gaussian Mapper]Reading parameters from "../cfg/gaussian_mapper/Monocular/TUM/tum_mono.yaml"

Start processing sequence ... Images in the sequence: 613

terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.8.0) /home/lrc/opencv/opencv-4.8.0/modules/core/src/matrix.cpp:246: error: (-215:Assertion failed) s >= 0 in function 'setSize'

Exception occurred in function:

void ORBextractor::ComputePyramid(cv::Mat image)
    {
        for (int level = 0; level < nlevels; ++level)
        {
            float scale = mvInvScaleFactor[level];
            Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
            Size wholeSize(sz.width + EDGE_THRESHOLD*2, sz.height + EDGE_THRESHOLD*2);
            Mat temp(wholeSize, image.type()), masktemp;
            mvImagePyramid[level] = temp(Rect(EDGE_THRESHOLD, EDGE_THRESHOLD, sz.width, sz.height));

            // Compute the resized image
            if( level != 0 )
            {
                resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);

                copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                               BORDER_REFLECT_101+BORDER_ISOLATED);
            }
            else
            {
                copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                               BORDER_REFLECT_101);
            }
        }

    }

When trying to call cv::Mat or cv::resize() with parameters including Size type, exceptions about assertion failure occurred. For example, I replace

Mat temp(wholeSize, image.type()), masktemp;

with

Mat temp(sz.height + EDGE_THRESHOLD*2, sz.width + EDGE_THRESHOLD*2, image.type()), masktemp;

the exception disappeared when level=0, but this exception occurred when level=1:

terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.8.0) /home/lrc/opencv/opencv-4.8.0/modules/imgproc/src/resize.cpp:4065: error: (-215:Assertion failed) inv_scale_x > 0 in function 'resize'

However, when I replace main() function with

int main()
{
    using namespace std;
    using namespace cv;
    string path = "./test.jpg";
    Mat images;
    vector<String> filename;
    glob(path, filename, false);
    size_t count = filename.size();
    for (int i = 0; i < count; i++)
    {
        images = imread(filename[i]);
        if (!images.data) {
            cout << "Image reading error !" << endl;
            continue;
        }

        Size dsize = Size(100, 70);
        Mat shrink;
        resize(images, shrink, dsize, 0, 0, INTER_AREA);

        stringstream str;
        str << "./test1.jpg";
        imwrite(str.str(), shrink);
    }
}

it run and resized an image successfully. So I think OpenCV environment has nothing to do with the problem.

Then why the exception occurred?

liquorleaf commented 5 months ago

As far as I know, (-215:Assertion failed) s >= 0 in function 'setSize' happens when the Mat is empty, which is often caused by incorrect image path. Have you checked whether all the cv::Mat have proper content?

Eragonlrc commented 5 months ago

Thanks for replying! However, I insert

imwrite("./image_level" + to_string(level) + ".jpg", image);

before

Mat temp(wholeSize, image.type()), masktemp;

to check the content of cv::Mat image in function ORBextractor::ComputePyramid() As a result, it saves a correct 640*480 gray image. So I'm sure that the function has a correct input. And wholeSize.width=678, wholeSize.height=518

The problem confuses me most is that when I replaced the usage of Size variables, the exception dissappeared, while it's impossible to replace every usage of Size variables.

Eragonlrc commented 5 months ago

Solved by preparing the environment by docker.

DapengFeng commented 4 months ago

The problem confuses me most is that when I replaced the usage of Size variables, the exception dissappeared, while it's impossible to replace every usage of Size variables.

It may conflict with the built-in system opencv in ORB-SLAM3.