其他分享
首页 > 其他分享> > 图像拼接matlab

图像拼接matlab

作者:互联网

图像拼接

声明

这是我本科期间的数字图像处理大作业,存在一定的问题无法保证一定可以使用。
且此篇文章为我第一次在CSDN上发布,可能存在一定的问题。
同时由于是在本科期间的课程大作业,内容原创性比较少轻喷(主要是将网上的一些和图像拼接有关的内容进行一个整合,这次文章的发布仅为一次实验)。
本篇文章会加入一些我自己的认为与理解,仅代表个人观点,轻喷。
希望不会有啥维权的问题,如果出现本人会删除这篇文章。

网上的几种方法

1.SIFT
2.Surf
3.角点检测
(网上的内容都挺详尽的,建议百度一下)

框图

写了个总的函数,加了点用户输入的部分。
在这里插入图片描述

在这里插入图片描述

Surf:

Alt

Harris:
alt

Coding

function  image_stitching(A,B,varargin)
%@Author    ;HuangWeiChen
%@Time      :2021/5/5


% Input:
% input_A :image 1
% input_B : image 2

% Output:
% output_image - combined new image

%@Note  :
%{
    1.No return ,show the combined image directly
    2.Without the GUI ,the function is stil working .
    Because I forget the gui so  I do this function better.
    That's the reason why has this function .

    The main.m is the test file maybe it is a reference,
    so i still save it.

%}


%@Power ;1. Detecting the input image is null or not.
%           Detecting the image dimension is matching or not
%          
%         2.if the input is too big and the use choose the harris,
%         it will run a long time ,so I detect the image size.
%          When the size is bigger than 2000,I suggest the use to using
%          SURF,so I wirte the input code . User choose YES
%          --SURF,whether NO --just run the harris
%         3. it will show the Corner point
%
%@TODO  :The SURF do only run with gray image. If you want run wiht
%        GRB,maybe bulid a new file.
%       : harris is too slow!!!!!!!!!!!!!!!!!!!


%%%%%%%%%%%%%%%%%%%%%%%%%
%{
    Sample:

addpath('resource');
addpath('Image');

imagePath = 'Image\eyes';
first = 1;
second = 2;
buildingScene = imageSet(imagePath);
A = read(buildingScene, first);
B= read(buildingScene, second);

A = rgb2gray(A);
B = rgb2gray(B);



% These functions you can choose,it big enough(smile)
 
image_stitching(A,B,'SURF');
% image_stitching(A,B,'SURF','write');
% image_stitching(A,B,'harris');
% image_stitching(A,B);
% image_stitching(A,B,'harris','write');
% image_stitching(A,B,'harris','Corner');

%}

%%%%%%%%%%%%%%%%%%%%%%%%%



%% detect input
if isempty(A)
    error('the first image is empty!');
elseif isempty(B)
    error('the second image is empty!');
end



Size_A =max(size(A));
Size_B =max(size(B));

dimension_A=numel(size(A));
dimension_B = numel(size(B));

if dimension_B *dimension_A~=9&&dimension_B *dimension_A~=4
    error('the input image dimension is not correct,they should have the same dimension');
end

%% image is too big
times = 1;

while(1)
    if times ==1
        if  Size_A>2000||Size_B>2000
            
            prompt={   'the image is too big,we think you should use SURF,  Yes   or   No'  };
            name='Warring';
            numlines=1;
            defaultanswer={'Yes'};
            
            options.Resize='on';
            options.WindowStyle='normal';
            options.Interpreter='tex';
            
            answer=inputdlg(prompt,name,numlines,defaultanswer,options);
            

        else
            flag = -1;
            break;
        end
        
    else
        string = answer;
        if string =="Yes"
            flag = 1;
            break;
        elseif string =="No"
            flag = -1;
            break;
        else
            disp("Please input the right string!!");
        end
        
    end
    times =times +1;
    
    
end

%% choose a way
if flag == 1
    MSURF(A ,B);
else
    if nargin == 3
        if varargin{1} ~="harris"&&varargin{1} ~="SURF"
            error('the first input string is incorrect! ');
            
        elseif  varargin{1} =="SURF"
            MSURF(A ,B);
        elseif varargin{1} =="harris"
            
            [newImage]= Mharris(A,B);
            figure('Name',"Harris,3");
            imshow(uint8(newImage));
            
            
        end
    elseif nargin == 2
        [newImage]= Mharris(A,B);
        figure('Name',"Harris,2")
        imshow( uint8(newImage));
    elseif nargin == 4
        if varargin{2}=="write"||varargin{2}=="Corner"
            if varargin{2}=="write"
                Mwrite = 1;
            else
                Mwrite = 0;
            end
            if varargin{2}=="Corner"
                Mcorner = 1;
            else
                Mcorner = 0;
                
            end
        else
            error('the second input string is incorrect');
        end
        
        if varargin{1} ~="harris"&&varargin{1} ~="SURF"
            error('the first input string is incorrect! ');
            
        elseif  varargin{1} =="SURF"
 
                output = MSURF(A ,B);

            
            
            
            if Mwrite ==1  %write
                saveas(output,'Output\SURF','png');
            elseif Mcorner ==1
                error("the SURF don't have the corner points!!");
            end
            
            
        elseif varargin{1} =="harris"
            
            [newImage,R1,R2]= Mharris(A,B,varargin{2});
            if Mcorner ==1
                figure('Name','Harris 3');
                imshow( uint8(newImage));
                
                figure('Name','Corner');
                subplot(121);
                imshow(R1);
                title('First');
                
                subplot(122);
                imshow(R2);
                title('Second');
                
            elseif Mwrite ==1
                figure('Name','Harris write');
                imshow( uint8(newImage));
                imwrite(uint8(newImage),'Output\Harris.png');
            else
                error('the input string is bug !!');
            end
            
        end
        
    end
end



end

Mharris:

function varargout= Mharris(A,B,varargin)
%% detect 3D
    detect_bug = numel(size(A))*numel(size(B));
    if detect_bug~=9&&detect_bug~=4
        error('The picture dimensions must be consistent! ')
        
    end
    
    if numel(size(A))>2
        A_gray =im2double(rgb2gray(A));
    else
        A_gray = im2double(A);
    end
    
    if numel(size(B))>2
        B_gray =im2double(rgb2gray(B));
    else
        B_gray = im2double(B);
    end
    
    %% size
    [height_wrap, width_wrap] = size(A_gray);
    [height_unwrap, width_unwrap] = size(B_gray);
    
    
    %%  find the cornet points in these two image
    [x_A, y_A, v_A, R1] = harris(A_gray, 2, 0.0, 2);
    [x_B, y_B, v_B, R2] = harris(B_gray, 2, 0.0, 2);
    
    %% (ANMS) Adaptive non-maximum suppression
    ncorners = 500;
    [x_A, y_A, ~] = ada_nonmax_suppression(x_A, y_A, v_A, ncorners);
    [x_B, y_B, ~] = ada_nonmax_suppression(x_B, y_B, v_B, ncorners);
    
    %%   get the features points
    sigma = 7;
    [des_A] = GFD(A_gray, x_A, y_A, sigma);
    [des_B] = GFD(B_gray, x_B, y_B, sigma);
    
    %%  distance A and B
    dist = distance(des_A,des_B);
    [ord_dist, index] = sort(dist, 2);
    %% ratio 
    % the ratio is better than distance 
    % the threshold is the tolerance
    ratio = ord_dist(:,1) ./ ord_dist(:,2);
    threshold = 0.5;
    idx = ratio < threshold;
    x_A = x_A(idx);
    y_A = y_A(idx);
    x_B = x_B(index(idx,1));
    y_B = y_B(index(idx,1));
    npoints = length(x_A);
    
    %% 使用4点随机抽样一致计算鲁棒单应性估计,保持第一张图像不扭曲。
    matcher_A = [y_A, x_A, ones(npoints,1)]'; %!!! previous x is y and y is x,
    matcher_B = [y_B, x_B, ones(npoints,1)]'; %!!! so switch x and y here.
    [hh, ~] = rmy(matcher_B, matcher_A, npoints, 10);
    
    %% 使用反向旋转方法确定整个图像的大小
    [newH, newW, newX, newY, xB, yB] = GNS(hh, height_wrap, width_wrap, height_unwrap, width_unwrap);
    
    [X,Y] = meshgrid(1:width_wrap,1:height_wrap);
    [XX,YY] = meshgrid(newX:newX + newW - 1, newY:newY + newH - 1);
    AA = ones(3,newH * newW);
    AA(1,:) = reshape(XX,1,newH * newW);
    AA(2,:) = reshape(YY,1,newH * newW);
    AA = hh * AA;
    XX = reshape(AA(1,:) ./ AA(3,:), newH, newW);
    YY = reshape(AA(2,:) ./ AA(3,:), newH, newW);
    
    %% Interp2 
    if numel(size(A))==2&&numel(size(B))==2
        newImage(:,:) = interp2(X, Y, double(A(:,:)), XX, YY);
        
    elseif numel(size(A))>2&&numel(size(B))>2
        newImage(:,:,1) = interp2(X, Y, double(A(:,:,1)), XX, YY);
        newImage(:,:,2) = interp2(X, Y, double(A(:,:,2)), XX, YY);
        newImage(:,:,3) = interp2(X, Y, double(A(:,:,3)), XX, YY);
    end
    %% output 
    if nargin == 2
        varargout{1} = Mblend(newImage, B, xB, yB);
    elseif  nargin == 3
        varargout{1} = Mblend(newImage, B, xB, yB);
        varargout{2} = R1;
        varargout{3} = R2;
    end
    
end

MSURF:

function output = MSURF(A ,B)


%% Input
dimension_A=numel(size(A));
dimension_B = numel(size(B));
if dimension_B *dimension_A==9
    color_flag = 1;
elseif dimension_B *dimension_A==4
    color_flag = 0;
else
    error('the input image dimension is not correct,they should have the same dimension');
end

%% imfliter
if color_flag ==1
    I1 = rgb2gray(A);
    I2 = rgb2gray(B);
elseif color_flag ==0
    I1 = (A);
    I2 = (B);

end

h = fspecial('gaussian',7,0.05);
I1 = imfilter(I1,h,'corr','replicate');
I2 = imfilter(I2,h,'corr','replicate');
I1 = imerode(I1,[0 1 0;0 1 0;0 1 0]);
I1 = imopen(I1,[0 0 0;1 1 1;0 0 0]);
I2 = imerode(I2,[0 1 0;0 1 0;0 1 0]);
I2 = imopen(I2,[0 0 0;1 1 1;0 0 0]);
%对原始图像滤波并采用纵向矩阵消除背景噪声和横向噪声,增大检测到的正确匹配点数目


%%  Backup

img1=I1;
img2=I2;


%% SURF
%input  :image
%Output :SURFPoints

points_1=detectSURFFeatures(img1);
points_2=detectSURFFeatures(img2);%检测SURF特征点


%% 特征向量

[img1Features, points_1] = extractFeatures(img1, points_1);%使用64维向量表示特征描述子,
%第一个返回的参数即为每个特征点对应的特征描述子,第二个参数是特征点
[img2Features, points_2] = extractFeatures(img2, points_2);

%% 用于特征点匹配
boxPairs = matchFeatures(img1Features, img2Features);%特征描述子匹配

%% find the Features points in all SURF points
matchedimg1Points = points_1(boxPairs(:, 1));%第二个参数:可以不加,因为其为n行1列的结构体数组
matchedimg2Points = points_2(boxPairs(:, 2));

%%
[tform, ~, ~] = ...
    estimateGeometricTransform(matchedimg2Points, matchedimg1Points, 'similarity');%射影变换,tfrom映射点对1内点到点对2内点
%该函数使用随机样本一致性(RANSAC)算法的变体MSAC算法实现,去除误匹配点
%The returned geometric transformation matrix maps the inliers in matchedPoints1
%to the inliers in matchedPoints2.返回的几何映射矩阵映射第一参数内点到第二参数内点
% 
% showMatchedFeatures(I1, I2, matchedimg1Points, ...
%     matchedimg2Points, 'montage');
% title('Matched Points (Inliers Only)');%显示匹配结果

%%
Rfixed = imref2d(size(I1));

[registered2, Rregistered] = imwarp(I2, tform);%图像射影变换,以图1作为基准
% [registered1, Rregistered1] = imwarp(I1, tform);%以图2作为基准
figure('Name','SURF');
output= imshowpair(I1,Rfixed,registered2,Rregistered,'blend');%图像拼接

里面有一些函数我没有放出来,我认为网上是都可以找到的。

我的一些认为

Surf: 由于matlab本身是有函数可以调用的,所以相对比较简单且速度很快,但是他会生成一种特殊的格式,其他的函数不太好调用。如果想修改的话,可能得从头开始写这个。
并且matlab里面的方法好像不能处理彩色的图片,得先变成灰度。

Harris:代码没有被打包,可以修改,复用性挺好的,就是速度有点慢。如果大尺寸的图片估计会卡死,建议先做一个图像的压缩。如果太大了建议还是使用Surf,感觉效果差不多。

一点展望

1.将不同维度的图片(一张彩色和一张灰度)的进行拼接,最后显示的有彩色的,有灰度(就是别直接把彩色变成灰度来处理)。
2.图片的大小不一定需要相同,可以用不同尺寸的图片进行拼接。
3.对多张有序的图片进行拼接。
4.对多张无序的图片进行拼接。

一个很不错的图像拼接项目
(无序多图拼接全景,但是存在一定参数的需要人为给定的问题)

标签:SURF,end,%%,image,拼接,matlab,图像,dimension,size
来源: https://blog.csdn.net/hopefullying/article/details/117301151