MATLAB【数字图像处理】 实验一:图像处理基本操作(平移、放大、缩小、旋转、插值) 您所在的位置:网站首页 matlab最近邻插值放大图片 MATLAB【数字图像处理】 实验一:图像处理基本操作(平移、放大、缩小、旋转、插值)

MATLAB【数字图像处理】 实验一:图像处理基本操作(平移、放大、缩小、旋转、插值)

2024-07-14 00:52| 来源: 网络整理| 查看: 265

目录 一、实验目的二、实验环境三、实验内容题目相关知识部分核心代码实验结果分析:两种插值法优缺点 四、实验心得

一、实验目的

1、熟悉并掌握MATLAB工具的使用;  2、实现图像的读取、显示、存储、平移、镜像、放大、缩小及旋转操作; 3、掌握常用的插值方法,并了解其优缺点。

二、实验环境

Matlab 2020B

三、实验内容 题目

1、读入一幅RGB图像,变换为灰度图像和二值图像,并在同一个窗口内分别显示RGB图像和灰度图像,注上文字标题,并将结果以文件形式存到磁盘上。 2、对图像执行平移、镜像(水平镜像、垂直镜像)放大、缩小及旋转操作,其中放大、旋转操作分别采用最近邻插值及双线性插值方法实现,要求根据算法自己编写代码实现,并分析两种插值方法的优缺点。

相关知识

在matlab环境中,调用imread()函数可读入图像,默认的存储方式为的矩阵,分RGB三个通道。值类型为uint8,即取值范围为0~255。

rgb2gray()函数将RGB三个通道存储的图像消除色调和饱和度,保留亮度,将RGB图像转为灰度图。 im2bw(I,level)函数基于阈值将图像转化为二值图像。输入图像可以为RGB图像,也可以为灰度图像。level参数为阈值取值范围为0到1之间的小数,将大于阈值的像素点变为白色(1),其他像素点变为黑色(0)。

图像平移时,设某个像素点坐标为 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​),经过平移 ( t x , t y ) (t_x,t_y) (tx​,ty​),达到坐标为 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​)。该关系可记为: { x 1 = x 0 + t x y 1 = y 0 + t y \begin{cases}x_1=x_0+t_x\\y_1=y_0+t_y\end{cases} {x1​=x0​+tx​y1​=y0​+ty​​,用矩阵形式可以记作: ( x 1 y 1 1 ) = ( x 0 y 0 1 ) ( 1 0 0 0 1 0 t x t y 1 ) \begin{pmatrix}x_1&y_1&1\end{pmatrix}=\begin{pmatrix}x_0&y_0&1\end{pmatrix}\begin{pmatrix}1&0&0\\0&1&0\\t_x&t_y&1\end{pmatrix} (x1​​y1​​1​)=(x0​​y0​​1​) ​10tx​​01ty​​001​ ​。在实现时,记图像的高为 h h h,宽为 w w w,需要判断 x 1 , y 1 x_1,y_1 x1​,y1​与 h , w h,w h,w的大小关系,不能发生下标越界。

图像水平镜像时,记图像宽为 w w w。则原像素点 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)变为 ( w − x 0 , y 0 ) (w-x_0,y_0) (w−x0​,y0​),即: { x 1 = w − x 0 y 1 = y 0 \begin{cases}x_1=w-x_0\\y_1=y_0\end{cases} {x1​=w−x0​y1​=y0​​。用矩阵形式记作: { x 1 = x 0 + t x y 1 = y 0 + t y \begin{cases}x_1=x_0+t_x\\y_1=y_0+t_y\end{cases} {x1​=x0​+tx​y1​=y0​+ty​​,用矩阵形式可以记作: ( x 1 y 1 1 ) = ( x 0 y 0 1 ) ( − 1 0 0 0 1 0 w 0 1 ) \begin{pmatrix}x_1&y_1&1\end{pmatrix}=\begin{pmatrix}x_0&y_0&1\end{pmatrix}\begin{pmatrix}-1&0&0\\0&1&0\\w&0&1\end{pmatrix} (x1​​y1​​1​)=(x0​​y0​​1​) ​−10w​010​001​ ​。

图像垂直镜像时,记图像高为 h h h。则原像素点 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)变为 ( x 0 , h − y 0 ) (x_0,h-y_0) (x0​,h−y0​),即: { x 1 = x 0 y 1 = h − y 0 \begin{cases}x_1=x_0\\y_1=h-y_0\end{cases} {x1​=x0​y1​=h−y0​​。用矩阵形式记作: ( x 1 y 1 1 ) = ( x 0 y 0 1 ) ( 1 0 0 0 − 1 0 0 h 1 ) \begin{pmatrix}x_1&y_1&1\end{pmatrix}=\begin{pmatrix}x_0&y_0&1\end{pmatrix}\begin{pmatrix}1&0&0\\0&-1&0\\0&h&1\end{pmatrix} (x1​​y1​​1​)=(x0​​y0​​1​) ​100​0−1h​001​ ​。

图像放大分为两个步骤:1.创建新的像素点位。2.给新的像素点位的对应位置赋值。

在使用最近邻插值法时,直接用原图中最近的像素点位给新图赋值。

在使用双线性插值法时,记原图大小 m ∗ n m*n m∗n,新图大小 a ∗ b a*b a∗b,则新图的坐标 ( x 0 ′ , y 0 ′ ) (x_0',y_0') (x0′​,y0′​)对应原图 ( x 0 , y 0 ) = ( x 0 ′ ∗ m / a , y 0 ′ ∗ n / b ) (x_0,y_0)=(x_0'*m/a,y_0'*n/b) (x0​,y0​)=(x0′​∗m/a,y0′​∗n/b)。找到与 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)最近的四个整数点位记作 ( x 1 , y 1 ) , ( x 1 , y 2 ) , ( x 2 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_1,y_2),(x_2,y_1),(x_2,y_2) (x1​,y1​),(x1​,y2​),(x2​,y1​),(x2​,y2​),其对应点位上的灰度值记为 P 11 , P 12 , P 21 , P 22 P_{11},P_{12},P_{21},P_{22} P11​,P12​,P21​,P22​。 则 ( x 0 ′ , y 0 ′ ) (x_0',y_0') (x0′​,y0′​)的灰度值为 y 2 − y 0 y 2 − y 1 ( x 2 − x 0 x 2 − x 1 P 11 + x 0 − x 1 x 2 − x 1 P 21 ) + y 0 − y 1 y 2 − y 1 ( x 2 − x 0 x 2 − x 1 P 12 + x 0 − x 1 x 2 − x 1 P 22 ) \frac{y_2-y_0}{y_2-y_1}(\frac{x_2-x_0}{x_2-x_1}P_{11}+\frac{x_0-x_1}{x_2-x_1}P_{21})+\frac{y_0-y_1}{y_2-y_1}(\frac{x_2-x_0}{x_2-x_1}P_{12}+\frac{x_0-x_1}{x_2-x_1}P_{22}) y2​−y1​y2​−y0​​(x2​−x1​x2​−x0​​P11​+x2​−x1​x0​−x1​​P21​)+y2​−y1​y0​−y1​​(x2​−x1​x2​−x0​​P12​+x2​−x1​x0​−x1​​P22​)

在实现时,可能需要去掉边框上的像素点值,以防止下标越界等情况。若 ( x 0 , y 0 ) = ( x 0 ′ ∗ m / a , y 0 ′ ∗ n / b ) (x_0,y_0)=(x_0'*m/a,y_0'*n/b) (x0​,y0​)=(x0′​∗m/a,y0′​∗n/b)为整数,则直接取该点灰度值赋给 ( x 0 ′ , y 0 ′ ) (x_0',y_0') (x0′​,y0′​)而无需进行双线性插值。

图像缩小算法与放大类似,只要新图像大小 a ∗ b a*b a∗b小于原图像大小 m ∗ n m*n m∗n即可。

在对图像进行旋转时,为了对图像中心进行旋转,需要先把坐标系平移到中心。记原中心点 ( x ′ , y ′ ) = ( 0 , 0 ) (x',y')=(0,0) (x′,y′)=(0,0),则变换后的中心点 ( x , y ) (x,y) (x,y)与原中心点关系为 ( x y 1 ) = ( x ′ y ′ 1 ) ( 1 0 0 0 − 1 0 − 0.5 w 0.5 h 1 ) \begin{pmatrix}x&y&1\end{pmatrix}=\begin{pmatrix}x'&y'&1\end{pmatrix}\begin{pmatrix}1&0&0\\0&-1&0\\-0.5w&0.5h&1\end{pmatrix} (x​y​1​)=(x′​y′​1​) ​10−0.5w​0−10.5h​001​ ​.则旋转分为三个步骤:将 x ′ o ′ y x'o'y x′o′y变成 x o y xoy xoy,将该点顺时针转 α \alpha α度,最后将 x o y xoy xoy变回 x ′ o ′ y ′ x'o'y' x′o′y′。则完整的变换为: ( x y 1 ) = ( x ′ y ′ 1 ) = ( 1 0 0 0 − 1 0 − 0.5 w o l d 0.5 h o l d 1 ) ( cos ⁡ α − sin ⁡ α 0 sin ⁡ α cos ⁡ α 0 0 0 1 ) ( 1 0 0 0 − 1 0 − 0.5 w n e w 0.5 h n e w 1 ) \begin{pmatrix}x&y&1\end{pmatrix}=\begin{pmatrix}x'&y'&1\end{pmatrix}=\begin{pmatrix}1&0&0\\0&-1&0\\-0.5w_{old}&0.5h_{old}&1\end{pmatrix}\begin{pmatrix}\cos\alpha&-\sin\alpha&0\\\sin\alpha&\cos\alpha&0\\0&0&1\end{pmatrix}\begin{pmatrix}1&0&0\\0&-1&0\\-0.5w_{new}&0.5h_{new}&1\end{pmatrix} (x​y​1​)=(x′​y′​1​)= ​10−0.5wold​​0−10.5hold​​001​ ​ ​cosαsinα0​−sinαcosα0​001​ ​ ​10−0.5wnew​​0−10.5hnew​​001​ ​ 由于前后图像大小不一定相等。所以需要进行插值处理,可以使用上文中提到的两种插值算法。新图像宽为 w ′ = ∣ cos ⁡ α ∣ ∗ w + ∣ sin ⁡ α ∣ ∗ h w'=|\cos\alpha|*w+|\sin\alpha|*h w′=∣cosα∣∗w+∣sinα∣∗h。新图像的高为 h ′ = ∣ sin ⁡ α ∣ ∗ w + ∣ cos ⁡ α ∣ ∗ h h'=|\sin\alpha|*w+|\cos\alpha|*h h′=∣sinα∣∗w+∣cosα∣∗h

部分核心代码 I_0=imread("test.jpg"); I_1=rgb2gray(I_0); I_2=im2bw(I_0,0.5); %figure('P1','P2','P3','P4') title("实验1-1") subplot(1,3,1);imshow(I_0);title('原图') subplot(1,3,2);imshow(I_1);title('灰度图') subplot(1,3,3);imshow(I_2);title('二值化') savefig("lab1_1.fig")

完成了读入一幅RGB图像,变换为灰度图像和二值图像,并在同一个窗口内分别显示RGB图像和灰度图像,注上文字标题,并将结果以文件形式存到磁盘上。

I=imread("test.jpg"); [R,C,color]=size(I); res=zeros(R,C,color); for color=1:3 for i=1:R for j=1:C newx=i+60; newy=j+60; if ((newx=n%下标不能越界 continue; end x11 = double(I(a,b,ch)); % x11 = I(a,b) x12 = double(I(a,b+1,ch)); % x12 = I(a,b+1) x21 = double(I(a+1,b,ch)); % x21 =I(a+1,b) x22 = double(I(a+1,b+1,ch)); % x22 = I(a+1,b+1) newimg(x,y,ch) = uint8( (b+1-yy) * ((xx-a)*x21 + (a+1-xx)*x11) + (yy-b) * ((xx-a)*x22 +(a+1-xx) * x12)); end end end end imshow(newimg);

完成了对图像的放大/缩小操作。使用双线性插值法。先把新图中的像素点除以放大倍数映射得到其在原图中的位置,如果是整数则直接填入,如果不是整数则找到与其相邻的四个点,按照上文中的公式进行插值,将该值填入。

I=imread("test2.jpg"); angle=30; [h,w,d]=size(I); theta=angle/180*pi; cos_val = cos(theta); sin_val = sin(theta); w2=round(abs(cos_val)*w+h*abs(sin_val)); h2=round(abs(cos_val)*h+w*abs(sin_val)); img_rotate = uint8(zeros(h2,w2,3)); %像素是整数 for x=1:w2 for y=1:h2 x0 = uint32(x*cos_val + y*sin_val -0.5*w2*cos_val-0.5*h2*sin_val+0.5*w);%展开矩阵乘法 y0 = uint32(y*cos_val - x*sin_val +0.5*w2*sin_val-0.5*h2*cos_val+0.5*h);%展开矩阵乘法 x0=round(x0); %最近邻 y0=round(y0); %最近邻 if x0>=1 && y0>=1&& x0=1 && pix(1)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有