• MATLAB图像处理入门


    一、读写图像、直方图 

    1、读取并显示图像

    imread与imshow函数

    1. clc;clear; close all;
    2. I = imread('pout.tif');
    3. imshow(I);

    结果:

    如果我们想显示图像坐标轴的话只需在imshow后加上下面这行代码:

    set(gca,'Visible','on');

     我们还可以用whos命令查看图像的信息:

    命令行窗口输入whos I查看上面那种图片的信息:

     2、直方图

    显示图像的直方图用hist函数,将直方图均衡化用histeq函数

    我们在上述代码基础上继续输入下面代码:

    1. figure();
    2. imhist(I);

    结果:

     可以看到图像的对比度比较低,我们进行直方图均衡,继续输入下面代码:

    1. I2 = histeq(I);
    2. imshow(I2);
    3. figure();
    4. imhist(I2);

    结果: 

     3、写入图像

    我们使用imwrite函数将上述均衡化的图像I2写入磁盘:

    imwrite(I2, 'output.png');

    可以看到左侧文件区多了output.png

    我们在命令行窗口使用imfinfo函数能看见该图片更为详细的信息:

     拓展:

    使用montage函数能一次显示多张图片在一个窗口,并且这些图像不需要是同一尺寸和大小,我们只需要将在当前目录下或已经在matlab路径里的图片的名字放在一个字典里:

    运行下面代码:

    1. clc;clear; close all;
    2. files = {'catdog.jpg', 'jiedao.jfif', 'Fig0638(a)(lenna_RGB).tif', 'output.png', 'Fig0335(a)(ckt_board_saltpep_prob_pt05).tif'};
    3. montage(files)

    结果:

     我们甚至可以看到不是同一类型的(灰度图和RGB图)都能一起展示!

    二、图像类型转换:

    在MATLAB的官方文档里有着这么几个图像类型转换的函数:

     我们选择几个常用的讲解:

    1、img2gray将 RGB 图像转换为灰度图像

    代码:

    1. clc;clear; close all;
    2. RGB = imread('example.tif');
    3. figure;
    4. imshow(RGB);
    5. I = im2gray(RGB);
    6. figure;
    7. imshow(I);

    结果:

    im2gray 函数与 rgb2gray 基本相同,不同之处是它可以接受灰度图像作为输入并原样返回它们。如果输入图像是灰度图像,则 rgb2gray 函数返回错误。

    2、mat2gray将矩阵转换为灰度图像 

     代码:

    1. clc;clear; close all;
    2. mat = [0:255]' * ones(1,256);
    3. mat = mat';
    4. img = mat2gray(mat);
    5. imshow(img);

    结果:

     3、imsplit将多通道图像分割成其独立的通道

    代码:

    1. clc;clear; close all;
    2. I = imread('peppers.png');
    3. imshow(I);
    4. [r,g,b] = imsplit(I);
    5. montage({r,g,b},'Size',[1 3]);

    结果:

    4、rgb2hsv将RGB图像转为HSV图像 

    代码:

    1. clc;clear; close all;
    2. rgbImage = imread('peppers.png');
    3. imshow(rgbImage);
    4. hsvImage = rgb2hsv(rgbImage);
    5. [h,s,v] = imsplit(hsvImage);
    6. montage({h,s,v},'Size',[1 3])

    结果:

    还有很多颜色空间之间的转换就不一一列举了:

     5、灰度图像二值化

    这里就不演示了

    6、数据类型转换

     其实这些都可以直接转换,比如我们想将uint16的矩阵I转换为uint8直接I = uint8(I)即可,其他数据类型转换也是同理!

    示例:

    三、几何变换和图像配准

    常见几何变换

    1、imcrop裁剪图像 

    Icropped = imcrop(I,rect)裁剪图像

    1. clc;clear; close all;
    2. I = imread('circuit.tif');
    3. I2 = imcrop(I,[75 68 130 112]);
    4. axis image;
    5. subplot(1,2,1);
    6. imshow(I);
    7. title('Original Image');
    8. subplot(1,2,2);
    9. imshow(I2);
    10. title('Cropped Image');
    11. axis image;

    结果:

     注意matlab的图像坐标系为:

    在这里插入图片描述

    使用空间参照矩形使裁剪图像居中

    1. I = imread('parkavenue.jpg');
    2. imshow(I)

    将目标窗口大小指定为 [宽度高度] 形式的二元素向量。

    targetSize = [300 600];

     创建指定裁剪窗口的空间范围的 Rectangle 对象。

    r = centerCropWindow2d(size(I),targetSize);

    在空间范围的界限处裁剪图像。显示裁剪的区域。 

    1. J = imcrop(I,r);
    2. imshow(J)

    结果:

     2、imresize调整图像大小

    J = imresize(I,scale) 返回图像 J,它是将 I 的长宽大小缩放 scale 倍之后的图像。输入图像 I 可以是灰度图像、RGB 图像、二值图像或分类图像。

    代码:

    1. clc;clear; close all;
    2. I = imread('rice.png');
    3. J = imresize(I, 0.5);
    4. figure;
    5. imshow(I);
    6. title('Original Image');
    7. figure;
    8. imshow(J);
    9. title('Resized Image');

    结果:

    我们都知道图像缩放需要进行插值,我们可以在imresize函数中自行选择插值方法:

    我们在下面的代码中指定最近邻插值(其他代码不变):

    J = imresize(I, 0.5,'nearest');
    

    J = imresize(I,[numrows numcols]) 返回图像 J,其行数和列数由向量 [numrows numcols] 指定。

    代码:

    1. clc;clear; close all;
    2. RGB = imread('peppers.png');
    3. RGB2 = imresize(RGB, [128 128]);
    4. figure;
    5. imshow(RGB);
    6. title('Original Image');
    7. figure;
    8. imshow(RGB2);
    9. title('Resized Image');

    结果:

     3、imroate旋转图像

    J = imrotate(I,angle) 将图像 I 围绕其中心点逆时针方向旋转 angle 度。要顺时针旋转图像,请为 angle 指定负值。imrotate 使输出图像 J 足够大,可以包含整个旋转图像。默认情况下,imrotate 使用最近邻点插值,将 J 中位于旋转后的图像外的像素的值设置为 0

     代码:
     

    1. clc;clear; close all;
    2. I = imread('peppers.png');
    3. J = imrotate(I, 45, 'bilinear','loose');
    4. figure(1);
    5. imshow(I);
    6. figure(2);
    7. imshow(J);

    结果:

     我们将bbox参数改为crop观察图片大小是否一致:

    J = imrotate(I, 45, 'bilinear','crop');

     

     可以看到改为'crop'后图片大小一致!

     4、图像金字塔impyramid

    B = impyramid(A,direction) computes a Gaussian pyramid reduction or expansion of A by one level. direction determines whether impyramid performs a reduction or an expansion.

    代码:

    1. clc;clear; close all;
    2. I = imread('cameraman.tif');
    3. I1 = impyramid(I, 'reduce');
    4. I2 = impyramid(I1, 'reduce');
    5. I3 = impyramid(I2, 'reduce');
    6. figure, imshow(I);
    7. figure, imshow(I1);
    8. figure, imshow(I2);
    9. figure, imshow(I3);

    结果:

    四、图像滤波和增强 

    1、图像滤波

    1.1、fspecial创建滤波器核、imfilter根据选定的滤波核进行滤波

    注:图像滤波也可以用filter2函数,与imfilter的区别请自行help命令查看 

     注意上面说的imfilter默认使用相关性而不是卷积,若要使用卷积进行滤波则需要指定'conv'参数!

    示例:

    读取图像并显示:

    1. I = imread('cameraman.tif');
    2. imshow(I);

    创建运动滤波器,并使用它来对图像进行模糊处理。显示模糊处理后的图像。 

    1. H = fspecial('motion',20,45);
    2. MotionBlur = imfilter(I,H,'replicate');
    3. imshow(MotionBlur);

     创建圆形滤波器,并使用它来对图像进行模糊处理。显示模糊处理后的图像。

    1. H = fspecial('disk',10);
    2. blurred = imfilter(I,H,'replicate');
    3. imshow(blurred);

    在执行imfilter时要注意的是将图像转换为uint8型以避免滤波核有负数值导致输出有负数:

     在此要与我们图像之间的运算做区分!我们想把两个图像相加再除2即取均值时我们往往先将两个图像转换为double来防止uint8的截断!而这里则是要刻意使用uint8来截断,注意细节!

    1.2、imgaussfilt图像二维高斯滤波

     注意,这里的滤波核大小未给出,经查看源码后,滤波核大小默认为3*3,sigma默认为0.5,如果要自己指定滤波核大小,以第三种键值对的方式给出:

    示例: B = imgaussfilt(A,'FilterSize',3);

    代码演示:

    1. clc;clear; close all;
    2. I = imread('cameraman.tif');
    3. Iblur = imgaussfilt(I,2, 'FilterSize',7); % sigma = 2, kernel_size = 5*5
    4. montage({I,Iblur});
    5. title('Original Image (Left) Vs. Gaussian Filtered Image (Right)');

     2、对比度调整

    同样的,我们选择常用函数进行演示!

    2.1、imadjust调整图像强度值

    调整灰度图像的对比度

    1. clc;clear; close all;
    2. I = imread('pout.tif');
    3. J = imadjust(I);
    4. montage({I,J});

    调整灰度图像的对比度,指定对比度限制 

    1. clc;clear; close all;
    2. I = imread('pout.tif');
    3. K = imadjust(I,[0.3 0.7],[]); %low_out和high_out未给出时默认等于low_in,high_in
    4. montage({I,K});

     调整彩色图像的对比度

    1. clc;clear; close all;
    2. RGB = imread('football.jpg');
    3. RGB2 = imadjust(RGB,[.2 .3 0; .6 .7 1],[]);%对应彩色图像三通道的low_in,high_in
    4. montage({RGB,RGB2});

     2.2、imsharpen图像锐化

     图像锐化

    1. clc;clear; close all;
    2. a = imread('hestain.png');
    3. imshow(a)
    4. title('Original Image');
    5. b = imsharpen(a);
    6. figure, imshow(b)
    7. title('Sharpened Image');

     在边界上控制锐化的数量

    1. clc;clear; close all;
    2. a = imread('rice.png');
    3. imshow(a), title('Original Image');
    4. b = imsharpen(a,'Radius',2,'Amount',1);
    5. figure, imshow(b)
    6. title('Sharpened Image');

    2.3、histeq直方图均衡化这个上文提过,这里就不多说了

    2.4、imnoise向图像添加噪声

    1. clc;clear; close all;
    2. I = imread('eight.tif');
    3. J = imnoise(I,'salt & pepper',0.02);
    4. montage({I,J});
    5. title('Original Image(left) and Noise Image(right)');

    3、形态学运算

    3.1、imerode腐蚀 

    其中的SE:

    1. original_img = imread('Fig0905(a)(wirebond-mask).tif');
    2. subplot(1,4,1);
    3. imshow(original_img);
    4. %三次不同大小的腐蚀操作比较
    5. SE = strel('rectangle',[11 11]);
    6. out = imerode(original_img, SE);
    7. subplot(1,4,2);
    8. imshow(out);
    9. SE = strel('rectangle',[15 15]);
    10. out = imerode(original_img, SE);
    11. subplot(1,4,3);
    12. imshow(out);
    13. SE = strel('rectangle',[45 45]);
    14. out = imerode(original_img, SE);
    15. subplot(1,4,4);
    16. imshow(out);

    注意,每一次腐蚀都会导致中间的白圈变小,这里不大明显! 

     下面我们用nhood再演示一下腐蚀操作:

    1. original_img = imread('Fig0905(a)(wirebond-mask).tif');
    2. subplot(1,2,1);
    3. imshow(original_img);
    4. nhood = ones(45);
    5. out = imerode(original_img, nhood);
    6. subplot(1,2,2);
    7. imshow(out);

     3.2、imdilate膨胀

     和腐蚀的参数差不多!

    1. original_img = imread('Fig0907(a)(text_gaps_1_and_2_pixels).tif');
    2. imshow(original_img);
    3. nhood = [0 1 0;1 1 1;0 1 0];
    4. out = imdilate(original_img, nhood);
    5. figure();
    6. imshow(out);

     放大后观察效果:

     3.3、imopen开运算

    与腐蚀和膨胀的语法差不多哈

    3.4、imclose闭运算 

    下面这个示例演示先开运算在闭运算结果

    1. original_img = imread('Fig0911(a)(noisy_fingerprint).tif');
    2. subplot(1,3,1);
    3. imshow(original_img);
    4. nhood = ones(3);
    5. out = imopen(original_img, nhood);
    6. subplot(1,3,2);
    7. imshow(out);
    8. out = imclose(out, nhood);
    9. subplot(1,3,3);
    10. imshow(out);

    4、基于关注区域的处理(待更新)

    5、图像算术

     5.1、imabsdiff

    1. clc;clear; close all;
    2. I = imread('cameraman.tif');
    3. J = uint8(filter2(fspecial('gaussian'), I));
    4. K = imabsdiff(I,J);
    5. figure;
    6. imshow(K,[]);%将K中像素最小值设为黑色,最大值设为白色

     5.2、imadd

    将两个图像相加。将输出指定为 uint16 类型以避免截断结果。

    1. clc;clear; close all;
    2. I = imread('rice.png');
    3. J = imread('cameraman.tif');
    4. K = imadd(I,J,'uint16');
    5. imshow(K,[]);

     5.3、imsubtract

     从一个图像中减去另一个图像或从图像中减去常量

    减去图像背景 

    1. clc;clear; close all;
    2. I = imread('rice.png');
    3. %估计背景
    4. background = imopen(I,strel('disk',15));
    5. %从图像中减去背景
    6. J = imsubtract(I,background);
    7. montage({I,J});

    五、傅里叶变换 

    1、fft2实现图像的快速傅里叶变换

     代码演示:

    1. clc;clear;close all;
    2. im = imread('street.jfif');
    3. figure(1);
    4. imshow(im);
    5. im = rgb2gray(im);
    6. out = fft2(im);
    7. figure(2);
    8. imshow(abs(out),[]); %取实部

    可能会有疑问,为什么傅里叶变换黑的啥都没有呢?事实上如果我们将Figure2的左上角放大,其实是这个样子:

     所以事实是只有左上角值比较大看起来是白色,而这就是我们的直流分量。事实上这种现象的原因是直接用fft2的话频谱的原点不在图像中心 而在左上角。

    如果我们想将原点移到中心,我们需要用fftshift函数:

    2、fftshift将频谱原点移到中心

     让我们在上面的代码加上:

    1. figure(3);
    2. out = fftshift(out);
    3. imshow(abs(out),[]);

     这样就对了!

    3、ifft2进行逆傅里叶变换

    下面我们进行频域的低通滤波再逆傅里叶变换查看结果

    1. clc;clear;close all;
    2. im = imread('Fig0638(a)(lenna_RGB).tif');
    3. figure(1);
    4. im = rgb2gray(im);%转灰度
    5. imshow(im);
    6. title('原图');
    7. [M N] = size(im);
    8. im_f = fft2(im);
    9. lp = fspecial('gaussian',25,2);%高斯低通滤波器(空间域)(补零到与原图一样大小)
    10. lp_f = fft2(lp,M,N);%高斯低通滤波器(频域)
    11. figure(2);
    12. surf(fftshift(abs(lp_f)),'edgecolor','none');%surf函数画曲面图
    13. title('滤波核频域曲面图');
    14. out_f = im_f.*lp_f; %频域相乘
    15. out = ifft2(out_f);%空间域结果
    16. figure(3);
    17. imshow(abs(out),[]);
    18. title('结果');

     这里我们的滤波核是用的自带的,当然我们也可以自定义一个频域低通滤波器:

    1. %D(u,v)<=D0时有值
    2. u = 0:Q-1
    3. v = 0:P-1
    4. %calculate D(u,v)
    5. H = double(D<=D0)

    参考资料:

    MATLAB官方文档的Image Processing Toolbox

  • 相关阅读:
    git 第一次推代码
    瑞吉外卖项目剩余功能补充
    Linux 网络基本命令
    Hadoop运行环境搭建
    初识红黑树
    函数式编程-Stream流
    IO:作业:线程:2. 要求用线程拷贝一张图片,一个线程拷贝前半部分,另一个线程拷贝后半部分
    基于 Python+DenseNet121 算法模型实现一个图像分类识别系统
    ssm+vue+elementUI 基于协同过滤算法的图书推荐系统-#毕业设计
    Goole框架 — — Guava用法
  • 原文地址:https://blog.csdn.net/qq_55621259/article/details/126216814