matlab模板仅匹配矩阵中的0(或1)

时间:2014-05-01 20:03:08

标签: image matlab image-processing matching template-matching

我是matlab编程的初学者,我在模板匹配方面遇到了一些麻烦。我有几个带有黑色边框的白色框(下面的图片链接)以及一些文字,我想要提取所有框,还有一个有X的(它是一个多选答案)。在开始时我使用了normxcorr2,但问题是由于模板的许多白色像素,我得到了一些不相关的模板,比如只有空格。我一直在寻找一种只在0上进行模板匹配的算法,所以我可以得到只有黑色方块的模板。我希望我能说清楚,谢谢:)。

http://i91.photobucket.com/albums/k284/Chris2401/sqrTemplate.png

1 个答案:

答案 0 :(得分:2)

编辑:2014年5月2日

现在了解您想要实现的目标,我现在可以帮助您解决问题。由于您是MATLAB的初学者,我将使用更简单的方法(即使有更复杂的方法可以帮助您解决这个问题),因为我想演示算法的工作原理。

您基本上想要实现normxcorr2,但您只想在模板中包含标记为黑色的像素。您还希望跳过搜索图像中非黑色的位置。在这种情况下,我将逐步为您布局算法,然后编写一些代码。

  1. 读入模板并提取黑色的像素位置
  2. 以滑动窗口的方式,对于与搜索图像中的模板大小相同的每个图像补丁...
    1. 如果整个图像色块为白色,请跳过
    2. 提取相同的黑色位置
    3. 仅使用这些位置计算NCC。
  3. 输出将是包含搜索图像中每个位置的NCC的地图
  4. 我不会处理搜索图像中边框像素的情况,因为我假设您希望能够将搜索图像中的某些内容与模板的完整大小进行匹配。

    以下是一些假设。让我们假设以下变量:

    • imTemplate - 模板图片,例如您向我展示的图片
    • imSearch - 我们希望在执行此NCC操作时搜索的图像

    我还假设每张图片都是二进制的,因为你帖子的标题有" 0或1"在它。

    因此,我有以下代码:

    [rowsSearch colsSearch] = size(imSearch); % Get dimensions of search image
    [rowsTemp colsTemp] = size(imTemplate); % Get dimensions of template image
    
    mapBlack = imSearch == 0; % Obtain a map of where the black pixels are in the template
    numPixelsCompare = sum(mapBlack(:)); % Need to know how many pixels are valid for comparison
    
    % Obtain area of searching within the search image
    startSearchRows = 1 + floor(rowsSearch/2);
    endSearchRows =  rowsSearch - floor(rowsSearch/2);
    startSearchCols = 1 + floor(colsSearch/2);
    endSearchCols = colsSearch - floor(colsSearch/2);
    
    % Need half the dimensions of each for the template dimensions... you will
    % see why we need this later
    rowsTempHalf = floor(rowsTemp/2);
    colsTempHalf = floor(colsTemp/2);
    
    % Where we will store our NCC calculations
    NCCMap = zeros(rowsSearch, colsSearch);
    
    % Because you want to include all of the black pixels in your
    % calculations, and these are all the same, the signal you are comparing
    % to basically consists of all white pixels.
    % Create a vector that consists of all 1s that is the same size as how
    % many black pixels exist in the template
    compareSignal = ones(numPixelsCompare, 1);
    
    % For each location in the search image (ensuring that the full template
    % is inside the image)
    for i = startSearchRows : endSearchRows
         for j = startSearchCols : endSearchCols
              % Grab an image patch that is the same size as the template
              % At each location (i,j) this serves as the CENTRE of the image
              % patch, and we are grabbing pixels surrounding this centre that
              % will create a patch that is the same size as the template
              searchBlock = imSearch(i-rowsTempHalf:i+rowsTempHalf, ...
                                     j-colsTempHalf:j+colsTempHalf);
    
              % If all of the pixels are white, skip
              if (all(searchBlock == 1))
                  continue;
              end
    
              % Extract only those pixels that are valid in the template
              searchPixels = searchBlock(mapBlock);
    
              % Must invert so that black pixels become white 
              % You mentioned that white pixels are "background"
              searchPixels = ~searchPixels;
    
              % Compute NCC for this patch
              NCCMap(i,j) = compareSignal'*searchPixels / ...
                            (sqrt(compareSignal'*compareSignal) * sqrt(searchPixels'*searchPixels));
         end
    end
    

    如果你对我计算NCC的方式感到有点困惑,它基本上就是你习惯的,但是我用矢量代数来计算它。这应该有希望给你你想要的。要找到模板匹配位置的最佳位置,您可以执行以下操作以提取此位置的行和列:

     [r,c] = find(NCCMap == max(NCCMap(:)));
    

    我希望这能解决你的问题。这有点效率低下,它真的会开始受到更高分辨率图像的影响,但我想给你一个良好的开端,这样你就不会闲着试图自己解决这个问题。

    NB:我还没有测试过此代码,因为我没有用于解决此问题的示例搜索图像。希望这会奏效。发表评论,让我知道它是怎么回事。