pattmatch: NCC based image-to-image match

Petr Sladek (sladep1) & Milan Kratochvil (kratom4) at CTU Prague

Contents

script contains normalized cross-correlation techniques: files: nccmx.m (the same as ncc.m with matrix support), function nccmx(x,y), x,y are matrices the same size

      pattmatch.m ('pattern match')

automatic RGB/grayscale to grayscale conversion.

A = imread('05.png'); %read reference image
B = imread('10.png'); %read image to be compared with the part of reference image
imgAdim=size(size(A),2);
imgBdim=size(size(B),2);

if imgAdim==2
  imgref = im2double(A);
  fprintf('ref grayscale picture \n');
end;
if imgAdim==3
  imgcmp = im2double(rgb2gray(A));
  fprintf('ref RGB picture, grayscaled \n');
end;

if imgBdim==2
  imgcmp = im2double(B);
  fprintf('cmp grayscale picture \n');
end;
if imgBdim==3
  imgcmp = im2double(rgb2gray(B));
  fprintf('cmp RGB picture, grayscaled \n');
end;
ref grayscale picture 
cmp grayscale picture 

display reference image and let user to cut reference region:

figure(1);
clf;
imshow(imgref);
imgcutpoint = imgcrop; %returns top-left corner and bottom-right corner of rectangle
imgcut = imgref(imgcutpoint(1):imgcutpoint(2),imgcutpoint(3):imgcutpoint(4));

% get size of cut reference image
[imgcy imgcx]= size(imgcut)

% plot selected reference image region
figure(2);clf;
imshow(imgcut);
Press ENTER to continue

imgcy =

    16


imgcx =

    18

get handle of NCCMX(ref,cmp'd_image) (normalized cross-correlation, matrix supported)

h_nccmx = @(x) nccmx(x(:,:),imgcut);

NCC nlfilter:

perform NCC sliding-neighborhood operation

% allocate memory
[imgcmp_y imgcmp_x] = size(imgcmp);
matched = ones(imgcmp_y, imgcmp_x);

% process slider-neighborhood NCC:
matched = nlfilter(imgcmp,[imgcy imgcx],h_nccmx);

% plot matched (cross-correlation function)
figure(3);clf;
colormap jet;
mesh(matched);

get maxima coordinates from matched:

[mcoordy mcoordx mval] = nmaxsup(matched);

sort maximas in descending order

smval contains values, sindex contains val's indexies, using index matrix scoordx,y are re-sorted.

[smval sindex] = sort(mval,'descend');
scoordy = mcoordy(sindex);
scoordx = mcoordx(sindex);

match-marker:

draws rectangle in matched position.

% create matrix rectangle, and rectangle multiply mask:
% 111111
% 100001
% 100001
% 111111
rect = zeros(imgcy,imgcx);
rect(1,:) =1;
rect(imgcy,:) =1;
rect(:,1) =1;
rect(:,imgcx) =1;
%create rects' multiply mask:
% 000000
% 011110
% 011110
% 000000
mmrect = ones(imgcy,imgcx)-rect;

copy grayscale into RGB image

imgflags = zeros(imgcmp_y,imgcmp_x,3);
imgflags(:,:,1) = imgcmp(:,:);
imgflags(:,:,2) = imgcmp(:,:);
imgflags(:,:,3) = imgcmp(:,:);

cut coordinates if crossing imgcmp boundaries

function makes quite different decisions about odd/evern length

if mod(imgcy,2)
  %odd
  yfrom = scoordy-floor(imgcy/2);
  yto = scoordy+floor(imgcy/2);
else
  %even
  yfrom = scoordy-floor(imgcy/2);
  yto = scoordy+floor(imgcy/2)-1;
end;
if mod(imgcx,2)
  xfrom = scoordx-floor(imgcx/2);
  xto = scoordx+floor(imgcx/2);
else
  xfrom = scoordx-floor(imgcx/2);
  xto = scoordx+floor(imgcx/2)-1;
end;

only >85% fitted maximas are diplayed.

maxthr = 0.85.*max(smval);
ilim = length(smval);
i=1;
while (smval(i)>maxthr)
  if (i>ilim)
    break;
  end;
  % limit edges of marker (see cell above), if drawing out of imgcmp boundaries:
  %
  % sometime in this way:
  % 1111
  % 1000
  % 1000
  % 1111
  % sometime in this way:
  %
  % 100001
  % 100001
  % 111111
  % and so on.

  yfm = 1;
  ytm = imgcy;
  xfm = 1;
  xtm = imgcx;
  if (yfrom(i)<1)
   yfm = abs(yfrom(i))+2;
   yfrom(i) = 1;
  end;
  if (yto(i)>imgcmp_y)
   ytm = imgcy - (yto(i)-imgcmp_y);
   yto(i) = imgcmp_y;
  end
  if (xfrom(i)<1)
   xfm = abs(xfrom(i))+2;
   xfrom(i) = 1;
  end;
  if (xto(i)>imgcmp_x)
   xtm = imgcx - (xto(i)-imgcmp_x);
   xto(i) = imgcmp_x;
  end
  % and re-draw marker in green-channel
  imgflags(yfrom(i):yto(i),xfrom(i):xto(i),1) = imgflags(yfrom(i):yto(i),xfrom(i):xto(i),1).*mmrect(yfm:ytm,xfm:xtm);
  imgflags(yfrom(i):yto(i),xfrom(i):xto(i),2) = imgflags(yfrom(i):yto(i),xfrom(i):xto(i),2).*mmrect(yfm:ytm,xfm:xtm);
  imgflags(yfrom(i):yto(i),xfrom(i):xto(i),3) = imgflags(yfrom(i):yto(i),xfrom(i):xto(i),3).*mmrect(yfm:ytm,xfm:xtm);
  imgflags(yfrom(i):yto(i),xfrom(i):xto(i),2) = imgflags(yfrom(i):yto(i),xfrom(i):xto(i),2) + rect(yfm:ytm,xfm:xtm);
  i = i+1;
end

show figure with markers:

figure(4); imshow(imgflags);