% Performs Hough Scan Matching (HSM). % The file is long but (I hope) well commented. Don't esitate to contact me % if you have any problem. % % There are a lot of params, listed here in order of % importance. The function returns a rich structure "result" % where all the computations are registered. You can % display nicely the result with the function displayHSMResult(). % % The two sets of points: % params.points1 % params.points2 % % The parameters for the Hough Transform: % params.thetaCells % params.rhoCells % params.rhoScale real-world width of buffer % % Parameters that characterize the search domain: % params.maxTBound bound for translation (|T|cells phiCell = phi / (2*pi) * p.thetaCells; % circular rotation r.hs2rot = circularRotation(result.hs2, phiCell); % We have to choose the columns (=which directions) of the HT to correlate % the best way to choose is to use the maxima of the spectrum; % therefore (to suppress noise) we multiply the two spectra, filter % and get the maxima r.product = result.hs1 .* r.hs2rot; r.productFiltered = simpleLowPassFilterCircular(r.product, p.phiFilterSigma); % Because the spectrum is 180-periodic, we search for maxima only in the first half r.corrIndexes = findLocalMaxima(r.productFiltered(1:floor(p.thetaCells/2)), p.maxRhoCorrelations); % We need at least 2 directions if (size(r.corrIndexes,2)==1) r.corrIndexes(2) = round(r.corrIndexes(1)+p.thetaCells/4); end % Now we setup a buffer, which will hold the prob. distribution for T cells = round(p.maxTBound * (p.rhoCells/p.rhoScale)); r.tbuffer = zeros(cells*2+1,cells*2+1); % For each direction for j=1:size(r.corrIndexes,2) index=r.corrIndexes(j); direction=index*2*pi/p.thetaCells; % We extract the two columns of the HT col1 = result.ht1(index,:); % we must "rotate" by phi index2 = round(mod(index+phiCell, p.thetaCells)); col2 = result.ht2(index2,:); % We do a cross correlation between the two columns crossCorrelationRange = cells; crossCorrelation = xcorr(col2,col1,crossCorrelationRange); % Now for each element in the T buffer, % we increase the value by this observation for a=1:size(r.tbuffer,1) for b=1:size(r.tbuffer,2) % Which value of the translation T is associated to this cell? T = [ (a-cells) (b-cells) ]' * p.rhoScale / p.rhoCells; % We project T on the correlation direction pT = [cos(direction) sin(direction)] * T; % We transform the projection to cells of the correlation % buffer pTcell = round(pT * p.rhoCells / p.rhoScale + cells); if (pTcell>=1) && (pTcell<=size(crossCorrelation,2)) value = crossCorrelation(pTcell); r.tbuffer(a,b)=r.tbuffer(a,b)+value; end end end end % For each direction % Now the buffer is complete, to find the T we extract the maxima % (for simplicity, we use only one maximum) r.tbufferFiltered = simpleLowPassFilter2(r.tbuffer, p.rhoFilterSigma); r.Tcells = findLocalMaxima2(r.tbufferFiltered, p.maxTHypotheses); num=size(r.Tcells,2); % Convert back to world-coordinates r.THypotheses = (r.Tcells-repmat([cells cells]',1,num)) * p.rhoScale / p.rhoCells; % Saving debug info into main structure result.r(i)=r; end result.params=p;