利用Matlab进行图像的几何运算

目录

本文章包含以下内容:

代码如下:(可全部放到 function U() 中)

结果示例:

几何运算函数:

旋转

缩放

裁剪

镜像

平移


本文章包含以下内容:

1、编程实现图像的旋转(imrotate);

2、编程实现图像的按比例缩放(imresize);

3、编程实现图像的裁剪(imcrop)。

4、编程实现图像的镜像变换(水平、垂直和对角镜像);

5、编程实现图像的平移。

代码如下:(可全部放到 function U() 中)

function U()
clear;
clc;
%img = imread('cameraman.tif');   % 读取文件
img = imread('peppers.png');      % 读取文件
figure('Name', '原图');           % 开一个标题为“原图”的窗口
imshow(img);                      % 显示原图
figure('Name', '旋转');           % 开一个标题为“旋转”的窗口
subplot(2,2,1);imshow(xuanzhuan(img,  30));title('旋转  30°');
subplot(2,2,2);imshow(xuanzhuan(img,  90));title('旋转  90°');
subplot(2,2,3);imshow(xuanzhuan(img, -60));title('旋转- 60°');
subplot(2,2,4);imshow(xuanzhuan(img,-180));title('旋转-180°');
figure('Name', '缩放');           % 开一个标题为“缩放”的窗口
subplot(2,2,1);imshow(suofang(img,-1));title('缩放-1(倍数错误提示)');
subplot(2,2,2);imshow(suofang(img,1));title('缩放1.0');
subplot(2,2,3);imshow(suofang(img,0.15));title('缩放0.15');
subplot(2,2,4);imshow(suofang(img,2.7));title('缩放2.7');
figure('Name', '裁剪');           % 开一个标题为“裁剪”的窗口
subplot(2,2,1);imshow(caijian(img,50,80,160,220));title('裁剪,50,80,160,220');
subplot(2,2,2);imshow(caijian(img,-80,10,200,200));title('裁剪,80,1,200,200(负位置错误)');
subplot(2,2,3);imshow(caijian(img,1e4,1e4,1e5,1e5));title('裁剪1e4,1e4,1e5,1e5(超界错误)');
subplot(2,2,4);imshow(caijian(img,200,220,10,100));title('裁剪200,220,10,100(负裁剪区域错误)');
figure('Name', '镜像');           % 开一个标题为“镜像”的窗口
subplot(2,2,1);imshow(jingxiang(img,'x'));title('水平镜像(x)');
subplot(2,2,2);imshow(jingxiang(img,'y'));title('垂直镜像(y)');
subplot(2,2,3);imshow(jingxiang(img,'xy'));title('对角镜像(xy)');
subplot(2,2,4);imshow(jingxiang(img,'z'));title('错误镜像(错误输入)');
figure('Name', '平移');           % 开一个标题为“平移”的窗口
subplot(2,2,1);imshow(pingyi(img,90,60));title('平移90,60°');
subplot(2,2,2);imshow(pingyi(img,60,-190));title('平移60,-190');
subplot(2,2,3);imshow(pingyi(img,-120,-60));title('平移-120,-60');
subplot(2,2,4);imshow(pingyi(img,-180,20));title('平移-180,20');




function img2=xuanzhuan(img,x)            % 旋转函数,(图像,角度)
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    M=a(1);
    N=a(2);
    cx=cosd(x);            % 计算cos(x)
    sx=sind(x);            % 计算sin(x)
    R=[cx,sx,0;-sx,cx,0;0,0,1];           % 旋转矩阵
    R_=R';                 % 旋转矩阵的逆矩阵
    len=[[1,M,1,M];[1,1,N,N];[1,1,1,1]];  % 分别得到图像4个点
    len = R * len;            % 计算移动后的四角点
    x=abs(round(max(len(1,:))-min(len(1,:))));      % 得到旋转后的x大小
    y=abs(round(max(len(2,:))-min(len(2,:))));      % 得到旋转后的y大小
    if length(a)==3           % 如果是RGB
        img2=zeros(x,y,a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(x,y);      % 创建全0矩阵
    end
    im2=[x/2,y/2,0];    % 旋转后图像中心点,用于旋转前平移
    im0=[M/2,N/2,1];    % 原图像中心点,用于旋转后平移
    % 如果由原图映射到旋转后图像,会产生空洞,所以由旋转后图像寻找原像素更佳。
    % 将旋转后的矩阵平移到原点,逆旋转回去,之后再平移原图像中心点的位置
    for i = 1:x
        for j = 1:y
            a=([i,j,0]-im2)*R_+im0;
            % 如果逆变换回去发现点在原图像外,就不赋值。
            if (a(1)<=M)&&(a(1)>=0.5)&&(a(2)<=N)&&(a(2)>=0.5)
                img2(i,j,:)=img(round(a(1)),round(a(2)),:);
            end
        end
    end
    
function img2=suofang(img,s)            % 缩放函数,(图像,缩放比例(>0))
    if s<=0
        fprintf('缩放函数比例错误,请使比例>0\n');
        img2=img;
        return
    end
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    x=round(a(1)*s);       % 得到缩放后的x大小
    y=round(a(2)*s);       % 得到缩放后的y大小
    if length(a)==3           % 如果是RGB
        img2=zeros(x,y,a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(x,y);      % 创建全0矩阵
    end
    % 无论缩放比例多少,都是由新图像素点找原图像素点,防止出现空洞。
    for i = 1:x
        for j = 1:y
            M=round(i/s);
            N=round(j/s);
            if M>0&&N>0&&M<=a(1)&&N<=a(2) % 防止出现索引错误
                img2(i,j,:)=img(M,N,:);
            end
        end
    end

function img2=caijian(img,a,b,c,d)      % 裁剪函数,(图像,裁剪后大小)
	if a<=1||b<=1||c<=1||d<=1
        fprintf('裁剪大小错误,裁剪位置应>=1\n');
        img2=img;
        return
    end
    img=im2double(img);    % 转double 不然显示会成2值图像
    s=size(img);           % 得到图像大小
    if a>=s(1)||b>=s(2)||c>=s(1)||d>=s(2)
        fprintf('裁剪大小错误,裁剪位置应<=图像边界大小\n');
        img2=img;
        return
    end
    x=c-a+1;       % 得到裁剪后的x大小
    y=d-b+1;       % 得到裁剪后的y大小
    if x<1||y<1
        fprintf('裁剪大小错误,裁剪位置应a<=c,b<=d\n');
        img2=img;
        return
    end
    img2=img(a:c,b:d,:);
    
    
function img2=jingxiang(img,x)          % 镜像函数,(图像,变换类型('x','y','xy'))
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    switch x               % 根据x不同,进行不同的变换
        case 'y'
            img2(1:a(1),1:a(2),:)=img(a(1):-1:1,1:a(2),:);
        case 'x'
            img2(1:a(1),1:a(2),:)=img(1:a(1),a(2):-1:1,:);
        case 'xy'
            img2(1:a(1),1:a(2),:)=img(a(1):-1:1,a(2):-1:1,:);
        otherwise
            fprintf('不是字符x,y,或xy,请检查输入');
          img2=img;
    end
    
    
function img2=pingyi(img,y,x)           % 平移函数,(图像,x平移距离,y平移距离)
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    if length(a)==3           % 如果是RGB
        img2=zeros(a(1)+abs(x),a(2)+abs(y),a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(a(1)+abs(x),a(2)+abs(y));      % 创建全0矩阵
    end
    for i=1:a(1)
        for j=1:a(2)
            if(x<0 && y<0)
                img2(i,j,:)=img(i,j,:); %如果进行左上移动,对新图像矩阵进行赋值
            elseif(x>0 && y>0)
                img2(i+x,j+y,:)=img(i,j,:); %如果进行右下移动,对新图像矩阵进行赋值
            elseif(x>0 && y<0)
                img2(i+x,j,:)=img(i,j,:); %如果进行右上移动,对新图像矩阵进行赋值
            else
                img2(i,j+y,:)=img(i,j,:); %如果进行左下移动,对新图像矩阵进行赋值
            end
        end
    end 
    

结果示例:

缩放函数比例错误,请使比例>0
裁剪大小错误,裁剪位置应>=1
裁剪大小错误,裁剪位置应<=图像边界大小
裁剪大小错误,裁剪位置应a<=c,b<=d
不是字符x,y,或xy,请检查输入>> 

几何运算函数:

旋转

function img2=xuanzhuan(img,x)            % 旋转函数,(图像,角度)
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    M=a(1);
    N=a(2);
    cx=cosd(x);            % 计算cos(x)
    sx=sind(x);            % 计算sin(x)
    R=[cx,sx,0;-sx,cx,0;0,0,1];           % 旋转矩阵
    R_=R';                 % 旋转矩阵的逆矩阵
    len=[[1,M,1,M];[1,1,N,N];[1,1,1,1]];  % 分别得到图像4个点
    len = R * len;            % 计算移动后的四角点
    x=abs(round(max(len(1,:))-min(len(1,:))));      % 得到旋转后的x大小
    y=abs(round(max(len(2,:))-min(len(2,:))));      % 得到旋转后的y大小
    if length(a)==3           % 如果是RGB
        img2=zeros(x,y,a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(x,y);      % 创建全0矩阵
    end
    im2=[x/2,y/2,0];    % 旋转后图像中心点,用于旋转前平移
    im0=[M/2,N/2,1];    % 原图像中心点,用于旋转后平移
    % 如果由原图映射到旋转后图像,会产生空洞,所以由旋转后图像寻找原像素更佳。
    % 将旋转后的矩阵平移到原点,逆旋转回去,之后再平移原图像中心点的位置
    for i = 1:x
        for j = 1:y
            a=([i,j,0]-im2)*R_+im0;
            % 如果逆变换回去发现点在原图像外,就不赋值。
            if (a(1)<=M)&&(a(1)>=0.5)&&(a(2)<=N)&&(a(2)>=0.5)
                img2(i,j,:)=img(round(a(1)),round(a(2)),:);
            end
        end
    end

缩放

function img2=suofang(img,s)            % 缩放函数,(图像,缩放比例(>0))
    if s<=0
        fprintf('缩放函数比例错误,请使比例>0\n');
        img2=img;
        return
    end
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    x=round(a(1)*s);       % 得到缩放后的x大小
    y=round(a(2)*s);       % 得到缩放后的y大小
    if length(a)==3           % 如果是RGB
        img2=zeros(x,y,a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(x,y);      % 创建全0矩阵
    end
    % 无论缩放比例多少,都是由新图像素点找原图像素点,防止出现空洞。
    for i = 1:x
        for j = 1:y
            M=round(i/s);
            N=round(j/s);
            if M>0&&N>0&&M<=a(1)&&N<=a(2) % 防止出现索引错误
                img2(i,j,:)=img(M,N,:);
            end
        end
    end

裁剪

function img2=caijian(img,a,b,c,d)      % 裁剪函数,(图像,裁剪后大小)
	if a<=1||b<=1||c<=1||d<=1
        fprintf('裁剪大小错误,裁剪位置应>=1\n');
        img2=img;
        return
    end
    img=im2double(img);    % 转double 不然显示会成2值图像
    s=size(img);           % 得到图像大小
    if a>=s(1)||b>=s(2)||c>=s(1)||d>=s(2)
        fprintf('裁剪大小错误,裁剪位置应<=图像边界大小\n');
        img2=img;
        return
    end
    x=c-a+1;       % 得到裁剪后的x大小
    y=d-b+1;       % 得到裁剪后的y大小
    if x<1||y<1
        fprintf('裁剪大小错误,裁剪位置应a<=c,b<=d\n');
        img2=img;
        return
    end
    img2=img(a:c,b:d,:);

镜像

function img2=jingxiang(img,x)          % 镜像函数,(图像,变换类型('x','y','xy'))
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    switch x               % 根据x不同,进行不同的变换
        case 'y'
            img2(1:a(1),1:a(2),:)=img(a(1):-1:1,1:a(2),:);
        case 'x'
            img2(1:a(1),1:a(2),:)=img(1:a(1),a(2):-1:1,:);
        case 'xy'
            img2(1:a(1),1:a(2),:)=img(a(1):-1:1,a(2):-1:1,:);
        otherwise
            fprintf('不是字符x,y,或xy,请检查输入');
          img2=img;
    end

平移

function img2=pingyi(img,y,x)           % 平移函数,(图像,x平移距离,y平移距离)
    img=im2double(img);    % 转double 不然显示会成2值图像
    a=size(img);           % 得到图像大小
    if length(a)==3           % 如果是RGB
        img2=zeros(a(1)+abs(x),a(2)+abs(y),a(3));    % 创建RGB全0矩阵
    else
        img2=zeros(a(1)+abs(x),a(2)+abs(y));      % 创建全0矩阵
    end
    for i=1:a(1)
        for j=1:a(2)
            if(x<0 && y<0)
                img2(i,j,:)=img(i,j,:); %如果进行左上移动,对新图像矩阵进行赋值
            elseif(x>0 && y>0)
                img2(i+x,j+y,:)=img(i,j,:); %如果进行右下移动,对新图像矩阵进行赋值
            elseif(x>0 && y<0)
                img2(i+x,j,:)=img(i,j,:); %如果进行右上移动,对新图像矩阵进行赋值
            else
                img2(i,j+y,:)=img(i,j,:); %如果进行左下移动,对新图像矩阵进行赋值
            end
        end
    end 
    

你可能感兴趣的:(matlab,图像处理,开发语言)