├── README.md ├── data ├── gang1.bmp └── gang2.bmp ├── hnormalise.m ├── homography2d.m ├── html ├── main_msac.html ├── main_msac.png ├── main_msac_01.png └── main_msac_02.png ├── iscolinear.m ├── main.m ├── main_msac.m ├── main_ransac.m ├── match.m ├── match_ransac.m ├── normalise2dpts.m ├── ransac.m ├── ransacfitfundmatrix.m └── ransacfithomography.m /README.md: -------------------------------------------------------------------------------- 1 | # Multi-sensor-images-matching(异源图像匹配/配准) 2 | - Original Paper: A Multi-sensor Image Matching Method Based on KAZE-HOG Features (https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8981033), ICIVC 2019. 3 | - Code: https://github.com/devenin/Multi-sensor-images-matching 4 | ### Requirements 5 | Please, use Matlab 2019a or latest vision. 6 | -------------------------------------------------------------------------------- /data/gang1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devenin/Multi-sensor-images-matching/3f5bb69dd34bf3fc04e9e69257d5b592bc7cc3af/data/gang1.bmp -------------------------------------------------------------------------------- /data/gang2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devenin/Multi-sensor-images-matching/3f5bb69dd34bf3fc04e9e69257d5b592bc7cc3af/data/gang2.bmp -------------------------------------------------------------------------------- /hnormalise.m: -------------------------------------------------------------------------------- 1 | % HNORMALISE - Normalises array of homogeneous coordinates to a scale of 1 2 | % 3 | % Usage: nx = hnormalise(x) 4 | % 5 | % Argument: 6 | % x - an Nxnpts array of homogeneous coordinates. 7 | % 8 | % Returns: 9 | % nx - an Nxnpts array of homogeneous coordinates rescaled so 10 | % that the scale values nx(N,:) are all 1. 11 | % 12 | % Note that any homogeneous coordinates at infinity (having a scale value of 13 | % 0) are left unchanged. 14 | % Peter Kovesi 15 | % School of Computer Science & Software Engineering 16 | % The University of Western Australia 17 | % pk at csse uwa edu au 18 | % http://www.csse.uwa.edu.au/~pk 19 | % 20 | % February 2004 21 | function nx = hnormalise(x) 22 | 23 | [rows,npts] = size(x); 24 | nx = x; 25 | % Find the indices of the points that are not at infinity 26 | finiteind = find(abs(x(rows,:)) > eps); 27 | if length(finiteind) ~= npts 28 | warning('Some points are at infinity'); 29 | end 30 | % Normalise points not at infinity 31 | for r = 1:rows-1 32 | nx(r,finiteind) = x(r,finiteind)./x(rows,finiteind); 33 | end 34 | nx(rows,finiteind) = 1; 35 | -------------------------------------------------------------------------------- /homography2d.m: -------------------------------------------------------------------------------- 1 | % HOMOGRAPHY2D - computes 2D homography 2 | % 3 | % Usage: H = homography2d(x1, x2) 4 | % H = homography2d(x) 5 | % 6 | % Arguments: 7 | % x1 - 3xN set of homogeneous points 8 | % x2 - 3xN set of homogeneous points such that x1<->x2 9 | % 10 | % x - If a single argument is supplied it is assumed that it 11 | % is in the form x = [x1; x2] 12 | % Returns: 13 | % H - the 3x3 homography such that x2 = H*x1 14 | % 15 | % This code follows the normalised direct linear transformation 16 | % algorithm given by Hartley and Zisserman "Multiple View Geometry in 17 | % Computer Vision" p92. 18 | % 19 | 20 | % Peter Kovesi 21 | % School of Computer Science & Software Engineering 22 | % The University of Western Australia 23 | % pk at csse uwa edu au 24 | % http://www.csse.uwa.edu.au/~pk 25 | % 26 | % May 2003 - Original version. 27 | % Feb 2004 - Single argument allowed for to enable use with RANSAC. 28 | % Feb 2005 - SVD changed to 'Economy' decomposition (thanks to Paul O'Leary) 29 | 30 | function H = homography2d(varargin) 31 | 32 | [x1, x2] = checkargs(varargin(:)); 33 | 34 | % Attempt to normalise each set of points so that the origin 35 | % is at centroid and mean distance from origin is sqrt(2). 36 | [x1, T1] = normalise2dpts(x1); 37 | [x2, T2] = normalise2dpts(x2); 38 | 39 | % Note that it may have not been possible to normalise 40 | % the points if one was at infinity so the following does not 41 | % assume that scale parameter w = 1. 42 | 43 | Npts = length(x1); 44 | A = zeros(3*Npts,9); 45 | 46 | O = [0 0 0]; 47 | for n = 1:Npts 48 | X = x1(:,n)'; 49 | x = x2(1,n); y = x2(2,n); w = x2(3,n); 50 | A(3*n-2,:) = [ O -w*X y*X]; 51 | A(3*n-1,:) = [ w*X O -x*X]; 52 | A(3*n ,:) = [-y*X x*X O ]; 53 | end 54 | 55 | [U,D,V] = svd(A,0); % 'Economy' decomposition for speed 56 | 57 | % Extract homography 58 | H = reshape(V(:,9),3,3)'; 59 | 60 | % Denormalise 61 | H = T2\H*T1; 62 | 63 | 64 | %-------------------------------------------------------------------------- 65 | % Function to check argument values and set defaults 66 | 67 | function [x1, x2] = checkargs(arg); 68 | 69 | if length(arg) == 2 70 | x1 = arg{1}; 71 | x2 = arg{2}; 72 | if ~all(size(x1)==size(x2)) 73 | error('x1 and x2 must have the same size'); 74 | elseif size(x1,1) ~= 3 75 | error('x1 and x2 must be 3xN'); 76 | end 77 | 78 | elseif length(arg) == 1 79 | if size(arg{1},1) ~= 6 80 | error('Single argument x must be 6xN'); 81 | else 82 | x1 = arg{1}(1:3,:); 83 | x2 = arg{1}(4:6,:); 84 | end 85 | else 86 | error('Wrong number of arguments supplied'); 87 | end -------------------------------------------------------------------------------- /html/main_msac.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | main_msac
clc;
 70 | clear all;
 71 | I1= imread('gang1.bmp');
 72 | I1=rgb2gray(I1);  %把RGB图像变成灰度图像
 73 | I2= imread('gang2.bmp');
 74 | I2=rgb2gray(I2);
 75 | 
 76 | 
 77 | %寻找特征点
 78 | % points1 = detectHarrisFeatures(I1);  %读取特征点,'MinQuality',0.005
 79 | % points2 = detectHarrisFeatures(I2);
 80 |  points1 = detectKAZEFeatures(I1);
 81 |  points2 = detectKAZEFeatures(I2);
 82 | % points1 = detectMSERFeatures(I1);
 83 | % points2 = detectMSERFeatures(I2);
 84 | % points1 = detectBRISKFeatures(I1);
 85 | % points2 = detectBRISKFeatures(I2);
 86 | 
 87 | %Extract the features.计算描述向量
 88 | [f1, vpts1] = extractHOGFeatures(I1, points1);
 89 | % I1为3-D彩色图像或2-D灰度图像,f1为1xN的HOG描述子向量,N为描述子的长度,该描述子是输入图像区域的局部形状信息编码。当指定Points1(同extractFeatures函数输入Points)时,则获取指定点附近的HOG描述子,visualization表示可用于任何可视化的函数的输入参数,例如plot(visualization),Name为用一对单引号包含的字符串,Value为对应Name的值。
 90 | [f2, vpts2] = extractHOGFeatures(I2, points2);
 91 | 
 92 | %进行匹配
 93 | indexPairs = matchFeatures(f1, f2,'Method','NearestNeighborSymmetric','MatchThreshold',100) ;
 94 | %用'Method','NearestNeighborSymmetric',阈值调节用'MatchThreshold',范围0-100,表示选择最强的匹配的百分比,越大匹配点越多
 95 | %用'Method','NearestNeighborRatio',阈值调节'MaxRatio',0.7,范围0-1,默认0.6,较大该值获得较多匹配
 96 | matched_pts1 = vpts1(indexPairs(:, 1));
 97 | matched_pts2 = vpts2(indexPairs(:, 2));
 98 | 
 99 | resultpairs1 = matched_pts1.Location; %存储匹配点坐标
100 | resultpairs2 = matched_pts2.Location;
101 | 
102 | %显示匹配
103 | figure('name','匹配后的图像');
104 | showMatchedFeatures(I1,I2,matched_pts1,matched_pts2,'montage');
105 | legend('matched points 1','matched points 2');
106 | 
107 |  %MSAC去除误匹配点
108 | [tform, inlierBoxPoints, inlierScenePoints] = estimateGeometricTransform(matched_pts1, matched_pts2, 'projective');
109 | 
110 | %  % ransac去除误匹配点
111 | %  Ipts1=(resultpairs1)';
112 | %  Ipts2=(resultpairs2)';
113 | %  [H, inliers] = ransacfithomography(Ipts1,Ipts2, .05);
114 | %  inlierBoxPoints = [Ipts1(2,inliers)' Ipts1(1,inliers)'];
115 | %  inlierScenePoints = [Ipts2(2,inliers)' Ipts2(1,inliers)'];
116 | figure;
117 | showMatchedFeatures(I1, I2, inlierBoxPoints, inlierScenePoints, 'montage','Parent',axes);
118 | title('MSAC去除误匹配点');
119 | 
警告: Maximum number of trials reached. Consider increasing the maximum
120 | distance or decreasing the desired confidence. 
121 | 
-------------------------------------------------------------------------------- /html/main_msac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devenin/Multi-sensor-images-matching/3f5bb69dd34bf3fc04e9e69257d5b592bc7cc3af/html/main_msac.png -------------------------------------------------------------------------------- /html/main_msac_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devenin/Multi-sensor-images-matching/3f5bb69dd34bf3fc04e9e69257d5b592bc7cc3af/html/main_msac_01.png -------------------------------------------------------------------------------- /html/main_msac_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devenin/Multi-sensor-images-matching/3f5bb69dd34bf3fc04e9e69257d5b592bc7cc3af/html/main_msac_02.png -------------------------------------------------------------------------------- /iscolinear.m: -------------------------------------------------------------------------------- 1 | function r = iscolinear(p1,p2,p3,flag) 2 | 3 | if nargin ==3 4 | flag='inhomog'; 5 | end 6 | if ~all(size(p1)==size(p2))|~all(size(p1)==size(p3))|... 7 | ~(length(p1)==2|length(p1)==3) 8 | error('points must have the same dimension of 2 or 3'); 9 | end 10 | if length(p1)==2 11 | p1(3)=1;p2(3)=1;p3(3)=1; 12 | end 13 | if flag(1)=='h' 14 | r=abs(dot(cross(p1,p2),p3))x2. 9 | % t - The distance threshold between data point and the model 10 | % used to decide whether a point is an inlier or not. 11 | % Note that point coordinates are normalised to that their 12 | % mean distance from the origin is sqrt(2). The value of 13 | % t should be set relative to this, say in the range 14 | % 0.001 - 0.01 15 | % 16 | % Note that it is assumed that the matching of x1 and x2 are putative and it 17 | % is expected that a percentage of matches will be wrong. 18 | % 19 | % Returns: 20 | % H - The 3x3 homography such that x2 = H*x1. 21 | % inliers - An array of indices of the elements of x1, x2 that were 22 | % the inliers for the best model. 23 | % 24 | % See Also: ransac, homography2d, homography1d 25 | 26 | % Copyright (c) 2004-2005 Peter Kovesi 27 | % School of Computer Science & Software Engineering 28 | % The University of Western Australia 29 | % http://www.csse.uwa.edu.au/ 30 | % 31 | % Permission is hereby granted, free of charge, to any person obtaining a copy 32 | % of this software and associated documentation files (the "Software"), to deal 33 | % in the Software without restriction, subject to the following conditions: 34 | % 35 | % The above copyright notice and this permission notice shall be included in 36 | % all copies or substantial portions of the Software. 37 | % 38 | % The Software is provided "as is", without warranty of any kind. 39 | 40 | % February 2004 - original version 41 | % July 2004 - error in denormalising corrected (thanks to Andrew Stein) 42 | % August 2005 - homogdist2d modified to fit new ransac specification. 43 | 44 | function [H, inliers] = ransacfithomography(x1, x2, t) 45 | 46 | if ~all(size(x1)==size(x2)) 47 | error('Data sets x1 and x2 must have the same dimension'); 48 | end 49 | 50 | [rows,npts] = size(x1); 51 | if rows~=2 & rows~=3 52 | error('x1 and x2 must have 2 or 3 rows'); 53 | end 54 | 55 | if npts < 4 56 | error('Must have at least 4 points to fit homography'); 57 | end 58 | 59 | if rows == 2 % Pad data with homogeneous scale factor of 1 60 | x1 = [x1; ones(1,npts)]; 61 | x2 = [x2; ones(1,npts)]; 62 | end 63 | 64 | % Normalise each set of points so that the origin is at centroid and 65 | % mean distance from origin is sqrt(2). normalise2dpts also ensures the 66 | % scale parameter is 1. Note that 'homography2d' will also call 67 | % 'normalise2dpts' but the code in 'ransac' that calls the distance 68 | % function will not - so it is best that we normalise beforehand. 69 | [x1, T1] = normalise2dpts(x1); 70 | [x2, T2] = normalise2dpts(x2); 71 | 72 | s = 4; % Minimum No of points needed to fit a homography. 73 | 74 | fittingfn = @homography2d; 75 | distfn = @homogdist2d; 76 | degenfn = @isdegenerate; 77 | % x1 and x2 are 'stacked' to create a 6xN array for ransac 78 | [H, inliers] = ransac([x1; x2], fittingfn, distfn, degenfn, s, t); 79 | 80 | % Now do a final least squares fit on the data points considered to 81 | % be inliers. 82 | H = homography2d(x1(:,inliers), x2(:,inliers)); 83 | 84 | % Denormalise 85 | H = T2\H*T1; 86 | 87 | %---------------------------------------------------------------------- 88 | % Function to evaluate the symmetric transfer error of a homography with 89 | % respect to a set of matched points as needed by RANSAC. 90 | 91 | function [inliers, H] = homogdist2d(H, x, t); 92 | 93 | x1 = x(1:3,:); % Extract x1 and x2 from x 94 | x2 = x(4:6,:); 95 | 96 | % Calculate, in both directions, the transfered points 97 | Hx1 = H*x1; 98 | invHx2 = H\x2; 99 | 100 | % Normalise so that the homogeneous scale parameter for all coordinates 101 | % is 1. 102 | 103 | x1 = hnormalise(x1); 104 | x2 = hnormalise(x2); 105 | Hx1 = hnormalise(Hx1); 106 | invHx2 = hnormalise(invHx2); 107 | 108 | d2 = sum((x1-invHx2).^2) + sum((x2-Hx1).^2); 109 | inliers = find(abs(d2) < t); 110 | 111 | 112 | %---------------------------------------------------------------------- 113 | % Function to determine if a set of 4 pairs of matched points give rise 114 | % to a degeneracy in the calculation of a homography as needed by RANSAC. 115 | % This involves testing whether any 3 of the 4 points in each set is 116 | % colinear. 117 | 118 | function r = isdegenerate(x) 119 | 120 | x1 = x(1:3,:); % Extract x1 and x2 from x 121 | x2 = x(4:6,:); 122 | 123 | r = ... 124 | iscolinear(x1(:,1),x1(:,2),x1(:,3)) | ... 125 | iscolinear(x1(:,1),x1(:,2),x1(:,4)) | ... 126 | iscolinear(x1(:,1),x1(:,3),x1(:,4)) | ... 127 | iscolinear(x1(:,2),x1(:,3),x1(:,4)) | ... 128 | iscolinear(x2(:,1),x2(:,2),x2(:,3)) | ... 129 | iscolinear(x2(:,1),x2(:,2),x2(:,4)) | ... 130 | iscolinear(x2(:,1),x2(:,3),x2(:,4)) | ... 131 | iscolinear(x2(:,2),x2(:,3),x2(:,4)); --------------------------------------------------------------------------------