matlab基础总结与图像处理应用(下)

(结合左侧的目录学习体验会更好)

本篇内容是我用matlab学习图像处理的记录,分为两个部分。

第一部分总结了matlab基础语法;第二部分实现了一个图像处理入门的算法。

matlab基础总结与图像处理应用上

图像处理基础算法

参考代码都是可以优化的,下面示例定位是简单入门。

图像导入与格式转换

clc;
clear;
close all;

%-----读--取--图--片--并--显--示---------
% imread 读一张图片,括号里格式为字符串,这字符串表示你要读取图片的路径
img = imread('1.jpg');

% 函数figure: 建立一个窗口 可以直接用数字去编号:
% figure(1);
% 关于figure的用法参考:https://blog.csdn.net/qq_30387863/article/details/80301996
% 命名编号:括号里两个参数:第一个是指定参数为'name', 第二个写你要起的名字
figure('name', '小黑')

% 函数imshow:显示图片 括号里面是需要显示的图片的名字
imshow(img);

% -----图--像--的--表--示-----
% 关于图像里面的数据格式,常见的是uint8和double 
% 其中,uint8指的是没有符号的整数,即非负整数,double指的是精确度比较高的浮点数

% 彩图和灰度图的转化不是可逆的,彩图到灰度图可以用函数rgb2gray
gray = rgb2gray(img);
figure('name', 'gray');
imshow(gray);

% ---保存图片到指定位置---
% 用 imwrite(A,filename) 
% 将图像数据 A 写入 filename 指定的文件,并从扩展名推断出文件格式。

均值滤波

说明

均值滤波的代码:code.m
示例用的思路是:
选取相邻3x3的范围,用9个数字的平均作为滤波结果,进行赋值。

均值滤波的两种方法:一个是示例的邻域平均,另一个是根据距离目标像素点的远近乘以加权的系数,叫做加权平均,像高斯滤波就是如此。
参考

这篇文章介绍得挺好:

均值滤波和中值滤波

代码

code.m

clc;
clear;
close all;

img = imread('1.jpg');

gray = rgb2gray(img);
figure('name', 'gray');
imshow(gray);

[m, n] = size(gray);

avg_filter = gray;
for i = 2:m-1
    for j = 2:n-1
        
        filter_con = gray(i-1:i+1, j-1:j+1);
        k = sum(sum(filter_con))/9;
        avg_filter(i, j) = k;
    
    end
end

figure('name', 'avg_filter');
imshow(avg_filter);

sobel算法

说明

文件code.m,

利用sobel算子可以将图像周围像素灰度有阶跃变化的像素检测出来,这些像素组成的集合就是该图像的边缘。

实现: 分别用检测垂直边缘和检测水平边缘的算子对图像一点作平面卷积,然后开平方得到该点的灰度值。

参考

sobel参考 原理可以,里面参考代码不太行,漏洞太多。

知乎一篇不错的文章

代码

code.m

clc;
clear;
close all;

img = imread('1.jpg');

figure('name', '原图');
imshow(img);

gray = rgb2gray(img);
[m, n] = size(gray);

% 预设好矩阵大小
x_sobel = double(gray);
y_sobel = double(gray);
img_sobel = gray;
for i = 2:m-1
    for j = 2:n-1
        % 分别用x、y方向的算子检测边缘,然后合成
        % x_con = [-1,0,1; -2,0,2; -1,0,1];
        % y_con = [-1,-2,-1; 0,0,0; 1,2,1];
        x_sobel(i,j) = (-1*gray(i-1, j-1) + gray(i-1, j+1) ... % 三个省略号表示接着下一行
            -2*gray(i, j-1) + 2*gray(i, j+1) ...
            -1*gray(i+1, j-1) + gray(i+1, j+1));
        
        y_sobel(i, j) = (-1*gray(i-1, j-1) - 2*gray(i-1, j) - gray(i-1, j+1) ...
            +gray(i+1, j-1) + 2*gray(i+1, j) + gray(i+1, j+1));
    end
end
img_sobel = sqrt(x_sobel.^2 + y_sobel.^2);
figure('name', 'img_sobel');
imshow(uint8(img_sobel));

腐蚀膨胀

说明

文件 code1.m:

膨胀,使图像中亮的区域增长

使用卷积核B对图片A进行卷积运算,求局部最大值,这个卷积核可以有任意的形状和大小,通常是一个方形或者圆形。卷积核B通常有个锚点,通常位于卷积核的中央位置。

随着卷积核扫描图像,计算叠加区域的最大像素值,并将锚点的位置用最大值替换,从而导致图片中亮的区域增长。

文件code2.m:

腐蚀,使亮色的区域减少

文件code3.m:

开操作, 先腐蚀后膨胀;先膨胀后腐蚀是闭操作;

顶帽操作和底帽操作是灰度图像所特有的,其原理是开操作将使峰顶消去,具体消去了多少呢,可以用原图减去开操作结果,这样就能得到其消去的部分,而这个过程成为顶帽操作,顶帽就是开操作消去的峰顶,这一部分对应于图像中较亮的部分,也叫白色顶帽。

开运算放大了裂缝或者局部低亮度的区域,所以,从原图中减去开运算后的图,得到的结果突出了比原图轮廓周围的区域更明亮的区域,这个操作与选择的核的大小有关。TopHat运算一般用来分离比邻近点亮一些的斑块,可以使用这个运算提取背景。

同理,底帽操作是用闭操作的结果减去原图就得到被闭操作填充的谷底部分,这一部分对应于图像中较暗的部分,也叫黑色底帽。黑帽运算的结果突出了比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。

参考

参考一

参考二

代码

code1.m

clc;
clear;
close all;

path = '1.jpg';
img = imread(path);

figure('name', '原图')
imshow(img);

% 膨胀:这里对灰度图腐蚀,其他类型图像同理
gray = rgb2gray(img);
figure('name', '灰度图')
imshow(gray);

[m,n] = size(gray);
pz = gray; % 提前预分配,优化速度
for i = 2 : m-1
    for j = 2 : n-1
        % con是选了3*3大小的卷积区域,然后腐蚀
        con = gray(i-1:i+1, j-1:j+1);
        % 一次max求每列最大,二次是整体最大
        pz(i,j) = max(max(con));
        
    end
end

figure('name', 'fs');
imshow(pz);

code2.m

clc;
clear;
close all;

path = '1.jpg';
img = imread(path);

figure('name', '原图')
imshow(img);

% ----------对--灰--度--图--腐--蚀---------
% gray = rgb2gray(img);
% figure('name', '灰度图')
% imshow(gray);
% 
% [m,n] = size(gray);
% fs = gray; % 提前预分配,优化速度
% for i = 2 : m-1
%     for j = 2 : n-1
%         % con是选了3*3大小的卷积区域,然后腐蚀
%         con = gray(i-1:i+1, j-1:j+1);
%         fs(i,j) = min(min(con));
%         
%     end
% end
% 
% figure('name', 'fs');
% imshow(fs);

%------------对--彩--色--图-------------
r = img(:, :, 1);
g = img(:, :, 2);
b = img(:, :, 3);

[m, n] = size(r);

r_out = r;
for i = 2 : m-1
    for j = 2 : n-1
        con = r(i-1:i+1, j-1:j+1);
        r_out(i,j) = min(min(con));
    end
end

g_out = g;
for i = 2 : m-1
    for j = 2 : n-1
        con = g(i-1:i+1, j-1:j+1);
        g_out(i,j) = min(min(con));
    end
end

b_out = b;
for i = 2 : m-1
    for j = 2 : n-1
        con = b(i-1:i+1, j-1:j+1);
        b_out(i,j) = min(min(con));
    end
end

out = cat(3, r_out, g_out, b_out);

figure('name', 'fs_color');
imshow(out);

code3.m

clc;
clear;
close all;

path = '1.jpg';
img = imread(path);

figure('name', '原图')
imshow(img);

% ----开--运--算------
gray = rgb2gray(img);
figure('name', '灰度图')
imshow(gray);

% 先腐蚀
[m,n] = size(gray);

fs = gray; 
for i = 2 : m-1
    for j = 2 : n-1
        con = gray(i-1:i+1, j-1:j+1);
        fs(i,j) = min(min(con));
    end
end

% 后膨胀

pz = fs;
for i = 2 : m-1
    for j = 2 : n-1
        con = fs(i-1:i+1, j-1:j+1);
        pz(i,j) = max(max(con));
    end
end

open_img = pz;
figure('name', 'open_img');
imshow(open_img);

% ------顶--帽:找出多膨胀的那一块亮度--------
% 原图-开运算的图
top_hat = gray - open_img;
figure('name', 'top_hat');
imshow(top_hat);

% 备注: 由上面代码变换顺序做一下微调整,便可以得到闭运算、黑帽

直方图均衡化

说明

原理

当图像直方图完全均匀分布的时候,此时图像的熵是最大的(随机变量每个值的概率都相同时,概率最大),图像对比度是最大的。直方图均衡化就是让图像的像素值所组成的直方图均匀分布,达到提高亮度的作用。

code.m 是用灰度图实现

code_color.m 是彩色图

coloraverage.m 是对code_color.m 的写法改进
参考

彩色图像的直方图均衡化,用到了函数,这个不错

直方图的原理

代码

code.m

clc
clear
close all;

% 读图
img = imread('1.jpg');

%灰度图处理
gray = rgb2gray(img);
figure('name', 'original gray');
imshow(gray);

%读取灰度图 及直方图
[R,C]=size(gray);
% figure(2);
% imhist(I);

%统计灰度
s=zeros(1,256);
for i=1:R
    for j=1:C
        s(1,gray(i,j)+1)=s(1,gray(i,j)+1)+1;
    end
end

%算概率
p=zeros(1,256);
for i=1:256
    p(i)=s(i)/(R*C*1.0);
end

%累计直方图
c=zeros(1,256);
c(1)=p(1);
for i=2:256
    c(i)=c(i-1)+p(i);
end
%取整
% c = uint8(255.*c+0.5);
c= round(255.*c);
%  均衡
for i=1:R
    for j=1:C
        gray(i,j)=c(gray(i,j)+1);
    end
end
%8 输出直方图均衡化后的图像
figure('name', 'out_hisq');
imshow(gray);
% figure(4);
% imhist(I);

code_color.m

clc
clear
close all;

% 读图
img = imread('1.jpg');
figure('name', 'original image');
imshow(img);

figure(12);
imshow(histeq(img, 256));

%彩图处理
r = img(:, :, 1);
g = img(:, :, 2);
b = img(:, :, 3);

% 获得图像的尺寸大小 
[R, C]=size(r);

% ----分--图--层--处--理------
% ----r----
r_out = r;
s = zeros(1,256);
for i = 1:R
    for j=1:C
        s(1, r_out(i,j)+1)=s(1, r_out(i,j)+1)+1;
    end
end

%算概率
p = zeros(1,256);
for i = 1:256
    p(i)=s(i)/(R*C*1.0);
end

%累计直方图
c=zeros(1,256);
c(1)=p(1);
for i=2:256
    c(i)=c(i-1)+p(i);
end
%取整
% c = uint8(255.*c+0.5);
c= round(255.*c);
%  均衡
for i=1:R
    for j=1:C
        r_out(i,j)=c(r_out(i,j)+1);
    end
end

% -----g-------
g_out = g;
s=zeros(1,256);
for i=1:R
    for j=1:C
        s(1, g_out(i,j)+1) = s(1, g_out(i,j)+1)+1;
    end
end

%算概率
p=zeros(1,256);
for i=1:256
    p(i)=s(i)/(R*C*1.0);
end

%累计直方图
c=zeros(1,256);
c(1)=p(1);
for i=2:256
    c(i)=c(i-1)+p(i);
end
%取整
% c = uint8(255.*c+0.5);
c= round(255.*c);
%  均衡
for i=1:R
    for j=1:C
        g_out(i,j) = c(g_out(i,j)+1);
    end
end

% -----b-------
b_out = b;
s=zeros(1,256);
for i=1:R
    for j=1:C
        s(1, b_out(i,j)+1) = s(1, b_out(i,j) + 1) + 1;
    end
end

%算概率
p=zeros(1,256);
for i=1:256
    p(i)=s(i)/(R*C*1.0);
end

%累计直方图
c=zeros(1,256);
c(1)=p(1);
for i=2:256
    c(i)=c(i-1)+p(i);
end
%取整
% c = uint8(255.*c+0.5);
c= round(255.*c);
%  均衡
for i = 1:R
    for j = 1:C
        b_out(i,j) = c(b_out(i,j)+1);
    end
end

out = cat(3, r_out, g_out, b_out);

% 输出直方图均衡化后的图像
figure('name', 'out_hisq');
imshow(out);

coloraverage.m

%主函数
function coloraverage()
I=imread('1.jpg');
imshow(I);
I1=I(:,:,1);%提取红色分量
I2=I(:,:,2);%提取绿色分量
I3=I(:,:,3);%提取蓝色分量
I1=histogram(I1);   %构造的函数
I2=histogram(I2);
I3=histogram(I3);
c=cat(3,I1,I2,I3);  %cat用于构造多维数组
subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(c);

%调用的(直方图均衡化)构造函数
function d=histogram(I)%构造histogram函数
J=I;
[m,n]=size(I);      %确定矩阵大小
area=m*n;
a=zeros(1,256);     %产生1*256的零矩阵a,用来存放原始图像各个灰度值的个数
b=zeros(1,256);
for i=1:m           %记录各个灰度值的个数
    for j=1:n
        d=I(i,j)+1;   %获取(i,j)位置的灰度值(注意:灰度值为0-255,对应矩阵的1-256)
        a(1,d)=a(1,d)+1;    %矩阵a上对应灰度值的计数+1
    end
end
for i=1:256         %均衡化
    sum=0;
    for j=1:i
        sum=sum+a(1,j);
    end
    b(1,i)=sum*255/area;
end
for i=1:m           %用均衡化后的数据代替原位置的数据
    for j=1:n
        d=J(i,j)+1;
        J(i,j)=b(1,d);
    end
end
d=J;

Reference

1、书:数字图像处理,朱虹等著

2、知乎/CSDN等网友的博客贴:

  1. 均值滤波和中值滤波

  2. sobel参考
    原理可以,里面参考代码不太行,漏洞太多。
    知乎一篇不错的文章

  3. 腐蚀膨胀参考一

    腐蚀膨胀参考二

  4. 彩色图像的直方图均衡化,用到了函数,这个不错

    直方图的原理

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值