Line descriptors radius matching demo

This example shows the functionalities of radius matching.

Sources:

Contents

Querying internal database

The cv.BynaryDescriptorMatcher class, owns an internal database that can be populated with descriptors extracted from different images and queried using one of the modalities described in previous section. Population of internal dataset can be done using the add function; such function doesn't directly add new data to database, but it just stores it them locally. The real update happens when function train is invoked or when any querying function is executed, since each of them invokes train before querying. When queried, internal database not only returns required descriptors, but, for every returned match, it is able to tell which image matched descriptor was extracted from. An example of internal dataset usage is described in the following code; after adding locally new descriptors, a radius search is invoked. This provokes local data to be transferred to dataset, which, in turn, is then queried.

Images

images = {
    fullfile(mexopencv.root(),'test','stuff.jpg')
    fullfile(mexopencv.root(),'test','blox.jpg')
    fullfile(mexopencv.root(),'test','books_left.jpg')
    fullfile(mexopencv.root(),'test','books_right.jpg')
    fullfile(mexopencv.root(),'test','detect_blob.png')
};

Detect and Compute

% create a BinaryDescriptor object
bd = cv.BinaryDescriptor();

% compute keylines and descriptors
descriptorsMat = cell(size(images));
lines = cell(size(images));
for i=1:numel(images)
    % load image
    img = cv.imread(images{i}, 'Grayscale',true);

    % compute lines and descriptors
    [lines{i}, descriptorsMat{i}] = bd.detectAndCompute(img);
end
display(lines)
display(descriptorsMat)
lines =
  5×1 cell array
    [1×13  struct]
    [1×50  struct]
    [1×103 struct]
    [1×90  struct]
    [1×83  struct]
descriptorsMat =
  5×1 cell array
    [ 13×32 uint8]
    [ 50×32 uint8]
    [103×32 uint8]
    [ 90×32 uint8]
    [ 83×32 uint8]

Query

compose a queries matrix

queries = zeros(0, size(descriptorsMat{1},2));
for i=1:numel(descriptorsMat)
    if size(descriptorsMat{i},1) >= 5
        queries = [queries; descriptorsMat{i}(1:5,:)];
    else
        queries = [queries; descriptorsMat{i}];
    end
end
fprintf('Query matrix of %d descriptors\n', size(queries,1));
fprintf('Total taining descriptions: %d\n', ...
    sum(cellfun(@(d)size(d,1), descriptorsMat, 'UniformOutput',true)));
Query matrix of 25 descriptors
Total taining descriptions: 339

Radius match

% create a BinaryDescriptorMatcher object
bdm = cv.BinaryDescriptorMatcher();

% populate matcher
bdm.add(descriptorsMat);

% compute matches
matches = bdm.radiusMatch(queries, 30)
fprintf('Found %d matches\n', numel(matches));

for i=1:numel(matches)
    for j=1:numel(matches{i})
        fprintf('  match: %3d <-> %3d = %g\n', ...
            matches{i}(j).queryIdx, matches{i}(j).trainIdx, ...
            matches{i}(j).distance);
    end
end
matches =
  1×25 cell array
  Columns 1 through 4
    [1×4 struct]    [1×2 struct]    [1×2 struct]    [1×2 struct]
  Columns 5 through 8
    [1×2 struct]    [1×1 struct]    [1×1 struct]    [1×1 struct]
  Columns 9 through 12
    [1×1 struct]    [1×1 struct]    [1×2 struct]    [1×4 struct]
  Columns 13 through 16
    [1×1 struct]    [1×1 struct]    [1×1 struct]    [1×1 struct]
  Columns 17 through 20
    [1×1 struct]    [1×1 struct]    [1×1 struct]    [1×1 struct]
  Columns 21 through 24
    [1×1 struct]    [1×6 struct]    [1×6 struct]    [1×5 struct]
  Column 25
    [1×3 struct]
Found 25 matches
  match:   0 <->   0 = 0
  match:   0 <-> 162 = 27
  match:   0 <-> 314 = 29
  match:   0 <-> 319 = 29
  match:   1 <->   1 = 0
  match:   1 <->   2 = 16
  match:   2 <->   2 = 0
  match:   2 <->   1 = 16
  match:   3 <->   3 = 0
  match:   3 <->   4 = 27
  match:   4 <->   4 = 0
  match:   4 <->   3 = 27
  match:   5 <->  13 = 0
  match:   6 <->  14 = 0
  match:   7 <->  15 = 0
  match:   8 <->  16 = 0
  match:   9 <->  17 = 0
  match:  10 <->  63 = 0
  match:  10 <->  64 = 21
  match:  11 <->  64 = 0
  match:  11 <->  63 = 21
  match:  11 <-> 317 = 29
  match:  11 <-> 335 = 29
  match:  12 <->  65 = 0
  match:  13 <->  66 = 0
  match:  14 <->  67 = 0
  match:  15 <-> 166 = 0
  match:  16 <-> 167 = 0
  match:  17 <-> 168 = 0
  match:  18 <-> 169 = 0
  match:  19 <-> 170 = 0
  match:  20 <-> 256 = 0
  match:  21 <-> 257 = 0
  match:  21 <-> 258 = 2
  match:  21 <-> 259 = 5
  match:  21 <->  69 = 26
  match:  21 <->  26 = 29
  match:  21 <->  81 = 30
  match:  22 <-> 258 = 0
  match:  22 <-> 257 = 2
  match:  22 <-> 259 = 5
  match:  22 <->  69 = 26
  match:  22 <->  81 = 30
  match:  22 <-> 164 = 30
  match:  23 <-> 259 = 0
  match:  23 <-> 257 = 5
  match:  23 <-> 258 = 5
  match:  23 <->  69 = 23
  match:  23 <->  26 = 26
  match:  24 <-> 260 = 0
  match:  24 <-> 332 = 17
  match:  24 <-> 327 = 28