Search code examples
c++opencvyamlsurfkeypoint

Loading keypoints and drawing


I have a piece of code that calculates the SURF keypoints of an image and saves them to a yml file. I am then trying to load that file and draw the saved keypoints on am image.

Keypoint and write code:

cv::Mat img_1 = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
detectKeypointsImage(img_1);
int minHessian = 400;
cv::SurfFeatureDetector detector(minHessian);
std::vector<cv::KeyPoint> keypoints_1;
detector.detect(img_1, keypoints_1);
cv::Mat img_keypoints_1;
drawKeypoints(img_1, keypoints_1, img_keypoints_1);
cv::FileStorage fs("keypointsVW.yml", cv::FileStorage::WRITE);
write(fs, "keypoints_1", keypoints_1);
fs.release();

In order to test if this has worked I then comment out the above block minus the following lines:

cv::Mat img_1 = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);

cv::Mat img_keypoints_1;

I am then using the following code to read the keypoints and draw them on the image:

std::vector<cv::KeyPoint> testPoints;
cv::FileStorage fs2("keypointsVW.yml", cv::FileStorage::READ);
cv::FileNode kptFileNode = fs2["keypointsVW"];
read(kptFileNode, testPoints);
fs2.release();
drawKeypoints(img_1, testPoints, img_keypoints_1);
cv::imshow("keypoints_1", img_keypoints_1);

However when the program starts it is showing the image minus any keypoints. Why is this happening?


Solution

  • I never used the storage functionality, but from intuition I thought that you named your FileNode wrong while loading the data.

    I tested this code and it works:

    std::vector<cv::KeyPoint> testPoints;
    cv::FileStorage fs2("keypointsVW.yml", cv::FileStorage::READ);
    cv::FileNode kptFileNode = fs2["keypoints_1"]; // Here you must use the name that you used for writing the data within the file. 
        // You named it "keypoints_1" before. 
        // It must be the same name that you used in write(fs, "keypoints_1", keypoints_1);
        // so for example write(storage, "nodeName", data); needs you to call cv::FileNode kptFileNode = fs2["nodeName"]; later
    
    read(kptFileNode, testPoints);
    fs2.release();
    drawKeypoints(img_1, testPoints, img_keypoints_1);
    cv::imshow("keypoints_1", img_keypoints_1);