关于数字图像处理的学习,我们首先要学会matlab这个工具来为我们的计算和处理做好编程的基础。(如果有matlab需求,作者将在另外的文章中来进行介绍安装)
接下来开始我们的数字图像处理的实验。
实验内容:
编程要求:选一副图像对其进行以下操作
1)输出所选图像;
2)对图像进行“红”、“绿”、“蓝”分层提取,并将三幅分层图显示在一个 窗口里,同时在这三个分层图的顶部附上图像的图名;
3)获得图像的3D灰度分布图;
4)分别对“红”、“绿”、“蓝”分层图像的某一行提取该行的灰度值图(一 共3副);并且用该行的“红”色灰度值减去“绿”色灰度值,该行的“红” 色灰度值减去“蓝”色灰度值,该行的“绿”色灰度值减去“蓝”色灰度值(一 共3副);将这6幅图显示一个窗口里,同时在这6个图的各自顶部附上图名; 5)类实地,分别对“红”、“绿”、“蓝”分层图像的某一列提取该列的灰度值图(一共3副);并且用该列的“红”色灰度值减去“绿”色灰度值,该 列的“红”色灰度值减去“蓝”色灰度值,该列的“绿”色灰度值减去“蓝”色 灰度值(一共3副);将这6幅图显示一个窗口里,同时在这6个图的各自顶部附上图名;
6)对所选图像进行垂直和水平方向的Sobel边缘检测,分别显示检测结果;
7)计算所选图像的直方图,并显示红、绿、蓝三个通道的直方图对比图;
8)对所选图像进行高斯平滑处理,显示平滑前后对比图;
9)对平滑后的图像进行Canny边缘检测,显示检测结果。
在做实验时,我们要去了解一些知识点:
1、什么是灰度?什么是3D灰度分布图?
答:1、灰度的定义
灰度,又称灰阶,是使用黑色调表示物体,即用黑色为基准色,通过不同的黑色饱和度来显示图像。灰度图像中的每个像素只有一个采样颜色,这类图像通常显示为从最暗的黑色到最亮的白色的灰度变化。灰度色中不包含任何色相,即不存在红色、黄色这样的颜色,而是纯白、纯黑以及两者中的一系列从黑到白的过渡色。灰度的通常表示方法是百分比,范围从0%(白色)到100%(黑色),也可以表示为0~255的范围,其中0代表黑色,255代表白色,中间的数值代表不同等级的灰色。
2、3D灰度分布图的定义
3D灰度分布图则是一种特殊的图像表示方法,它将灰度图像的灰度值分布以三维的形式展现出来。具体来说,3D灰度分布图以灰度图像的灰度值为高度(或深度)信息,将图像的每个像素点映射到一个三维空间中,从而形成一个三维的灰度分布图。这种表示方法能够更直观地展示灰度图像的灰度值分布情况,有助于对图像进行更深入的分析和处理。
2、什么是垂直和水平方向的Sobel边缘检测?
答:Sobel边缘检测是一种经典的图像处理技术,它基于图像灰度梯度的计算来识别边缘区域。这种技术特别适用于检测图像中灰度值发生剧烈变化的地方,即边缘。在Sobel边缘检测中,水平和垂直方向的梯度是通过使用特定的3x3卷积核(也称为Sobel算子模板)来计算的。
2.1、Sobel算子模板
Sobel算子包含两个主要的卷积核,一个用于检测水平方向的边缘,另一个用于检测垂直方向的边缘。
-
水平方向(Gx):
Sobel水平方向算子的模板如下:
3*3矩阵 :第一行[-1 0 1 ] 第二行[-2 0 2 ]第三行[-1 0 1]
-
这个模板与图像的每个像素进行卷积操作,得到的结果表示该像素在水平方向上的梯度值。
-
垂直方向(Gy):
Sobel垂直方向算子的模板如下:
3*3矩阵 :第一行[-1 -2 -1 ] 第二行[0 0 0 ]第三行[1 2 1]
同样地,这个模板与图像的每个像素进行卷积操作,得到的结果表示该像素在垂直方向上的梯度值。
梯度计算与边缘检测
在进行Sobel边缘检测时,通常会对图像的每个像素应用上述两个模板,从而得到水平和垂直方向上的梯度值(Gx和Gy)。然后,可以通过以下步骤进行边缘检测:
-
计算梯度幅值:梯度幅值G是梯度向量的模,可以通过公式G = sqrt(Gx² + Gy²)计算得到。这个值表示了图像中每个像素点附近的灰度变化强度。
-
设定阈值:为了确定哪些像素点属于边缘,需要设定一个阈值。通常,梯度幅值大于该阈值的像素点会被认为是边缘点。
-
边缘标记:将梯度幅值大于阈值的像素点标记为边缘点,通常是通过将这些点的值设置为255(白色),而其他点的值设置为0(黑色),从而得到二值化的边缘图像。
注意事项
- Sobel边缘检测对噪声较为敏感,因此在处理噪声较多的图像时,可能需要进行预处理(如高斯模糊)来减少噪声的影响。
- Sobel算子主要适用于检测水平和垂直方向的边缘,对于斜向边缘的检测效果可能较差。如果需要检测斜向边缘,可以考虑使用其他边缘检测算法(如Canny边缘检测)。
3、高斯平滑处理
答:基本原理:
高斯平滑处理的基本思想是使用一个二维的高斯分布函数与图像进行卷积,从而达到平滑图像、去除细节和噪声的效果。高斯分布函数是一种钟形曲线,它在中心点取得最大值,并随着与中心点距离的增大而逐渐减小。这种特性使得高斯平滑在处理图像时,能够更好地保留图像的边缘信息,同时去除不需要的细节和噪声。
实现方式:高斯平滑的实现方式主要有两种:一是通过离散化窗口滑窗卷积,二是通过傅里叶变换。在实际应用中,最常用的是第一种方式,因为它简单且易于实现。
- 离散化窗口滑窗卷积:
- 首先定义一个二维高斯核(也称为滤波器),其大小由滤波器尺寸和标准差决定。
- 然后,将高斯核应用于图像的每个像素点,将该像素点与其周围邻域内的像素点进行加权平均计算。权重是根据高斯核的数值分布确定的,距离中心像素越远的像素点权重越小。
- 傅里叶变换:
- 将图像和高斯核分别进行傅里叶变换,将空间域的问题转换到频率域。
- 在频率域中进行乘法运算,相当于在空间域中进行卷积。
- 最后,将结果再进行傅里叶逆变换,得到平滑后的图像。
注意:
- 在进行高斯平滑处理时,需要注意选择合适的参数,以平衡平滑效果和图像细节保留之间的关系。(这里的参数指的是sigma,这里是高斯核的标准差,这里的实验标准差值是需要调整的,参考学习的资料我放在文章末尾,大家都可以去多学点东西)
- 对于边界上的点,通常需要采用特定的处理方式(如复制周围的点到另一面再进行加权平均运算),以避免边界效应。
- 高斯平滑处理虽然可以有效地去除噪声和细节,但也可能导致图像的某些重要特征被模糊掉。因此,在实际应用中需要根据具体需求进行权衡。
总之,高斯平滑处理的过程中会使的图片变得比较连接,少了那种线条的分割感觉,但是在于图像的降噪和视觉上有帮助,但是需要注意选择合适的参数,以平衡平滑效果和图像细节保留之间的关系。
实验过程:(作者这里喜欢薇尔莉特,所以用了她的图片来展示)
1、输出所选图像
A = imread('1.png'); % 读取名为'1.png'的图像文件,并赋值给变量A (注意这里可以更换图片的名称,这里是为了简便)
figure, imshow(A), title('原始图像'); % 显示原始图像,并设置窗口标题
结果:

2、对图像进行“红”、“绿”、“蓝”分层提取,并显示
fxy_r = A(:,:,1); % 提取图像A的红色通道
fxy_g = A(:,:,2); % 提取图像A的绿色通道
fxy_b = A(:,:,3); % 提取图像A的蓝色通道
figure, subplot(1,3,1), imshow(fxy_r), title('红色图层'); % 显示红色图层
subplot(1,3,2), imshow(fxy_g), title('绿色图层'); % 显示绿色图层
subplot(1,3,3), imshow(fxy_b), title('蓝色图层'); % 显示蓝色图层
结果:

3.获得图像的3D灰度分布图
if size(A, 3) == 3
A_gray = rgb2gray(A); % 如果A是RGB图像,则转换为灰度图像
else
A_gray = A; % 如果A已经是灰度图像,则直接使用
end
[rows, cols] = size(A_gray); % 获取灰度图像的尺寸
[X, Y] = meshgrid(1:cols, 1:rows); % 生成网格坐标矩阵
Z = double(A_gray); % 将灰度图像转换为double类型,用于3D绘图
figure, surf(X, Y, Z), shading interp, title('3D灰度分布'); % 绘制3D灰度分布图
结果:

4、提取某一行的灰度值图及差值图
row_index = 257; % 假设提取第257行
figure; % 创建一个新的图形窗口
subplot(2,3,1), plot(fxy_r(row_index,:), '-r'), title('257行红色灰度值'); % 绘制红色通道的灰度值
subplot(2,3,2), plot(fxy_g(row_index,:), '-g'), title('257行绿色灰度值'); % 绘制绿色通道的灰度值
subplot(2,3,3), plot(fxy_b(row_index,:), '-b'), title('257行蓝色灰度值'); % 绘制蓝色通道的灰度值
subplot(2,3,4), plot(fxy_r(row_index,:) - fxy_g(row_index,:), '-k'), title('红-绿差值'); % 绘制红绿差值
subplot(2,3,5), plot(fxy_r(row_index,:) - fxy_b(row_index,:), '-m'), title('红-蓝差值'); % 绘制红蓝差值
subplot(2,3,6), plot(fxy_g(row_index,:) - fxy_b(row_index,:), '-c'), title('绿-蓝差值'); % 绘制绿蓝差值
结果:

5、提取某一列的灰度值图及差值图
col_index = 128; % 假设我们提取第128列
figure; % 创建一个新的图形窗口
subplot(2,3,1), plot(fxy_r(:,col_index), '-r'), title('128列红色灰度值'); % 绘制红色通道的灰度值
subplot(2,3,2), plot(fxy_g(:,col_index), '-g'), title('128列绿色灰度值'); % 绘制绿色通道的灰度值
subplot(2,3,3), plot(fxy_b(:,col_index), '-b'), title('128列蓝色灰度值'); % 绘制蓝色通道的灰度值
subplot(2,3,4), plot(fxy_r(:,col_index) - fxy_g(:,col_index), '-k'), title('红-绿差值'); % 绘制红绿差值
subplot(2,3,5), plot(fxy_r(:,col_index) - fxy_b(:,col_index), '-m'), title('红-蓝差值'); % 绘制红蓝差值
subplot(2,3,6), plot(fxy_g(:,col_index) - fxy_b(:,col_index), '-c'), title('绿-蓝差值'); % 绘制绿蓝差值
结果:

6、Sobel边缘检测
imgGrayDouble = double(rgb2gray(A)); % 将RGB图像转换为灰度图像,并转换为double类型
% 垂直Sobel边缘检测
sobelVertical = imfilter(imgGrayDouble, [-1 0 1; -2 0 2; -1 0 1], 'replicate'); % 应用垂直Sobel滤波器
% 水平Sobel边缘检测
sobelHorizontal = imfilter(imgGrayDouble, [-1 -2 -1; 0 0 0; 1 2 1], 'replicate'); % 应用水平Sobel滤波器
% 显示原始灰度图和边缘检测结果
figure, imshow(uint8(abs(sobelVertical)), []), title('垂直Sobel边缘检测'); % 显示垂直边缘检测结果
figure, imshow(uint8(abs(sobelHorizontal)), []), title('水平Sobel边缘检测'); % 显示水平边缘检测结果
%figure, imshow(imgGrayDouble, []), title('原始灰度图像'); % 可选:显示原始灰度图像
结果:

7、计算并显示直方图
figure; % 创建一个新的图形窗口
C = rgb2gray(A); % 将RGB图像A转换为灰度图像C
subplot(4,1,1), imhist(C), title('原图直方图'); % 显示原图的灰度直方图
subplot(4,1,2), imhist(fxy_r), title('红色通道直方图'); % 显示红色通道的直方图
subplot(4,1,3), imhist(fxy_g), title('绿色通道直方图'); % 显示绿色通道的直方图
subplot(4,1,4), imhist(fxy_b), title('蓝色通道直方图'); % 显示蓝色通道的直方图
结果:

8、高斯平滑处理
sigma = 1.5; % 高斯核的标准差
A_smoothed = imgaussfilt(A, sigma); % 对原始图像进行高斯平滑处理
figure, subplot(1,2,1), imshow(A), title('原始图像'); % 显示原始图像
subplot(1,2,2), imshow(A_smoothed), title('高斯平滑后的图像'); % 显示高斯平滑后的图像
结果:

9、Canny边缘检测
e_canny = edge(rgb2gray(A_smoothed), 'canny'); % 对高斯平滑后的图像进行Canny边缘检测
figure;
subplot(1,2,1), imshow(A_smoothed), title('高斯平滑后的图像'); % 显示高斯平滑后的图像
subplot(1,2,2), imshow(e_canny), title('Canny边缘检测'); % 显示Canny边缘检测结果
结果:

完整代码如下:
(这里建议使用matlab2020a/b版本的来运行操作,避免相关函数不包括)
% 1) 输出所选图像
A = imread('1.png'); % 读取名为'1.png'的图像文件,并赋值给变量A
% 替换 'your_image.png' 为你的图像文件名
figure, imshow(A), title('原始图像'); % 显示原始图像,并设置窗口标题
% 2) 对图像进行“红”、“绿”、“蓝”分层提取,并显示
fxy_r = A(:,:,1); % 提取图像A的红色通道
fxy_g = A(:,:,2); % 提取图像A的绿色通道
fxy_b = A(:,:,3); % 提取图像A的蓝色通道
figure, subplot(1,3,1), imshow(fxy_r), title('红色图层'); % 显示红色图层
subplot(1,3,2), imshow(fxy_g), title('绿色图层'); % 显示绿色图层
subplot(1,3,3), imshow(fxy_b), title('蓝色图层'); % 显示蓝色图层
% 3) 获得图像的3D灰度分布图
if size(A, 3) == 3
A_gray = rgb2gray(A); % 如果A是RGB图像,则转换为灰度图像
else
A_gray = A; % 如果A已经是灰度图像,则直接使用
end
[rows, cols] = size(A_gray); % 获取灰度图像的尺寸
[X, Y] = meshgrid(1:cols, 1:rows); % 生成网格坐标矩阵
Z = double(A_gray); % 将灰度图像转换为double类型,用于3D绘图
figure, surf(X, Y, Z), shading interp, title('3D灰度分布'); % 绘制3D灰度分布图
% 4) 提取某一行的灰度值图及差值图
row_index = 257; % 假设提取第257行
figure; % 创建一个新的图形窗口
subplot(2,3,1), plot(fxy_r(row_index,:), '-r'), title('257行红色灰度值'); % 绘制红色通道的灰度值
subplot(2,3,2), plot(fxy_g(row_index,:), '-g'), title('257行绿色灰度值'); % 绘制绿色通道的灰度值
subplot(2,3,3), plot(fxy_b(row_index,:), '-b'), title('257行蓝色灰度值'); % 绘制蓝色通道的灰度值
subplot(2,3,4), plot(fxy_r(row_index,:) - fxy_g(row_index,:), '-k'), title('红-绿差值'); % 绘制红绿差值
subplot(2,3,5), plot(fxy_r(row_index,:) - fxy_b(row_index,:), '-m'), title('红-蓝差值'); % 绘制红蓝差值
subplot(2,3,6), plot(fxy_g(row_index,:) - fxy_b(row_index,:), '-c'), title('绿-蓝差值'); % 绘制绿蓝差值
% 5) 提取某一列的灰度值图及差值图(类似行,但使用列索引)
col_index = 128; % 假设我们提取第128列
figure; % 创建一个新的图形窗口
subplot(2,3,1), plot(fxy_r(:,col_index), '-r'), title('128列红色灰度值'); % 绘制红色通道的灰度值
subplot(2,3,2), plot(fxy_g(:,col_index), '-g'), title('128列绿色灰度值'); % 绘制绿色通道的灰度值
subplot(2,3,3), plot(fxy_b(:,col_index), '-b'), title('128列蓝色灰度值'); % 绘制蓝色通道的灰度值
subplot(2,3,4), plot(fxy_r(:,col_index) - fxy_g(:,col_index), '-k'), title('红-绿差值'); % 绘制红绿差值
subplot(2,3,5), plot(fxy_r(:,col_index) - fxy_b(:,col_index), '-m'), title('红-蓝差值'); % 绘制红蓝差值
subplot(2,3,6), plot(fxy_g(:,col_index) - fxy_b(:,col_index), '-c'), title('绿-蓝差值'); % 绘制绿蓝差值
% 6) Sobel边缘检测
imgGrayDouble = double(rgb2gray(A)); % 将RGB图像转换为灰度图像,并转换为double类型
% 垂直Sobel边缘检测
sobelVertical = imfilter(imgGrayDouble, [-1 0 1; -2 0 2; -1 0 1], 'replicate'); % 应用垂直Sobel滤波器
% 水平Sobel边缘检测
sobelHorizontal = imfilter(imgGrayDouble, [-1 -2 -1; 0 0 0; 1 2 1], 'replicate'); % 应用水平Sobel滤波器
% 显示原始灰度图和边缘检测结果
figure, imshow(uint8(abs(sobelVertical)), []), title('垂直Sobel边缘检测'); % 显示垂直边缘检测结果
figure, imshow(uint8(abs(sobelHorizontal)), []), title('水平Sobel边缘检测'); % 显示水平边缘检测结果
%figure, imshow(imgGrayDouble, []), title('原始灰度图像'); % 可选:显示原始灰度图像
% 7) 计算并显示直方图
figure; % 创建一个新的图形窗口
C = rgb2gray(A); % 将RGB图像A转换为灰度图像C
subplot(4,1,1), imhist(C), title('原图直方图'); % 显示原图的灰度直方图
subplot(4,1,2), imhist(fxy_r), title('红色通道直方图'); % 显示红色通道的直方图
subplot(4,1,3), imhist(fxy_g), title('绿色通道直方图'); % 显示绿色通道的直方图
subplot(4,1,4), imhist(fxy_b), title('蓝色通道直方图'); % 显示蓝色通道的直方图
% 8) 高斯平滑处理
sigma = 1.5; % 高斯核的标准差
A_smoothed = imgaussfilt(A, sigma); % 对原始图像进行高斯平滑处理
figure, subplot(1,2,1), imshow(A), title('原始图像'); % 显示原始图像
subplot(1,2,2), imshow(A_smoothed), title('高斯平滑后的图像'); % 显示高斯平滑后的图像
% 9) Canny边缘检测
edges_canny = edge(rgb2gray(A_smoothed), 'canny'); % 对高斯平滑后的图像进行Canny边缘检测
figure;
subplot(1,2,1), imshow(A_smoothed), title('高斯平滑后的图像'); % 显示高斯平滑后的图像
subplot(1,2,2), imshow(edges_canny), title('Canny边缘检测'); % 显示Canny边缘检测结果
相关的参考资料如下:
1、Sobel算子:
(1)基于Sobel算子图像边缘检测的MATLAB实现 | Why·Liam·Blog (naaln.com)
(2)Matlab自编函数实现Sobel边缘检测_matlab sobel-CSDN博客
2、matlab中如何做到对所选图像进行高斯平滑处理
(1)【MATLAB 高斯滤波完全指南】:从理论到实战应用,一文搞定 - CSDN文库
(2)MATLAB图像处理:43:用高斯平滑滤波器处理图像 - 知乎 (zhihu.com)
(3)imgaussfilt - 图像的二维高斯滤波 - MATLAB (mathworks.com)
3、matlab中如何做到对平滑后的图像进行Canny边缘检测
(1)Canny边缘检测及matlab实现 - 知乎 (zhihu.com)
(2)边缘检测 - MATLAB & Simulink - MathWorks 中国 (这个方法最简单)
(3)[图像]Canny检测的Matlab实现(含代码)_matlab canny函数-CSDN博客
4、对于图像的任意行或者列的灰度值取值
(1)用MATLAB怎么获取任意像素点的灰度值_matlab灰度值提取-CSDN博客
(2)Matlab图像处理系列——图像点运算和灰度直方图Matlab仿真 - 知乎 (zhihu.com)
参考书籍:
(1) MATLAB程序设计与应用 第3版 刘卫国著 出版社: 北京:高等教育出版社ISBN:9787040478136
(哈哈,uu们,咸鱼哥又要开始坚持写文章了,之前的模电实验系列和Arduino系列不是作者不更新,主要是有点忙,后续咸鱼哥也会陆续更新,并会添加嵌入式、UI、opencv/mv、蓝桥杯、光学、电路设计等的文章,还希望大家可以耐心等待,和大家一起加油很快乐,要做励志翻身的咸鱼们哦!)
2934

被折叠的 条评论
为什么被折叠?



