DIP 数字图像处理3:形态学综合题(粒子测度实现)

文章目录

  • DIP 数字图像处理3:形态学综合题(粒子测度实现)
    • 1. 题目:计算粒子大小分布,并画出分布图
    • 2. 实验环境:
    • 3. 实验步骤:
    • 4. 实验中使用到的图像处理操作:
    • 5. 实验结果:
    • 6. 所有代码如下:


DIP 数字图像处理3:形态学综合题(粒子测度实现)

1. 题目:计算粒子大小分布,并画出分布图

提示:
1)选择合适的开运算结构元大小及增量步长,结构元取元素全为1的正方形结构元
2)原始图像与图像开运算后相减后,还要做灰度阈值处理,只考虑哪些灰度差足够大的区域
3)分布频率对应于灰度显著变化的区域的面积除以结构元大小(33,55,…)
提示:

  • 可用自动或手动方法排除背景干扰(即去掉自动评测的区域)!
  • 某一尺度下的WTH将保留比该尺度小的所有亮细节,要想得到单一尺度的亮细节,应该把比它小的细节都减去。比如WTH(n)- WTH(n-2)保留的就是尺度介于n到n-2的亮细节 (比如尺度n是(2n+1)*(2n+1)的结构元!)

2. 实验环境:

win10 + Python3.7 + OpenCV4.1

3. 实验步骤:

3.1 将原始图片转成灰度图,高斯去燥;
3.2 设置阈值二值化图像;
3.3 不断增加开运算中正方形结构元的大小,记录相邻两次的差值;
3.4 用面积的变化除以结构元的宽度,反应原图中粒子的尺寸;

4. 实验中使用到的图像处理操作:

4.1 彩色转灰度图
4.2 高斯模糊
4.3 阈值分割
4.4 开运算

5. 实验结果:

5.1 习题图片对应的粒子测度结果如下:
DIP 数字图像处理3:形态学综合题(粒子测度实现)_第1张图片
上图对应的粒子测度如下:
DIP 数字图像处理3:形态学综合题(粒子测度实现)_第2张图片
5.2 实验过程中,为了便于调试程序,自己绘制了更加简单的图片用于测试。测试图片和结果如下:
DIP 数字图像处理3:形态学综合题(粒子测度实现)_第3张图片
上图对应的粒子测度如下:
DIP 数字图像处理3:形态学综合题(粒子测度实现)_第4张图片
5.3. 实验结果说明:
图中的条状图越高,代表原始图片中,当前尺寸的圆越多。
图像中极大值的数目表示图片中圆的尺寸分布情况。
分析可知,第一张图片中主要存在三种尺寸的圆,小圆很多,中等圆较少,最大的“圆”(纸片)最少。

6. 所有代码如下:

#! -*- coding: utf-8 -*-
# py37
# 时间:2019年4月30日09:56:17
# DIP:形态学操作处理应用(粒子测度)
# 粒子测度是一种对图像中粒子的尺度分布进行测量的操作
# 原理:开操作对输入图像中与结构元尺度相似的粒子的亮区域影响最大

import cv2
import matplotlib.pyplot as plt


def particleMeasure(imgBin):
    sizes = []
    values = []
    # maxSize = int(imgBin.shape[0] / 4)  # 只分析比图像的高度小一半的圆
    maxSize = 100

    #  不断增加kernel的大小,计算开运算对图像的影响
    for size in range(3, maxSize, 2):
        # 定义结构元的类型和大小
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size - 2, size - 2))
        imgOpen_1 = cv2.morphologyEx(imgBin, cv2.MORPH_OPEN, kernel=kernel)
        # 定义结构元的类型和大小
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size, size))
        imgOpen_2 = cv2.morphologyEx(imgBin, cv2.MORPH_OPEN, kernel=kernel)

        diffImg = imgOpen_2 - imgOpen_1

        # image, cnts, hierarchy = cv2.findContours(diffImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 找轮廓
        diffValue = cv2.sumElems(diffImg)[0] / 255  # 统计一个通道腐蚀导致减少的点的数量

        sizes.append(size)  # 结构元的size 画图时的横坐标
        # if diffValue / (len(cnts) + 0.01) > 1:  # 总减少的面积/总的个数,等于每个减少的面积,只统计开操作使面积减少较大的结构元size
        values.append(diffValue / size)  # 区域的面积除以结构元的大小,画图时的纵坐标
        # else:
        #     values.append(0)
    MAX = max(values)
    values = [i if i > 0.03 * MAX else 0 for i in values]  # 去掉较小的数据
    values = [i / sum(values) for i in values]  # 计算各个尺寸占的比例
    return sizes, values


if __name__ == "__main__":
    # fileName = "Chapter5_1.bmp"  # 作业要求的测试图片
    fileName = "images5_1.png"  # 自己制作的测试图片
    img = cv2.imread(fileName)
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)  # 转成灰度图
    print(gray.shape)  # (274, 279)

    img2 = cv2.GaussianBlur(gray, (5, 5), 0.05)  # 平滑去燥
    _, imgBin = cv2.threshold(img2, 80, 255, type=cv2.THRESH_BINARY | cv2.THRESH_OTSU)  # 设阈值二值化

    sizes, values = particleMeasure(imgBin)  # 计算开操作对二值图的影响

    plt.bar(sizes, values)   # 绘制粒子测度图
    plt.text(30, 0.12, "remove low ratio data")
    plt.ylabel("ratio")
    plt.xlabel("rectangle kernel size")
    plt.show()
    print("END ")

THE END

你可能感兴趣的:(OpenCV)