【youcans 的 OpenCV 例程200篇】143. 基于灰度形态学的粒度测定
5.5 灰度形态学之粒度分析
粒度测度是指确定图像中颗粒的大小分布,属于判断图像中颗粒的尺寸分布的领域 。
由于颗粒通常并不是整齐地分隔排列,要通过逐个颗粒识别来计算颗粒数量非常困难。形态学可间接估计颗粒的大小分布,而不需要识别和测量每个颗粒。
开运算的特性是,某个尺寸的开运算会对包含了这个尺寸的区域产生最大的效果,而闭运算可以删除尺寸小于结构元的黑色区域。基于灰度形态学的粒度分析,原理就是对于比背景亮且形状规则的颗粒,使用逐渐增大的结构元对图像进行开运算。
对于每次开运算得到的图像,计算像素值之和,称为表面区域。由于开运算会减小图像中的亮特征,表面区域随结构元的增大而减小,由此得到一个一维阵列。计算一维阵列中相邻两个元素的差并绘图,曲线中的峰值就会指明图像中主要大小颗粒的分布。
例程 10.34:基于灰度形态学的粒度测定
本例是基于形态学重建的粒度测定,由使用逐渐增大的结构元对图像执行开操作组成。
测定图中木钉的尺寸。设置一个半径从小到大的结构元序列,依次对其做开操作,并且统计图像总灰度值,计算相邻灰度值的差。当结构元尺寸与木钉尺寸吻合时,会产生一个局部灰度高峰。比较不同尺寸的灰度差序列,峰值所对应的尺寸就是木钉的大致尺寸。
# 10.34: 基于灰度形态学的粒度测定
imgGray = cv2.imread("../images/Fig0941a.tif", flags=0) # flags=0 灰度图像
plt.figure(figsize=(9, 6))
plt.subplot(231), plt.imshow(imgGray, cmap='gray'), plt.title("origin"), plt.axis("off")
# 用不同半径圆形结构元进行开运算, 实现图像平滑
rList = [5, 10, 20, 25, 30]
for i in range(5):
size = rList[i] * 2 + 1
element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (size, size)) # 圆形结构元
imgOpen = cv2.morphologyEx(imgGray, cv2.MORPH_OPEN, element)
plt.subplot(2,3,i+2), plt.title("smoothed (r={})".format(rList[i])), plt.axis("off")
plt.imshow(imgOpen, cmap='gray')
plt.tight_layout()
plt.show()
maxSize = 40
sumSurf = np.zeros(maxSize)
deltaSum = np.zeros(maxSize)
for r in range(5, maxSize):
size = r * 2 + 1
element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (size, size)) # 圆形结构元
imgOpen = cv2.morphologyEx(imgGray, cv2.MORPH_OPEN, element)
sumSurf[r] = np.concatenate(imgOpen).sum()
deltaSum[r] = sumSurf[r-1] - sumSurf[r]
# print(r, sumSurf[r], deltaSum[r])
r = range(maxSize)
plt.figure(figsize=(8, 6))
plt.plot(r[6:], deltaSum[6:], 'b-o') # 腐蚀运算
plt.title("Delta of surface area")
plt.yticks([])
plt.show()
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/123786099)
Copyright 2022 youcans, XUPT
Crated:2022-3-30