题目:自定义一个图像的平移变换函数myImageTranslation,用于平移给定的输入图像,要求该函数的输入参数包括处理前的图像img1、垂直方向的平移步长delta_v和水平方向的平移步长delta_h,输出参数为处理后的图像img2。
说明:函数模板为img2 = myImageTranslation(img1, delta_v, delta_h),其中,平移后的图像img2必须和输入图像img1的大小相同,若平移后新坐标溢出img1的坐标范围,则用值0来填充该坐标处的灰度值,否则用img1中相应像素点的灰度值进行赋值,delta_v和delta_h必须是整数(可以是正或负整数);要求能处理灰度图像EXP2A.tif和彩色图像EXP2B.bmp。
实现思路:
1.首先使用abs()函数将分别取水平v和垂直位移h的绝对值,使用size()函数获取图像的宽和高以及层数,即图像数据的行数r和列数c以及维数l;
2.判断水平位移和垂直位移的大小:若水平位移或垂直位移大于图片的宽度或长度,则构造一个与原图像相同行数、列数、层数的零矩阵,输出矩阵,即直接输出与原图像相同大小的黑色图像;若水平位移和垂直位移都为0,则直接输出原图像;否则,继续下面的步骤;
3. 构造矩阵:①构造行数为h、列数为c、层数为l的零矩阵,用于插入图片的上方或下方,其中当垂直位移小于0时插入图像的下方,当垂直位移大于0时插入图像的上方;②构造行数为(r + h)、列数为v、层数为l的零矩阵,用于插入图片的左方或右方,其中当水平位移小于0时插入图像的右方,当水平位移大于0时插入图像的左方;
4.插入两个零矩阵:分别判断水平位移和垂直位移的大小,将步骤3中构造的矩阵按规则分别插入图像的上方或下方以及图像的左方或右方;
5.裁剪图像并输出:根据水平位移和垂直位移的大小裁剪图像,即裁剪图像中插入零矩阵的角落,例如水平位移和垂直位移均大于0时,分别的图像的左方和上方插入零矩阵,那么在裁剪图像时应该裁剪图像的左上角,参见图1。
图1 图像水平位移+v 垂直位移+h 原理示意图
该算法的时间复杂度为O(1),效率更高。
实现效果演示:
图2 灰度图像平移
图3 彩色图像平移
实现源代码:
function img2 = myImageTranslation(img1, delta_v, delta_h)%参数分别为图像矩阵、水平位移、垂直位移 %%取位移的绝对值 abs_delta_v = abs(delta_v); abs_delta_h = abs(delta_h); %%将图像uint8类型的数据转换为double类型的同时,把数据范围由原来的0~255映射到0~1,可以看作数据的一种归一化,以便计算 img = im2double(img1); %获取图像的宽和高以及层数,即图像数据的行数r和列数c以及维数l [r,c,l] = size(img); %如果平移的水平位移或垂直位移大于图像的宽度或高度,则直接输出黑色图像即可 if(abs_delta_h >= r || abs_delta_v >= c) img2 = zeros(r,c,l); return elseif(abs_delta_h == 0 && abs_delta_v == 0)%当水平和垂直位移都为0时,输出原图像 img2 = img; return end %%构造矩阵 rows = zeros(abs_delta_h,c,l);%用于插入图像的上方或下方,当垂直位移为负时插入图像的下方 cols = zeros(r + abs_delta_h,abs_delta_v,l);%用于插入图像的左方或右方,当垂直位移为负时插入图像的右方 if(delta_v < 0)%当水平位移为负时插入图像的下方 img = [img;rows]; if(delta_h < 0)%当垂直位移为负时插入图像的右方 img = [img,cols]; img2 = img(abs_delta_h:end,abs_delta_v:end,:);%输出右下角 elseif(delta_h > 0)%当垂直位移为正时插入图像的左方 img = [cols,img]; img2 = img(abs_delta_h:end,1:c,:);%输出右下角 end elseif(delta_v > 0)%当水平位移为正时插入图像的上方 img = [rows;img]; if(delta_h < 0) img = [img,cols]; img2 = img(1:r,abs_delta_v:end,:);%输出右上角 elseif(delta_h > 0) img = [cols,img]; img2 = img(1:r,1:c,:);%输出左上角 end else%当水平位移为0时垂直方向不操作 if(delta_h < 0) img = [img,cols]; img2 = img(1:r,abs_delta_v:end,:);%输出图像右方 elseif(delta_h > 0) img = [cols,img]; img2 = img(1:r,1:c,:);%输出图像左方 end end [r2,c2,l2] = size(img2) end clc; clear; %%%%%%%%%%%%%%%%%%%%%%%黑白%%%%%%%%%%%%%%%%%%%%%%%%%%%%% img1 = imread('EXP2A.tif'); delta_v = 600; delta_h = 0; img2 = myImageTranslation(img1, delta_v, delta_h); figure('NumberTitle', 'off', 'Name', '实验二第一题 图像平移 黑白'); subplot(2,2,1); imshow(img1); title('原始图像'); subplot(2,2,2); imshow(img2); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']); delta_v = 100; delta_h = 50; img3 = myImageTranslation(img1, delta_v, delta_h); subplot(2,2,3); imshow(img3); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']); delta_v = -70; delta_h = -120; img4 = myImageTranslation(img1, delta_v, delta_h); subplot(2,2,4); imshow(img4); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']); %%%%%%%%%%%%%%%%%%%%%%%彩色%%%%%%%%%%%%%%%%%%%%%%%%%%%%% img1 = imread('EXP2B.bmp'); delta_v = 200; delta_h = 50; img2 = myImageTranslation(img1, delta_v, delta_h); figure('NumberTitle', 'off', 'Name', '实验二第一题 图像平移 彩色'); subplot(2,2,1); imshow(img1); title('原始图像'); subplot(2,2,2); imshow(img2); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']); delta_v = -100; delta_h = 50; img3 = myImageTranslation(img1, delta_v, delta_h); subplot(2,2,3); imshow(img3); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']); delta_v = -70; delta_h = -120; img4 = myImageTranslation(img1, delta_v, delta_h); subplot(2,2,4); imshow(img4); title(['平移后的图像:水平',num2str(delta_v),'像素,垂直',num2str(delta_h),'像素']);
