Matlab之山东大学数字图像处理实验二(几何变换与变形)

本文属于原创,转载请注明出处。
实验2.1:图像缩放

  • 实现一个图像缩放函数,可以对输入图像进行任意倍数的缩放;
  • 采用双线性插值进行重采样;
  • X,Y方向的缩放倍数参函数参数的形式传入;
  • 可以只考虑输入图像为3通道,8位深度的情况;
  • 不能调用图像处理库的缩放函数来完成;

实验2.2:图像变形
记[x’, y’]=f([x, y])为像素坐标的一个映射,实现f所表示的图像形变。f的逆映射为:
Matlab之山东大学数字图像处理实验二(几何变换与变形)

Matlab之山东大学数字图像处理实验二(几何变换与变形)

在讲实验之前,先说一下变量,之后的变量都是这样,水平方向为height或y,垂直方向为width或x。
Matlab之山东大学数字图像处理实验二(几何变换与变形)
实验2.1:图像缩放
图像缩放要求使用双线性差值算法,算法如下:
Matlab之山东大学数字图像处理实验二(几何变换与变形)

转到二维矩阵中,除掉四条边缘线,该算法可以解释为:
设x和y为缩放倍数,i,j为新图像的某个坐标,tempx,tempy为原图像的坐标,a和b为原图像坐标减去新图像坐标的小数部分,即上图公式中的x,y两个参数,其中floor()函数为向下取整函数,他们之间的关系为:

tempx = floor((i-1)/x);
tempy = floor((j-1)/y);

a = (i-1) / x - tempx;
b = (j-1) / y - tempy;

然后上图公式就可以转化成二维矩阵的公式:

output_img(i,j,:) = input_img(tempx,tempy,:)*(1-a)*(1-b)+input_img(tempx,tempy+1,:)*(1-a)*b...
                +input_img(tempx+1,tempy,:)*a*(1-b)+input_img(tempx+1,tempy+1,:)*a*b;

当然得对四条边缘进行处理,否则矩阵会越界,具体代码如下所示:

function resize( input_img,x,y )
%RESIZE 此处显示有关此函数的摘要
%   input_img为输入图像,output_img为输出图像,x,y为缩放倍数
[I,map] = imread(input_img);
input_img = imread(input_img);
%获取原图像的长宽
[width,height,dimension] = size(I);
%计算新图像的长宽
new_width = round(width*x);
new_height = round(height*y);
figure();
imshow(input_img);
title(['原图像(大小: ',num2str(width),'*',num2str(height),'*',num2str(dimension),')']);
%双线性差值法
for i = 1:new_width
    for j = 1:new_height
        %原来图像的坐标,向下取整
        tempx = floor((i-1)/x);
        tempy = floor((j-1)/y);
        %对四条边和四个顶点进行处理
        if tempx == 0 || tempy == 0 || tempx == width-1 || tempy == height-1
            output_img(1,j,:) = input_img(1,tempy+1,:);
            output_img(i,1,:) = input_img(tempx+1,1,:);
        %对其余像素进行处理
        else
            %计算原图像坐标减去新图像坐标的小数部分
            a = (i-1) / x - tempx;
            b = (j-1) / y - tempy;
            %最小值为1
            tempx = tempx+1;
            tempy = tempy+1;
            output_img(i,j,:) = input_img(tempx,tempy,:)*(1-a)*(1-b)+input_img(tempx,tempy+1,:)*(1-a)*b...
                +input_img(tempx+1,tempy,:)*a*(1-b)+input_img(tempx+1,tempy+1,:)*a*b;
        end
    end
end
figure();
imshow(output_img);
title(['缩放后的图像(大小: ',num2str(new_width),'*',num2str(new_height),'*',num2str(dimension)',')']);
imwrite(output_img,'resize.jpg');

现在看看缩放效果:
Matlab之山东大学数字图像处理实验二(几何变换与变形)

resize('a.jpg',1.3,0.6);

Matlab之山东大学数字图像处理实验二(几何变换与变形)

实验2.2:图像变形
这里的公式在实验要求之中,这里就不多说了,直接给出代码:

function reshape(input_img)
%RESHAPE 此处显示有关此函数的摘要
%   input_img为输入图像,output_img为输出图像,angle为顺时针旋转角度
[I,map] = imread(input_img);
input_img = imread(input_img);
%获取原图像的长宽
[width,height,dimension] = size(I);
for i = 1:width-1
    for j = 1:height-1
        %中心归一化坐标
        tempx = (i-0.5*width)/(0.5*width);
        tempy = (j-0.5*height)/(0.5*height);
        %获取r和angle
        r  = sqrt(tempx^2 + tempy^2);
        angle = (1-r)^2;
        if r >= 1
            x = tempx;
            y = tempy;
        else
            x = cos(angle)*tempx - sin(angle)*tempy;
            y = sin(angle)*tempx + cos(angle)*tempy;
        end
        %必须使用(uint16()函数进行处理坐标,将其转化成无符号16位的int类型,否则坐标索引会出错
        old_x = uint16((x + 1)*0.5*width);
        old_y = uint16((y + 1)*0.5*height);
        %输出图像
        output_img(i,j,:) = input_img(old_x,old_y,:);
    end
end
imshow(output_img);
title('变形后的图像');
imwrite(output_img,'reshape.jpg');
end

这里唯一要注意的就是old_x = uint16((x + 1)*0.5*width);,这个地方得将原来中心归一化后的坐标转回到原来的坐标,并且使用uint16()函数进行处理,将其转化成无符号16位的int类型,否则坐标索引会出错。

re_shape('a.jpg');

下面看看效果:
Matlab之山东大学数字图像处理实验二(几何变换与变形)