【MATLAB Image Processing Toolbox 入门教程一】
- MATLAB Image Processing Toolbox 简介
- MATLAB Image Processing Toolbox 的知识架构
- Image Processing Toolbox快速入门
-
- 1 基本图像的导入、处理和导出
-
- 1.1 图像的读入和显示
- 1.2 检查图像在工作区的显示方式
- 1.3 提高图像对比度
- 1.4 将图片写入磁盘
- 2 检测和测量图像中的圆形对象
-
- 2.1 加载图像和确定搜索圆的范围
- 2.2 初步尝试圆识别
- 2.3 深入imfindcircles函数
- 2.4 再次尝试圆识别
- 2.5 完善圆识别
- 2.6 绘制检测出来的所有圆
写在前面:2020.10 转博的第一个月,本科自动化专业,硕士光电科学与工程专业,博士光学工程专业。我目前还认为自己是一个本科生,因为我只拿到了本科的学位证书。硕士期间做的项目和图像处理无关,自学MATLAB Iamge Processing Toolbox是想增加自己学习的范围,不知道哪天用得上。想要更新这个系列一是为了给自己接下来几年的学习做个记录,二是真切希望自己能坚持下来。我深知想要顺利博士毕业或者说符合博士的身份,只学习这些是不够的,希望社区大佬轻喷,另外希望与大家共同进步。
MATLAB Image Processing Toolbox 简介
MATLAB帮助中心文档这样描述:
“Image Processing Toolbox? 为图像处理、分析、可视化和算法开发提供了一套全面的参考标准算法和工作流 App。您可以使用深度学习和传统图像处理技术执行图像分割、图像增强、去噪、几何变换和图像配准。工具箱支持处理二维、三维和任意大的图像。
Image Processing Toolbox App 可让您自动完成常见的图像处理工作流。您可以交互方式分割图像数据、比较图像配准技术,以及对大型数据集进行批量处理。利用可视化函数和 App,您可以探查图像、三维体和视频;调整对比度;创建直方图;以及对关注区域 (ROI) 执行操作。
您可以通过在多核处理器和 GPU 上运行算法来提高算法的执行速度。许多工具箱函数支持桌面原型和嵌入式视觉系统部署的 C/C++ 代码生成。”
总结就是:MATLAB图像处理工具箱可以对您的任意尺寸图像实现任意的操作(废话)。
MATLAB Image Processing Toolbox 的知识架构
Image processing toolbox包括以下几个内容:
1 Image processing toolbox快速入门:基础知识的学习;
2 导入、导出和转换:图像数据的导入和导出,图像类型的转换换;
3 显示和探查:用于图像的显示和探查的交互性工具;
4 几何变换和图像配准:使用强度相关性、特征匹配或控制点映射来缩放、旋转、执行其他 N 维变换和对齐图像;
5 图像滤波和增强:对比度调整、形态学滤波、去模糊、基于关注区域的处理;
6 图像分割与分析:区域分析、纹理分析、像素和图像统计量;
7 深度学习进行图像处理:使用卷积神经网络执行图像处理任务,例如去除图像噪声和基于低分辨率图像创建高分辨率图像,此时需要用到deep learning toolbox;
8 三维体图像处理:对三维体数据进行滤波、分割和其他图像处理操作;
9 代码生成:为工具箱函数生成 C 代码和 MEX 函数;
10 GPU运算:在图形处理单元(GPU)运行图像处理代码。
作者目前也不知道各个模块具体的作用,可能等我有幸更新完所有模块的时候才有资格说这些。有基础的可以根据上面的大概描述选择自己感兴趣的部分继续学习。
对MATLAB Image Toolbox做完介绍,下面开始进行第一部分Image processing toolbox快速入门的学习。
Image Processing Toolbox快速入门
1 基本图像的导入、处理和导出
1.1 图像的读入和显示
MATLAB中使用imread和imshow来进行读取图片和显示图片的操作,类似于OpenCV。
从工作区读图片:
I=imread('1.jpg')
此时,图片1.jpg就已经读入,I为表示图片的数组。
显示图片:
imshow(I)
之前读入的图片就可以显示出来。
1.2 检查图像在工作区的显示方式
可以使用whos指令,检查imread读入的图像在工作区的存储方式,说白了就是查看数组I的大小尺寸数据类型等,这些在工作区中也可以查看。
在MATLAB命令行窗口继续输入
whos I
可以得到:
1.3 提高图像对比度
使用imhist函数查看图像的像素强度分布,但注意,imhist只能查看灰度图像的直方图,所以称为灰度直方图。使用rgb2gray将RGB图像转成灰度图像,继续输入:
J=rgb2gray(I);
imhist(J);
即得到赵云-龙胆的灰度图J及其灰度直方图。
灰度直方图反映了图像的对比度强弱,直方图分布范围越宽,表明对比度越强,反之则越弱。
histeq函数用于直方图均衡化,可增强图像的对比度。
继续输入:
K=histeq(J);
figure;imshow(K);
figure;imhist(K);
可以得到直方图均衡化后的灰度图像及其直方图。
可以看出,处理后的灰度图像黑白对比更加明显,灰度直方图的分布范围更加广泛。
1.4 将图片写入磁盘
使用imwrite将图片K写入磁盘:
imwrite(K,'ok.jpg');
即可将图片写入MATLAB当前工作文件夹。
如果想要将图片写入任意指定的文件夹,就在两个单引号中间输入完整的路径。
我们可以使用imfinfo函数查看文件夹中图片的信息,例如图片的尺寸大小、格式、颜色类型等。
继续输入
imfinfo('ok.jpg');
得到
能看出,返回的图片信息类型是数组类型。
2 检测和测量图像中的圆形对象
本小节中说明MATLAB检测图像中圆形对象的imfindcircles函数的使用方法,并通过viscircles函数将检测到的圆标注出来。
2.1 加载图像和确定搜索圆的范围
为了方便实例,本次采用的图片是MATLAB自带的“彩色薯片”,首先是imread读入图片,并用imshow显示。
srcImage=imread('coloredChips.png');imshow(srcImage);
这张图作为圆形对象的识别范例真是完美,既有颜色对比强烈的蓝色和红色薯片,也有和背景颜色近似的黄色,更重要的是,图中有一些重叠交错的圆,贴近实际情况中的目标检测,这也是比较具有挑战性的地方。
载入图片之后,接下来确定搜索圆的半径范围,这里采用的是imdistline函数。接着输入:
d=imdistline;
可以看出在之前载入的彩色薯片图像上多了一个类似标尺的玩意,我们可以拖动这个标尺,移动标尺两边的方框,用于测量图像中圆形的直径,此处只需要测量一个大概的半径范围即可。
随意测量了两个,直径在40-50个像素,所以半径范围为20-25,当然保险起见,也可以设置大一点,这个区间[20,25]要记住,下面的圆形识别时需要用到,但要注意,确定了半径范围之后别忘记删除imhistline工具,也就是上面的对象d。
delete(d);
2.2 初步尝试圆识别
在圆识别之前,让我们先熟悉使用的函数:imfindcircles.
[centers,radii]=imfindcircles(A,radiusRange);
A即为输入的rgb图像,radiusRange就是上一步我们确定的搜索圆的大概半径,返回的centers和radii为检测到的圆心位置和对应的圆半径。
我们在MATLAB中输入:
[centers,radii]=imfindcircles(srcImage,[20,25]);
但却发现,返回的圆心和半径居然是空数组。没关系,这是正常现象,只是没检测到圆罢了,至少我们会简单使用imfindcircles这个函数了,但到底怎么才能检测到圆,继续往下看。
2.3 深入imfindcircles函数
让我们深究一下imfindcircles这个函数,通过MATLAB帮助文档,我们发现有这个语法:
[centers,radii,metric]=imfindcircles(A,radiusRange,Name,Value);
参数A和radiusRange已经在上面说过了,后面的Name是传递给imfindcircles函数的参数名称,value是对应的参数值。
具体的Name有:ObjectPolarity/Method/Sensitivity/EdgeThreshold。我们逐个参数分析:
1 ObjectPolarity
此参数用于指定检测的目标与背景之间的亮度关系。具体的值和含义为:
‘bright’(default):搜索比背景更亮的圆形对象;
‘dark’:搜索比背景更暗的圆形对象。
那么,我们怎么确定目标比背景更亮还是更暗呢?可以用下面的方法:
使用rgb2gray将彩色薯片转成灰度图。
grayImage=rgb2gray(srcImage);imshow(grayImage)
可以看出,灰度图中大部分圆比背景颜色更深,更暗,所以对于这张图的ObjectPolarity参数,设置为’dark’更合适。
2 Method
此参数用于指定累加器数组的算法,有下面两个值:
‘PhaseCode’(default):Atherton和Kerbyson的相位编码方法;
‘TwoStage’:这个算法使用的是两段圆霍夫变换。
3 Sensitivity
此参数设置圆形霍夫变换累加器数组的检测敏感度,此参数对于两个Method参数均有效果。默认值为0.85,可以设置为0-1内的数字。
较高的敏感度可以检测到弱圆和被遮挡的圆,但也会增加误检测的风险。
4 EdgeThreshold
此参数用于确定图像中边缘像素的梯度阈值,将阈值设置为较低的值时,imfindcircles会检测到更多的圆形对象(具有弱边和强边)。随着阈值值的增加,它会检测到较少具有弱边的圆。一般默认情况下,imfindcircles使用函数graysthresh自动选择边缘渐变阈值。
在返回的参数列表里,我们发现还多了一个参数metric。此参数返回的是检测到的圆的强度,圆强度是圆中心的相对强度。
MATLAB帮助文档里列出使用imfindcircles函数的几个tips:
①当输入的最小半径小于5时,imfindcircles的检测精度会受到影响。
②使用默认的算法(PhaseCode)会比TwoStage在半径近似时速度更快。
③两种检测算法都有其优缺点,检测结果因输入图片而异。
④当圆的圆心在图片外时,imfindcircles函数检测不到此圆。
⑤在检测二值图片时,imfindcircles函数会对其预处理,同样,检测rgb图片时,imfindcircles函数也会将其先转为灰度图像。
2.4 再次尝试圆识别
深入了解imfindcircles函数中各个参数的作用后,接下来进行真正的圆识别,并通过viscircles函数将检测到的圆在原图像中显示出来。
在MATLAB中输入:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','dark','Sensitivity',0.9);imshow(srcImage);h=viscircles(centers,radii);
我们发现,有部分圆已经被检测出来了。继续增大检测灵敏度:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','dark','Sensitivity',0.92);
delete(h);%删除之前画的圆h=viscircles(centers,radii);
可以看出,这次检测到了更多的圆。让我们尝试使用另外一种检测方法,其他参数不变:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','dark','Sensitivity',0.92,'Method','twostage');
delete(h);h=viscircles(centers,radii);
这次,除了比背景亮的黄色圆没有被检测出来之外,其他的圆都被检测出来了。
可以看出,使用TwoStage算法在灵敏度0.92时能检测更多的圆。一般来说,两种算法是互补的,有不同的优点。默认的PhaseCode方法速度更快,抗噪声,稳定性强,但想要达到与TwoStage算法相同的检测效果,则需要更高的灵敏度,我们采用默认算法,在0.95灵敏度下检测试试看:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','dark','Sensitivity',0.95);
delete(h);h=viscircles(centers,radii);
效果和TwoStage算法在灵敏度0.92下的检测结果一样。
2.5 完善圆识别
经过上面几个步骤的检测,除了比背景更亮的黄色薯片,其他都被检测出来了,下面我们来检测黄色圆,将ObjectPolarity参数设置为bright:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','bright','Sensitivity',0.95);
delete(h);h=viscircles(centers,radii);
有三个黄色圆被检测出来,还有一个边界较为模糊的圆没有被检测。我们将灵敏度调到0.95时,这个圆可以被检测,但除此之外还有橙色和蓝色的圆被检测出来,有兴趣的同学可以试一下。
那么如何做到在不重复检测的情况下检测到这个黄色的圆呢?一个我们忽视的参数EdgeThreshold派上了用场。边界模糊的黄色圆具有更低的边缘梯度,默认的边缘梯度值不能将这个圆的边缘识别出来,所以我们要降低边缘梯度的值:
[centers,radii]=imfindcircles(srcImage,[20,25],'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);
delete(h);h=viscircles(centers,radii);
可以看出,所有的黄色圆都被检测处出来了(虽然还有个绿色。。。)。
2.6 绘制检测出来的所有圆
本节将MATLAB识别圆的完整代码列出,仅供参考
srcImage=imread('coloredChips.png');
imshow(srcImage);
d=imdistline;
delete(d);
[centersDark,radiiDark]=imfindcircles(srcImage,[20,25],'ObjectPolarity','dark','Method','TwoStage','Sensitivity',0.92);
hDark=viscircles(centersDark,radiiDark,'EdgeColor','G'); %设定画出的圆的边界为绿色,其中EdgeColor不同版本不同,博主用的2014,新版本的MATLAB用Color即可。
[centersBright,radiiBright]=imfindcircles(srcImage,[20,25],'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);
hBright=viscircles(centersBright,radiiBright,'EdgeColor','B');
大功告成,所有的圆都被检测出来了。
大家可以尝试改一下imfindcircles函数中各种参数的值,看看有没有惊人的结果。
第一次写文章,难免由排版不好看、错误的地方,尽请指正。