Petr Sladek (sladep1) & Milan Kratochvil (kratom4) at CTU Prague
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')
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
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
h_nccmx = @(x) nccmx(x(:,:),imgcut);
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);
[mcoordy mcoordx mval] = nmaxsup(matched);
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);
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;
imgflags = zeros(imgcmp_y,imgcmp_x,3); imgflags(:,:,1) = imgcmp(:,:); imgflags(:,:,2) = imgcmp(:,:); imgflags(:,:,3) = imgcmp(:,:);
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;
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
figure(4); imshow(imgflags);