matlabimage-processingcomputer-visionfeature-extractionmatlab-cvst

Passing parameters to function handle in bagOfFeatures function


Lets say we have a custom extractor function

[features,featureMetrics] = exampleBagOfFeaturesExtractor(img,param1, param2)

I want to call bagOfFeatures function and pass custom extractor function:

extractorFcn = @exampleBagOfFeaturesExtractor;
bag = bagOfFeatures(imgSets,'CustomExtractor',extractorFcn)

In exampleBagOfFeaturesExtractor function I want to use different local descriptors extractor depending on param1. How do I pass param1 to exampleBagOfFeaturesExtractor?

What is the best way to use different local descriptors in my custom extractor function?

Thank you for your help!

Edit

This is the custom extractor function I am currently using:

function [features,featureMetrics] = exampleBagOfFeaturesExtractor(img,param1,param2)

    keypoint_detector = cv.FeatureDetector(param1);
    descriptor_extractor = cv.DescriptorExtractor(param2);

    kpts = keypoint_detector.detect(img);
    [ features, kpts ] = descriptor_extractor.compute(img, kpts);
    featureMetrics=ones(1,size(features,1))/size(features,1);
end

Solution

  • The expected kind of functions that the bagOfFeatures function requires can only be a single input, namely the input image. Therefore, if you want to create a custom feature extractor where you can vary the parameters, you will need to first create the parameters, then create an anonymous function that captures these parameters via lexical closure. This means that when you create the anonymous function, make sure the parameters are created so that when you reference them in your anonymous function, they capture the most up to date version of the parameters prior to creating the function.

    Therefore, assuming param1 and param2 already exist in your workspace, create a function like so:

    % Create param1 and param2 here
    param1 = ...;
    param2 = ...;
    extractorFcn = @(img) exampleBagOfFeaturesExtractor(img, param1, param2);
    

    This creates an anonymous function that takes in a single input - your image. param1 and param2 are thus captured in your function, so the state of the variables is recorded and are made available within the anonymous function. Also note that the function doesn't take in additional inputs, only the input image. You can then call bagOfFeatures as normal. However, should you want to change param1 or param2, not only will you have to change these parameters, but you must re-declare the anonymous function again so that the latest stage of the variables is recaptured.

    As a quick example, suppose I've created an anonymous function like so:

    x = 5;
    y = @(t) t + x;
    

    This function y takes the current state of x and adds it with a variable t. For now, this acts like how we expect it:

    >> x = 5;
    >> y = @(t) t + x;
    >> y(6)
    
    ans =
    
        11
    

    We put in the value 6 and we get 11. If we try and change x then call y, it will not change this in the function as it captured the state of the variable before you created the function:

    >> x = 10;
    >> y(6)
    
    ans =
    
        11
    

    Therefore, if you want to change the parameters, you must also re-declare the function again before calling bagOfFeatures, so:

    param1 = ...; % Change this to something new
    param2 = ...; % Change this if you like as well
    extractorFcn = @(img) exampleBagOfFeaturesExtractor(img, param1, param2);
    

    In MATLAB terms, these variables persist in the anonymous function. You can read more about it here: https://www.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html#f4-71621