pythonopencvpython-3.7flann

Save opencv FlannBasedMatcher from python


I am trying to save a FlannBasedMatcher created and train with opencv-python 4.5.5.62.

The save function of the class only save the parameters. I can also access to the trainDescriptors, but what I would like is to save the flann once trained. Be able to reload it from another python script.

Does anybody have any clue on it ?

Code example would be something like (I know the code is useless and ugly but an example can sometimes help to understand the problem) :

import cv2
import numpy as np

# Creating random data
datas = np.random.rand(50000, 512)
datas = np.float32(datas)

# Creating the FlannBasedMatcher and train it
flann = cv2.FlannBasedMatcher(index_params, search_params)
flann.add([datas])
flann.train()

# Here I am able to do knnMatch search in 'flann'

# Not existing function that I am looking for
flann.saveTrainedModel("my_file_path")

# Loading from an existing file 
flannLoaded = cv2.FlannBasedMatcher.LoadFromFile("my_file_path")

# Here I want to be able to do knnMatch in 'flannLoaded' without training it.

If someone have a clue about such a function as saveTrainedModel and/or LoadFromFile, it would be of great help.

Edit: I have found somethin online to do this in C++ : https://github.com/renweizhukov/LearningOpenCV/blob/master/FlannKnnSavableMatching1toN/src/FlannBasedSavableMatcher.cpp But it uses trainDescCollection that is not available in the python version.

Many thanks for help,


Solution

  • I finally found a way to do it by using pyflann module. First I had to modify pyflann (pyflann-1.6.14) and index (index-0.2-py37) modules for them to accept python 3 usage.

    Then you can savec flann indexes doing:

    from pyflann.index import FLANN, set_distance_type
     
    # creating the data
    datas = np.random.rand(1000000, 512)
    datas = np.float32(datas)
     
    # declaring the FLANN
    flann = FLANN()
    # build the index from datas
    flann.build_index(datas, algorithm="linear", checks=10)
    # Saving the index created therebefore
    flann.save_index(b"my_saved_flann.txt")
     
    # Searched data
    searched = datas[i]
    searched = np.expand_dims(searched, axis=0)
     
    # retrieving the 500 nearest neighbours of searched
    results, distances = flann.nn_index(searched, 500)