线描述符匹配演示

此示例显示由cv.BinaryDescriptorMatcher类提供的行描述符匹配的功能。

此模块显示如何通过2种不同的方法从图像中提取线段:首先使用线段检测器cv.LSDDetector对线进行分段,然后(或仅使用)使用二进制描述符获取线并为它们提供描述符cv.BinaryDescriptor。最后,我们可以使用cv.BinaryDescriptorMatcher类匹配线段。

资料来源:

内容

描述符之间的匹配

如果我们从两个不同的图像中提取了描述符,则可以在它们之间搜索匹配。一种方法是将描述符与每个输入查询描述符完全匹配,选择最近距离的描述符。

有时,我们可能有兴趣搜索最接近的k描述符,给定一个输入。请参见cv.BinaryDescriptorMatcher.knnMatch

在某些情况下,我们可以有一个搜索半径,看看远处的最重要的描述符[R从输入查询。请参阅cv.BinaryDescriptorMatcher.radiusMatch

图片

<span style="color:#000000">
<span style="color:#0000ff">如果为</span> false,<span style="color:#228b22">%load images</span>
    img1 = cv.imread(fullfile(mexopencv.root(),<span style="color:#a020f0">'test'</span>,<span style="color:#a020f0">'books_left.jpg'</span>),<span style="color:#a020f0">'Color'</span>,true);
    img2 = cv.imread(fullfile(mexopencv.root(),<span style="color:#a020f0">'test'</span>,<span style="color:#a020f0">'books_right.jpg'</span>),<span style="color:#a020f0">'Color'</span>,true);
<span style="color:#0000ff">否则</span> 
    im = which(<span style="color:#a020f0">'cameraman.tif'</span>);
    <span style="color:#0000ff">if</span> isempty(im),im = fullfile(mexopencv.root(),<span style="color:#a020f0">'test'</span>,<span style="color:#a020f0">'blox.jpg'</span>); <span style="color:#0000ff">结束</span> 
    img1 = cv.imread(im,<span style="color:#a020f0">'Color'</span>,true);
    M = cv.getRotationMatrix2D(round([size(img1,2)size(img1,1)] ./ 2), -  20,0.9);
    img2 = cv.warpAffine(img1,M);
<span style="color:#0000ff">结束</span>

<span style="color:#228b22">%创建二进制掩码</span> 
mask1 = ones(size(img1,1),size(img1,2),<span style="color:#a020f0">'uint8'</span>);
mask2 = ones(size(img2,1),size(img2,2),<span style="color:#a020f0">'uint8'</span>);

subplot(121),imshow(img1)
subplot(122),imshow(img2)
img <span style="color:#a020f0">img1 </span> <span style="color:#a020f0">img2 </span> <span style="color:#a020f0">mask1 </span> <span style="color:#a020f0">mask2</span></span>
<span style="color:#4c4c4c">  名称大小字节类属性

  img1 256x256x3 196608 uint8              
  img2 256x256x3 196608 uint8              
  mask1 256x256 65536 uint8              
  mask2 256x256 65536 uint8              

</span>

BinaryDescriptor:检测和计算

<span style="color:#000000"><span style="color:#228b22">%使用默认参数创建BinaryDescriptor对象</span>
bd = cv.BinaryDescriptor();

<span style="color:#228b22">%compute lines and descriptors</span> 
[keylines1,descr1] = bd.detectAndCompute(img1,<span style="color:#a020f0">'Mask'</span>,mask1);
[keylines2,descr2] = bd.detectAndCompute(img2,<span style="color:#a020f0">'Mask'</span>,mask2);
卫生组织<span style="color:#a020f0">keylines1 </span> <span style="color:#a020f0">keylines2 </span> <span style="color:#a020f0">descr1 </span> <span style="color:#a020f0">descr2</span>

<span style="color:#228b22">%从第一个八度音程中选择keylines及其描述符</span>
idx =([keylines1.octave] == 0);
keylines1 = keylines1(idx);
descr1 = descr1(idx,:);

idx =([keylines2.octave] == 0);
keylines2 = keylines2(idx);
descr2 = descr2(idx,:);</span>
<span style="color:#4c4c4c">  名称大小字节类属性

  descr1 53x32 1696 uint8               
  descr2 46x32 1472 uint8               
  keylines1 1x53 79208 struct              
  keylines2 1x46 68848 struct              

</span>

BinaryDescriptor:匹配

<span style="color:#000000"><span style="color:#228b22">%创建BinaryDescriptorMatcher对象</span>
bdm = cv.BinaryDescriptorMatcher();

<span style="color:#228b22">%需要匹配</span>
matches = bdm.match(descr1,descr2)

<span style="color:#228b22">%选择最佳匹配</span>
MATCHES_DIST_THRESHOLD = 25;
good_matches =([matches.distance] <MATCHES_DIST_THRESHOLD);
fprintf(<span style="color:#a020f0">'匹配数=%d \ n'</span>,nnz(good_matches));

<span style="color:#228b22">%plot匹配</span> 
outImg = cv.drawLineMatches(img1,keylines1,img2,keylines2,matches,<span style="color:#0000ff">... </span>
    <span style="color:#a020f0">'MatchesMask'</span>,good_matches);
图,imshow(outImg)
标题(<span style="color:#a020f0">'八度音阶0'</span>)</span>
<span style="color:#4c4c4c">匹配= 
  带字段的1×53结构数组:
    queryIdx
    trainIdx
    imgIdx
    距离
好的比赛数= 12
</span>

LSDDetector:检测和计算

<span style="color:#000000"><span style="color:#228b22">%创建一个LSD检测器</span>
lsd = cv.LSDDetector();

<span style="color:#228b22">%检测行</span> 
keylines1 = lsd.detect(img1,<span style="color:#a020f0">'Scale'</span>,2,<span style="color:#a020f0">'NumOctaves'</span>,2,<span style="color:#a020f0">'Mask'</span>,mask1);
keylines2 = lsd.detect(img2,<span style="color:#a020f0">'Scale'</span>,2,<span style="color:#a020f0">'NumOctaves'</span>,2,<span style="color:#a020f0">'Mask'</span>,mask2);
卫生组织<span style="color:#a020f0">keylines1 </span> <span style="color:#a020f0">keylines2</span>

<span style="color:#228b22">行的%计算描述符</span>
descr1 = bd.compute(img1,keylines1);
descr2 = bd.compute(img2,keylines2);
卫生组织<span style="color:#a020f0">descr1 </span> <span style="color:#a020f0">descr2</span>

<span style="color:#228b22">%从第二个八度音程中选择行和描述符</span>
idx =([keylines1.octave] == 1);
keylines1 = keylines1(idx);
descr1 = descr1(idx,:);

idx =([keylines2.octave] == 1);
keylines2 = keylines2(idx);
descr2 = descr2(idx,:);</span>
<span style="color:#4c4c4c">  名称大小字节类属性

  keylines1 1x230 341168结构              
  keylines2 1x208 308608 struct              

  名称大小字节类属性

  descr1 230x32 7360 uint8              
  descr2 208x32 6656 uint8              

</span>

LSDDetector:匹配

<span style="color:#000000"><span style="color:#228b22">%compute匹配</span>
matches = bdm.match(descr1,descr2)

<span style="color:#228b22">%选择最佳匹配</span>
good_matches =([matches.distance] <MATCHES_DIST_THRESHOLD);
fprintf(<span style="color:#a020f0">'匹配数=%d \ n'</span>,nnz(good_matches));

<span style="color:#228b22">%情节匹配</span>
img1 = cv.resize(img1,0.5,0.5);
img2 = cv.resize(img2,0.5,0.5);
outImg = cv.drawLineMatches(img1,keylines1,img2,keylines2,matches,<span style="color:#0000ff">... </span>
    <span style="color:#a020f0">'MatchesMask'</span>,good_matches);
图,imshow(outImg)
标题(<span style="color:#a020f0">'LSD匹配八度音阶'</span>)</span>
<span style="color:#4c4c4c">匹配= 
  带字段的1×64结构数组:
    queryIdx
    trainIdx
    imgIdx
    距离
好匹配数= 16
</span>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值