MATLAB:Image Processing Toolbox工具箱入门实战(1)

% 此段代码是为了清楚对象是比背景亮还是比背景暗,输出灰度图片看一看
% gray_image = rgb2gray(rgb);
% imshow(gray_image)

% 此段代码用来确定imfindcircles函数里的radiusRange,测出来应该是[25 30]
% d = drawline; % 画一条线,大致画出圆的直径
% pos = d.Position % 线的位置
% diffPos = diff(pos); % 各行之间的一阶差分,也就是delta x和delta y
% diameter = hypot(diffPos(1),diffPos(2)) % 平方和的平方根(斜边)

% 这里开始找圆,用的是imfindcircles()函数
% 背景相当亮,大多数塑料片比背景暗,将参数 ‘ObjectPolarity’ 设置为 ‘dark’ 以搜索较暗的圆。
% imfindcircles 有两种不同寻找圆的方法:默认方法(称为相位编码方法)/两阶段方法,这里指定使用两阶段方法
% 两种方法都能准确找到部分可见(遮挡)塑料片的中心和半径。
[centers,radii] = imfindcircles(rgb,[25 30],‘ObjectPolarity’,‘dark’, …
‘Sensitivity’,0.92,‘Method’,‘twostage’);

% 注意到黄色圆都没有被检测到
% 与背景相比,黄色塑料片的强度几乎相同,甚至更亮。因此,要检测黄色塑料片,‘ObjectPolarity’ 改为 ‘bright’。
% [centersBright,radiiBright] = imfindcircles(rgb,[25 30], …
% ‘ObjectPolarity’,‘bright’,‘Sensitivity’,0.95)
% 找到了三个原先未检测到的黄色塑料片,但仍有黄色塑料片未检测到

% 要查找圆,imfindcircles 仅使用图像中的边缘像素。这些边缘像素基本上是具有高梯度值的像素。
% ‘EdgeThreshold’ 参数控制像素的梯度值必须有多高,才能将其视为边缘像素并包含在计算中。
% 该参数的高值(更接近 1)只允许包含强边缘(较高梯度值),而低值(更接近 0)的宽容度更高,可在计算中包含较弱的边缘(较低梯度值)。
% 对于检测不到黄色塑料片的情况,是因为对比度低,一些边界像素(在塑料片的圆周上)预期具有低梯度值。因此,请降低 ‘EdgeThreshold’。
[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[25 30], …
‘ObjectPolarity’,‘bright’,‘Sensitivity’,0.95,‘EdgeThreshold’,0.1);

imshow(rgb)
hBright = viscircles(centersBright, radiiBright,‘Color’,‘b’); % 蓝色画出
h = viscircles(centers,radii); % 红色画出


![](https://img-blog.csdnimg.cn/direct/270e92d7cd1745bf8020aa6533d0983c.png)


#### 3.实战项目二:图像增强(预处理)统计米粒


本案例说明如何在分析前的预处理步骤增强图像。例如校正背景亮度不均匀问题,并将图像转换为二值图像,以便于识别前景对象(单个米粒)。然后分析对象,例如计算每粒大米的面积,并计算图像中所有对象的统计量。


关于**形态学图像处理**的知识(strel腐蚀和imopen形态学开操作),可参考冈萨雷斯的数字图像处理第9章和以下资料:


[形态学运算与仿真:图像处理中形态学操作的简单解释 - 知乎 (zhihu.com)![icon-default.png?t=N7T8](https://csdnimg.cn/release/blog_editor_html/release2.3.6/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=N7T8)https://zhuanlan.zhihu.com/p/628780157](https://zhuanlan.zhihu.com/p/628780157 "形态学运算与仿真:图像处理中形态学操作的简单解释 - 知乎 (zhihu.com)")


简而言之,形态学运算包括膨胀、腐蚀、开运算、闭运算等。其中:


* 膨胀操作可以将图像中的物体变大,使它更加连通;
* 腐蚀操作则可以将图像中的物体变小,使它更加细化;
* 开运算可以去除噪声,平滑图像的边缘;
* 闭运算可以填补图像中物体的孔洞。


这里应用strel腐蚀和imopen形态学开操作,目的是得到背景。


经过预处理得到图像的二值版本,然后利用bwconncomp()在二值图像中查找所有连通分量(对象)得到所有米粒的信息。最后展示了经过预处理后的图片和米粒面积的直方图:


![](https://img-blog.csdnimg.cn/direct/82d9cf0012354ea68dc81fed2b33180a.png)



I = imread(‘rice.png’);
% imshow(I)

% strel 对象表示一个平面形态学结构元素,该元素是形态学膨胀和腐蚀运算的重要部分。
se = strel(‘disk’,15);
% 开操作Open先对图像进行腐蚀操作,然后再进行膨胀操作的组合过程,可以用于消除小的物体或细节,并且可以平滑物体的边界
% 闭操作Close则相反,它是先对图像进行膨胀操作,然后再进行腐蚀操作的组合过程。可以用于填补小的空洞或裂缝,并且也可以平滑物体的边界。
% imopen执行形态学开操作,然后得到背景
background = imopen(I,se);
% imshow(background)
I2 = I - background;
% 默认情况下,imadjust 对所有像素值中最低的 1% 和最高的 1% 进行饱和处理。此运算可提高输出图像的对比度。
I3 = imadjust(I2);
bw = imbinarize(I3); % 使用 imbinarize 函数将灰度图像转换为二值图像
bw = bwareaopen(bw,50); % 使用 bwareaopen 函数去除图像中的背景噪声。
cc = bwconncomp(bw,4); % bwconncomp查找二值图像中的连通分量
% cc.NumObjects
labeled = labelmatrix(cc); % 使用 labelmatrix 根据 bwconncomp 的输出创建标签矩阵,将二进制图像中的连通分量标记为唯一的整数值。使用标签矩阵可视化不同的连通分量。
RGB_label = label2rgb(labeled,‘spring’,‘c’,‘shuffle’); % 为了更容易区分不同的连通分量,使用label2rgb将标签矩阵显示为RGB图像,并对标签的颜色随机。
% imshow(RGB_label)
graindata = regionprops(cc,‘basic’); % regionprops返回二值图像中每个8连通分量(对象)的属性集的测量值。
grain_areas = [graindata.Area];
histogram(grain_areas)
title(‘Histogram of Rice Grain Area’)


![](https://img-blog.csdnimg.cn/direct/8680f862733e49edb7efb1c3102d494e.png)



![](https://img-blog.csdnimg.cn/direct/033799967c3e45d99bcdad2168ec2f44.png)


#### 4.实战项目三:利用Sobel算子进行裂纹检测


Sobel算子实现步骤:


1.首先需要两个方向(水平和竖直方向)的滤波核:


![S_x=\begin{bmatrix} -1 &0 &1 \\ -2 &0 &2 \\ -1 &0 &1 \end{bmatrix},S_y=\begin{bmatrix} -1 &-2 &-1 \\ 0 &0 &0 \\ 1 &2 &1 \end{bmatrix}=S_{x}^{T}](https://latex.csdn.net/eq?S_x%3D%5Cbegin%7Bbmatrix%7D%20-1%20%260%20%261%20%5C%5C%20-2%20%260%20%262%20%5C%5C%20-1%20%260%20%261%20%5Cend%7Bbmatrix%7D%2CS_y%3D%5Cbegin%7Bbmatrix%7D%20-1%20%26-2%20%26-1%20%5C%5C%200%20%260%20%260%20%5C%5C%201%20%262%20%261%20%5Cend%7Bbmatrix%7D%3DS_%7Bx%7D%5E%7BT%7D)


这是因为边缘检测的**目的**是**标识数字图像中亮度变化明显的点**。**图像属性中的显著变化通常反映了属性的重要事件和变化**。所以通常说来图像中梯度较大的点代表着边缘。边缘检测方法分为两类:


* 基于搜索:利用一阶导数最大值检测边缘。通过寻找图像**一阶导数中的最大值**来**检测边界**,然后**利用计算结果估计边缘的局部方向**,代表算法是**Sobel算子**和**Scharr算子**。这是因为**边缘附近的像素值会有明显突变,即变化最大,也就是一阶导数最大(实际操作中通常设置一个阈值)。那么找到最大的一阶导数也就找到了像素变化最大的点,即边缘点。**
* 基于零穿越:利用二阶导数为0检测边缘。代表算法是**Laplace算子**。因为**在一阶导数的基础上再求一次导,那么此时零点就是变化最大的点,即边缘点。**


导数定义:![f{}'(x)=\lim_{h \to 0}\frac{f(x+h)-f(x-h)}{2h}](https://latex.csdn.net/eq?f%7B%7D%27%28x%29%3D%5Clim_%7Bh%20%5Cto%200%7D%5Cfrac%7Bf%28x+h%29-f%28x-h%29%7D%7B2h%7D)


对于不连续的函数,一阶导数(一阶均差)可以写作:


![f{}'(x)=f(x+1)-f(x)=f(x)-f(x-1)](https://latex.csdn.net/eq?f%7B%7D%27%28x%29%3Df%28x+1%29-f%28x%29%3Df%28x%29-f%28x-1%29)


所以有:![f{}'(x)=\frac{f(x+1)-f(x)+f(x)-f(x-1)}{2}=\frac{f(x+1)-f(x-1)}{2}](https://latex.csdn.net/eq?f%7B%7D%27%28x%29%3D%5Cfrac%7Bf%28x+1%29-f%28x%29+f%28x%29-f%28x-1%29%7D%7B2%7D%3D%5Cfrac%7Bf%28x+1%29-f%28x-1%29%7D%7B2%7D),也就是后-前。


因此我们有:


x方向的梯度:拿后一列(下标j+1)减去前一列(下标j-1):


![\frac{\partial f}{\partial x}=\left |[f(i-1,j+1)+f(i,j+1)+f(i+1,j+1)]-[f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)] \right |](https://latex.csdn.net/eq?%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%3D%5Cleft%20%7C%5Bf%28i-1%2Cj+1%29+f%28i%2Cj+1%29+f%28i+1%2Cj+1%29%5D-%5Bf%28i-1%2Cj-1%29+f%28i%2Cj-1%29+f%28i+1%2Cj-1%29%5D%20%5Cright%20%7C)


y方向的梯度:拿后一行(下标i+1)减去前一行(下标i-1):


![\frac{\partial f}{\partial y}=\left |[f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)]-[f(i-1,j-1)+f(i-1,j)+f(i-1,j+1)] \right |](https://latex.csdn.net/eq?%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%3D%5Cleft%20%7C%5Bf%28i+1%2Cj-1%29+f%28i+1%2Cj%29+f%28i+1%2Cj+1%29%5D-%5Bf%28i-1%2Cj-1%29+f%28i-1%2Cj%29+f%28i-1%2Cj+1%29%5D%20%5Cright%20%7C)


写成卷积表达式就是:


![S_x=\begin{bmatrix} -1 &0 &1 \\ -1 &0 &1 \\ -1 &0 &1 \end{bmatrix},S_y=\begin{bmatrix} -1 &-1 &-1 \\ 0 &0 &0 \\ 1 &1 &1 \end{bmatrix}=S_{x}^{T}](https://latex.csdn.net/eq?S_x%3D%5Cbegin%7Bbmatrix%7D%20-1%20%260%20%261%20%5C%5C%20-1%20%260%20%261%20%5C%5C%20-1%20%260%20%261%20%5Cend%7Bbmatrix%7D%2CS_y%3D%5Cbegin%7Bbmatrix%7D%20-1%20%26-1%20%26-1%20%5C%5C%200%20%260%20%260%20%5C%5C%201%20%261%20%261%20%5Cend%7Bbmatrix%7D%3DS_%7Bx%7D%5E%7BT%7D)


![\frac{\partial f}{\partial x}=S_x\bigotimes f,\frac{\partial f}{\partial y}=S_y\bigotimes f](https://latex.csdn.net/eq?%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%3DS_x%5Cbigotimes%20f%2C%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%3DS_y%5Cbigotimes%20f)


梯度:![\nabla f=[\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}],\left \| \nabla f \right \|=\sqrt{\left | \frac{\partial f}{\partial x} \right |^2+\left |\frac{\partial f}{\partial y} \right |^2}](https://latex.csdn.net/eq?%5Cnabla%20f%3D%5B%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%2C%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%5D%2C%5Cleft%20%5C%7C%20%5Cnabla%20f%20%5Cright%20%5C%7C%3D%5Csqrt%7B%5Cleft%20%7C%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%20%5Cright%20%7C%5E2+%5Cleft%20%7C%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%20%5Cright%20%7C%5E2%7D)


为计算方便起见,通常:![\left \| \nabla f \right \|=\left | \frac{\partial f}{\partial x} \right |+\left |\frac{\partial f}{\partial y} \right |](https://latex.csdn.net/eq?%5Cleft%20%5C%7C%20%5Cnabla%20f%20%5Cright%20%5C%7C%3D%5Cleft%20%7C%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%20%5Cright%20%7C+%5Cleft%20%7C%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%20%5Cright%20%7C)


以上卷积核![S_x=\begin{bmatrix} -1 &0 &1 \\ -1 &0 &1 \\ -1 &0 &1 \end{bmatrix},S_y=\begin{bmatrix} -1 &-1 &-1 \\ 0 &0 &0 \\ 1 &1 &1 \end{bmatrix}=S_{x}^{T}](https://latex.csdn.net/eq?S_x%3D%5Cbegin%7Bbmatrix%7D%20-1%20%260%20%261%20%5C%5C%20-1%20%260%20%261%20%5C%5C%20-1%20%260%20%261%20%5Cend%7Bbmatrix%7D%2CS_y%3D%5Cbegin%7Bbmatrix%7D%20-1%20%26-1%20%26-1%20%5C%5C%200%20%260%20%260%20%5C%5C%201%20%261%20%261%20%5Cend%7Bbmatrix%7D%3DS_%7Bx%7D%5E%7BT%7D)称为**Prewitt算子**。现在我们在计算梯度时引入加权平均,就构成了**Sobel算子**和**Schar算子:**


**Sobel算子提高了4邻域的权重:**![S_x=\begin{bmatrix} -1 &0 &1 \\ -2 &0 &2 \\ -1 &0 &1 \end{bmatrix},S_y=\begin{bmatrix} -1 &-2 &-1 \\ 0 &0 &0 \\ 1 &2 &1 \end{bmatrix}=S_{x}^{T}](https://latex.csdn.net/eq?S_x%3D%5Cbegin%7Bbmatrix%7D%20-1%20%260%20%261%20%5C%5C%20-2%20%260%20%262%20%5C%5C%20-1%20%260%20%261%20%5Cend%7Bbmatrix%7D%2CS_y%3D%5Cbegin%7Bbmatrix%7D%20-1%20%26-2%20%26-1%20%5C%5C%200%20%260%20%260%20%5C%5C%201%20%262%20%261%20%5Cend%7Bbmatrix%7D%3DS_%7Bx%7D%5E%7BT%7D)


**Schar算子**能弥补Sobel**内核为3**时的误差:![S_x=\begin{bmatrix} -3 &0 &3 \\ -10 &0 &10 \\ -3 &0 &3 \end{bmatrix},S_y=\begin{bmatrix} -3 &-10 &-3 \\ 0 &0 &0 \\ 3 &10 &3 \end{bmatrix}=S_{x}^{T}](https://latex.csdn.net/eq?S_x%3D%5Cbegin%7Bbmatrix%7D%20-3%20%260%20%263%20%5C%5C%20-10%20%260%20%2610%20%5C%5C%20-3%20%260%20%263%20%5Cend%7Bbmatrix%7D%2CS_y%3D%5Cbegin%7Bbmatrix%7D%20-3%20%26-10%20%26-3%20%5C%5C%200%20%260%20%260%20%5C%5C%203%20%2610%20%263%20%5Cend%7Bbmatrix%7D%3DS_%7Bx%7D%5E%7BT%7D)


以下是Sobel算子的代码实现(Matlab):



%% 1.导入
img=imread(“2.png”);
[x,y,z]=size(img);
img=im2double(img); % 数据类型转化uint8–>double,uint8类型参与运算容易溢出
if(z==3) % rgb–>gray
img_gray=(img(:,:,1).229+img(:,:,2).578+img(:,:,3).114)./1000;
end
%% 2.Sobel算子锐化
img_sobel=zeros(x,y);
img_sobelx=img_sobel;
img_sobely=img_sobel;
for i=2:x-1
for j=2:y-1
img_sobelx(i,j)=abs(img_gray(i-1,j+1)-img_gray(i-1,j-1)+2
img_gray(i,j+1)-2
img_gray(i,j-1)+img_gray(i+1,j+1)-img_gray(i+1,j-1));
img_sobely(i,j)=abs(img_gray(i-1,j-1)-img_gray(i+1,j-1)+2
img_gray(i-1,j)-2*img_gray(i+1,j)+img_gray(i-1,j+1)-img_gray(i+1,j+1));
end
end
img_sobel=img_sobelx+img_sobely;
for i=1:x
for j=1:y
if img_sobel(i,j)>0.3
img_sobel(i,j)=1;
else
img_sobel(i,j)=0;
end
end
end
figure(1)
imshow(img) % 原图
figure(2)
imshow(img_sobel) % 进行过Sobel之后的
%% 3.去噪
BW = bwareaopen(img_sobel,8);
figure(3)
imshow(BW)
%% 4.求连通分量,统计裂纹特征
cc = bwconncomp(BW,4);
labeled = labelmatrix(cc);
graindata = regionprops(cc,‘basic’);
grain_areas = [graindata.Area];
%% 5.画图
figure
histogram(grain_areas)
title(‘Histogram of Crack Area’)




![](https://img-blog.csdnimg.cn/direct/527daa3e290c4c56b40fb836dbf002fc.png)

 原图 
 




![](https://img-blog.csdnimg.cn/direct/25b652d3782c44e1a5c5f0749509cb8e.png)

 经过Sobel算子锐化后的图像 
 




![](https://img-blog.csdnimg.cn/direct/55b0749f335c4389af02d0d4e82a03b0.png)

 对上述锐化过的图像进行去噪 
 




![](https://img-blog.csdnimg.cn/direct/02350f434f9943619830c012af8c97de.png)

 裂纹面积特征统计直方图 
 


以下是用Canny算子检测的图像代码(Python):



import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

读取图像

img = cv2.imread(‘F:/2.png’)
img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转成RGB方便后面显示

灰度化处理图像

grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
img

52689779)]
[外链图片转存中…(img-hx4IC0ky-1712852689779)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
[外链图片转存中…(img-DqTabbAd-1712852689779)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值