• OpenCV自学笔记二十:图像分割和提取


    1、用分水岭算法实现图像分割与提取

    分水岭算法是一种经典的图像分割算法,用于将图像中的前景和背景进行分离。它基于图像中的灰度值和梯度信息来确定边界,并通过填充区域将图像分割成多个连通的区域。

    以下是分水岭算法的基本原理:

    1. 预处理:首先对输入图像进行预处理操作,例如灰度化、平滑滤波和边缘检测等,以便更好地捕捉图像的特征。

    2. 计算梯度图:根据图像的梯度信息,生成一个梯度图像,用于表示图像中不同区域的边缘强度。

    3. 标记种子点:选择一些合适的种子点作为分水岭算法的起始标记点。这些种子点可以手动选择,也可以通过其他分割算法自动选择。

    4. 构建距离变换图:从种子点开始,计算每个像素到最近种子点的距离,并将其保存在一个距离变换图中。

    5. 寻找最小值点:对距离变换图进行处理,寻找局部最小值点,这些点表示图像中的低谷区域。

    6. 基于分水岭的图像分割:根据低谷区域,建立分水岭模型,并通过不断填充高度较小的区域来实现图像的分割。以下是一个简单的示例代码,演示如何使用Python和OpenCV库实现分水岭算法进行图像分割:

    1. import cv2
    2. import numpy as np
    3. # 读取图像
    4. image = cv2.imread('input_image.jpg')
    5. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    6. # 预处理操作
    7. blur = cv2.GaussianBlur(gray, (5, 5), 0)
    8. _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    9. # 距离变换
    10. dist_transform = cv2.distanceTransform(thresh, cv2.DIST_L2, 3)
    11. _, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)
    12. # 寻找未知区域
    13. sure_fg = np.uint8(sure_fg)
    14. unknown = cv2.subtract(thresh, sure_fg)
    15. # 标记种子点
    16. _, markers = cv2.connectedComponents(sure_fg)
    17. # 添加标记
    18. markers = markers + 1
    19. markers[unknown == 255] = 0
    20. # 应用分水岭算法
    21. markers = cv2.watershed(image, markers)
    22. image[markers == -1] = [0, 0, 255]
    23. # 显示结果
    24. cv2.imshow("Segmented Image", image)
    25. cv2.waitKey(0)
    26. cv2.destroyAllWindows()


    在上述示例中,我们首先对输入图像进行预处理,然后通过距离变换找到前景区域,并确定未知区域。接下来,我们使用连通组件算法标记种子点,将其与未知区域结合,并应用分水岭算法进行图像分割。最后,通过在分水岭标记处添加红色边界线,可视化显示分割结果。

    请注意,这只是分水岭算法的简单示例,实际应用中可能需要根据具体情况进行调整和优化。

    2、交互式前景提取

    交互式前景提取是一种图像处理技术,用于将图像中的前景对象从背景中分离出来。其原理基于计算机视觉和深度学习方法,以下是一个示例的交互式前景提取流程:

    1. 输入图像:首先,用户提供一张包含前景对象和背景的图像。

    2. 初始分割:使用图像分割算法(如GrabCut或基于超像素的方法),根据图像的纹理、颜色和边界信息对图像进行初步的前景-背景分割。

    3. 用户交互:系统展示初始分割结果,并允许用户进行交互。用户可以通过绘制笔刷指示前景和背景的区域,或者通过标记像素为前景或背景来指定感兴趣的区域。

    4. 更新分割:根据用户的交互信息,更新分割结果。通常使用图割(graph cuts)或随机游走(random walks)等优化方法来调整前景和背景的分割边界,使得分割结果更加准确。

    5. 迭代交互:重复步骤3和步骤4,直到用户满意为止。用户可以通过多次交互来逐渐改进分割结果。

    6. 输出前景:根据最终的分割结果,将前景对象从原始图像中提取出来,并生成一个包含前景的新图像。可以使用透明度通道或者二值掩码来表示前景对象。

    交互式前景提取的示例应用广泛,例如抠图、图像编辑和虚拟背景等。通过与用户的交互,可以精确地选择所需的前景和背景区域,从而实现更加准确和自定义的前景提取效果。
    下面是一个使用OpenCV实现交互式前景提取的简单示例:
     

    1. import cv2
    2. # 读取图像
    3. image = cv2.imread('input_image.jpg')
    4. # 创建一个窗口并设置鼠标回调函数
    5. cv2.namedWindow('image')
    6. mask = None
    7. def mouse_callback(event, x, y, flags, param):
    8.     global mask
    9.     
    10.     if event == cv2.EVENT_LBUTTONDOWN:
    11.         # 初始化掩码
    12.         mask = np.zeros(image.shape[:2], dtype=np.uint8)
    13.         cv2.circle(mask, (x, y), 5, (255), -1)
    14.         cv2.imshow('mask', mask)
    15.         # 进行GrabCut算法
    16.         bgdModel = np.zeros((1,65),np.float64)
    17.         fgdModel = np.zeros((1,65),np.float64)
    18.         rect = (x-50, y-50, 100, 100)  # 可根据具体情况调整矩形框的大小
    19.         cv2.grabCut(image, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)
    20.         # 更新掩码
    21.         mask = np.where((mask==2)|(mask==0), 0, 1).astype('uint8')
    22.         # 通过掩码提取前景
    23.         foreground = image * mask[:, :, np.newaxis]
    24.         cv2.imshow('foreground', foreground)
    25. # 设置鼠标回调函数
    26. cv2.setMouseCallback('image', mouse_callback)
    27. while True:
    28.     cv2.imshow('image', image)
    29.     k = cv2.waitKey(1)
    30.     
    31.     # 按下ESC键退出循环
    32.     if k == 27:
    33.         break
    34. cv2.destroyAllWindows()

    上述示例中,我们首先读取输入图像。然后,创建一个窗口并设置鼠标回调函数。在鼠标回调函数中,我们使用GrabCut算法进行前景提取,并根据用户点击的位置生成初始掩码。然后,根据掩码提取前景,并显示在窗口中。用户可以通过点击图像来指定感兴趣的前景区域。按下ESC键退出程序。

  • 相关阅读:
    【深度学习】笔记2-模型在测试集的准确率大于训练集
    统一配置中心Config、Bus组件的使用以及 SpringCloud 微服务工具集总结
    英语语法笔记
    用信号量实现进程互斥, 同步, 前驱关系
    LVM使用与管理
    SVG公众号排版 | 可重复点击显示和关闭图片,在Apple上无法正常关闭
    docker基础命令 docker镜像和docker容器的操作基础命令的思维导图
    Day5:三指针描述一颗树
    Android之MediaMetricsService实现本质(四十二)
    arthas 监控线程池相关对象
  • 原文地址:https://blog.csdn.net/m0_71721954/article/details/133146835