9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充

9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充

1 算法原理

区域和其边界可以互求。

区域填充就是已知区域按边界提取可求得其边界,反过来已知边界通过填充也可得到区域。

区域填充的一个例子,已知一个区域边界点的集合A,它的补集Ac.可通过用结构元素对它膨胀,求补,和求交来填充区域。首先给边界内一个点赋深色像素值。然后根据下列选代公式填充。实验中因为Ac 比较难求,用原始图的补集代替。

image-20210808171441313

当Xk==Xk-1时停止选代。这种膨胀过程可称为条件膨胀过程。

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改第8行代码的图片地址:cv2.imread("image1.jpg", 0)

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

代码依赖包:

matplotlib  3.4.2
numpy  1.20.3
opencv-python  4.1.2.30
# pip安装
pip install matplotlib numpy opencv-python
import cv2
import numpy as np
import matplotlib.pyplot as plt
import copy
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

image = cv2.imread("image1.jpg", 0)
retval, image = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY_INV)

image_C = cv2.bitwise_not(image)
# 构造一个3×3的结构元素
element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dilate = cv2.dilate(image, element)  #
erode = cv2.erode(image, element)  # 腐蚀
# kernel形态运算的内核,一般由getStructuringElement函数生成,有三种形状
# MORPH_RECT 矩形
# MORPH_CROSS 交叉形
# MORPH_ELLIPSE 椭圆形

# 将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像
margin = cv2.absdiff(dilate, erode)

### 区域填充

"""
条件,原图像image 
     原图像补集 image_C
     边缘图像 margin
    
"""
r, c = margin.shape[:2]

Mark_1 = np.zeros((r,c), np.uint8)  # 创建一个和图像一样的全零的图像矩阵
kernel = np.ones((7, 7), np.uint8)

epoch_img_1 = np.zeros((r,c), np.uint8)
epoch_img_2 = np.zeros((r,c), np.uint8)
Mark_1[200][250] = 255  # 种子点
stop = 0
while True:
    stop = stop+1
    print(stop)
    if stop == 50:
        epoch_img_1 = copy.deepcopy(Mark_1)
    if stop == 100:
        epoch_img_2 = copy.deepcopy(Mark_1)
    if stop == 200:
        # break
        pass
    Mark_tmep = copy.deepcopy(Mark_1)
    Mark_1 = cv2.dilate(Mark_1, kernel) #图像膨胀处理

    Mark_1 = cv2.bitwise_and(Mark_1, image)  # 图像交集
    flag = 0
    for i in range(r):
        for j in range(c):
            if Mark_1[i][j] == Mark_tmep[i][j]:
                flag = 0
            else:
                flag = 1
                break
        if flag == 1:
            break
    if flag == 0:
        break


plt.subplot(231), plt.imshow(image, plt.cm.gray), plt.title('原始二值图像'), plt.axis('off')
plt.subplot(232), plt.imshow(image_C, plt.cm.gray), plt.title('原始补集')
plt.subplot(233), plt.imshow(margin, plt.cm.gray), plt.title('二值边缘图像'), plt.axis('off')
plt.subplot(234), plt.imshow(epoch_img_1, plt.cm.gray), plt.title('50轮填充'), plt.axis('off')
plt.subplot(235), plt.imshow(epoch_img_2, plt.cm.gray), plt.title('100轮填充'), plt.axis('off')
plt.subplot(236), plt.imshow(Mark_1, plt.cm.gray), plt.title('填充图像'), plt.axis('off')
# plt.savefig('2.3new-img.jpg")
plt.show()

对简单图片效果比较好。复杂图片不怎么样。

3 效果

image-20210808172108448

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值