此示例显示由cv.BinaryDescriptorMatcher类提供的行描述符匹配的功能。
此模块显示如何通过2种不同的方法从图像中提取线段:首先使用线段检测器cv.LSDDetector对线进行分段,然后(或仅使用)使用二进制描述符获取线并为它们提供描述符cv.BinaryDescriptor。最后,我们可以使用cv.BinaryDescriptorMatcher类匹配线段。
资料来源:
如果我们从两个不同的图像中提取了描述符,则可以在它们之间搜索匹配。一种方法是将描述符与每个输入查询描述符完全匹配,选择最近距离的描述符。
有时,我们可能有兴趣搜索最接近的k描述符,给定一个输入。请参见cv.BinaryDescriptorMatcher.knnMatch
在某些情况下,我们可以有一个搜索半径,看看远处的最重要的描述符[R从输入查询。请参阅cv.BinaryDescriptorMatcher.radiusMatch
如果为 false,%load images
img1 = cv.imread(fullfile(mexopencv.root(),'test','books_left.jpg'),'Color',true);
img2 = cv.imread(fullfile(mexopencv.root(),'test','books_right.jpg'),'Color',true);
否则
im = which('cameraman.tif');
if isempty(im),im = fullfile(mexopencv.root(),'test','blox.jpg'); 结束
img1 = cv.imread(im,'Color',true);
M = cv.getRotationMatrix2D(round([size(img1,2)size(img1,1)] ./ 2), - 20,0.9);
img2 = cv.warpAffine(img1,M);
结束
%创建二进制掩码
mask1 = ones(size(img1,1),size(img1,2),'uint8');
mask2 = ones(size(img2,1),size(img2,2),'uint8');
subplot(121),imshow(img1)
subplot(122),imshow(img2)
img img1 img2 mask1 mask2
名称大小字节类属性
img1 256x256x3 196608 uint8
img2 256x256x3 196608 uint8
mask1 256x256 65536 uint8
mask2 256x256 65536 uint8
%使用默认参数创建BinaryDescriptor对象
bd = cv.BinaryDescriptor();
%compute lines and descriptors
[keylines1,descr1] = bd.detectAndCompute(img1,'Mask',mask1);
[keylines2,descr2] = bd.detectAndCompute(img2,'Mask',mask2);
卫生组织keylines1 keylines2 descr1 descr2
%从第一个八度音程中选择keylines及其描述符
idx =([keylines1.octave] == 0);
keylines1 = keylines1(idx);
descr1 = descr1(idx,:);
idx =([keylines2.octave] == 0);
keylines2 = keylines2(idx);
descr2 = descr2(idx,:);
名称大小字节类属性
descr1 53x32 1696 uint8
descr2 46x32 1472 uint8
keylines1 1x53 79208 struct
keylines2 1x46 68848 struct
%创建BinaryDescriptorMatcher对象
bdm = cv.BinaryDescriptorMatcher();
%需要匹配
matches = bdm.match(descr1,descr2)
%选择最佳匹配
MATCHES_DIST_THRESHOLD = 25;
good_matches =([matches.distance] '匹配数=%d \ n' ,nnz(good_matches));
%plot匹配
outImg = cv.drawLineMatches(img1,keylines1,img2,keylines2,matches,...
'MatchesMask',good_matches);
图,imshow(outImg)
标题('八度音阶0')
匹配=
带字段的1×53结构数组:
queryIdx
trainIdx
imgIdx
距离
好的比赛数= 12
%创建一个LSD检测器
lsd = cv.LSDDetector();
%检测行
keylines1 = lsd.detect(img1,'Scale',2,'NumOctaves',2,'Mask',mask1);
keylines2 = lsd.detect(img2,'Scale',2,'NumOctaves',2,'Mask',mask2);
卫生组织keylines1 keylines2
行的%计算描述符
descr1 = bd.compute(img1,keylines1);
descr2 = bd.compute(img2,keylines2);
卫生组织descr1 descr2
%从第二个八度音程中选择行和描述符
idx =([keylines1.octave] == 1);
keylines1 = keylines1(idx);
descr1 = descr1(idx,:);
idx =([keylines2.octave] == 1);
keylines2 = keylines2(idx);
descr2 = descr2(idx,:);
名称大小字节类属性
keylines1 1x230 341168结构
keylines2 1x208 308608 struct
名称大小字节类属性
descr1 230x32 7360 uint8
descr2 208x32 6656 uint8
%compute匹配
matches = bdm.match(descr1,descr2)
%选择最佳匹配
good_matches =([matches.distance] '匹配数=%d \ n' ,nnz(good_matches));
%情节匹配
img1 = cv.resize(img1,0.5,0.5);
img2 = cv.resize(img2,0.5,0.5);
outImg = cv.drawLineMatches(img1,keylines1,img2,keylines2,matches,...
'MatchesMask',good_matches);
图,imshow(outImg)
标题('LSD匹配八度音阶')
匹配=
带字段的1×64结构数组:
queryIdx
trainIdx
imgIdx
距离
好匹配数= 16