图像分割-Grabcut法

news/2024/7/21 5:51:08 标签: 计算机视觉, 图像处理, Grabcut

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

本文的C#版本请访问:图像分割-Grabcut法(C#)-CSDN博客

GrabCut是一种基于图像分割的技术,它可以用于将图像中的前景和背景分离。在实现中,GrabCut算法通常需要使用高斯混合模型(GMM)来建立前景和背景的概率分布,以便更好的估计像素的标签。同时,还需要考虑如何处理边界处的像素,以避免边界处的像素被错误地分类。GrabCut算法在图像分割中有着广泛的应用,例如人像分割、物体抠图等。

EmguCV使用CvInvoke.GrabCut方法来执行GrabCut算法,该方法声明如下:

Public Shared Sub GrabCut (

         img As IInputArray,

         mask As IInputOutputArray,

         rect As Rectangle,

         bgdModel As IInputOutputArray,

         fgdModel As IInputOutputArray,

         iterCount As Integer,

         type As GrabcutInitType

)

参数说明:

  1. img:输入输出的图像,必须是三通道彩色图像。
  2. mask:指定的掩码图像,必须是单通道灰度图像,并且与输入图像具有相同的尺寸。可以传入0-3的值,分别为:0表示明显为背景的像素、1表示冥相位前景的像素、2表示可能为背景的像素、3表示可能为前景的像素。
  3. rect:指定的矩形框,用于定位大概率可能为前景目标的位置。
  4. bgdModel:背景模型,必须是单通道浮点型Mat。
  5. fgdModel:前景模型,必须是单通道浮点型Mat。
  6. iterCount:迭代次数,用于控制算法的收敛性。
  7. type:GrabCut算法初始化类型,可以选择GrabCutInitType.WithRect或GrabCutInitType.WithMask,分别表示根据提供的矩形初始化或根据掩码初始化。

该方法没有返回值,而是直接在mask图像上进行前景分割操作,最终获得的mask包含0-3的值,含义如参数中说明。

    'Grabcut法 
    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
        Dim m As New Mat("C:\learnEmgucv\tower.jpg", ImreadModes.AnyColor)

        Dim result As New Mat
        Dim bg As New Mat
        Dim fg As New Mat

        Dim rect As New Rectangle(80, 30, 680, 450)
        CvInvoke.GrabCut(m, result, rect, bg, fg, 1, GrabcutInitType.InitWithRect)
        '输出的result只有4个值:
        '0:确定背景
        '1:确定前景
        '2:可能背景
        '3:可能前景

        '演示框选范围
        CvInvoke.Rectangle(m, rect, New MCvScalar(255, 255, 255), 1)
        ImageBox1.Image = m

        '标记区域
        Dim matr As New Matrix(Of Byte)(result.Rows, result.Cols)
        result.CopyTo(matr)
        For i As Integer = 0 To matr.Cols - 1
            For j As Integer = 0 To matr.Rows - 1
                '将确定背景和可能背景标记为0,否则为255
                If matr(j, i) = 0 Or matr(j, i) = 2 Then
                    matr(j, i) = 0
                Else
                    matr(j, i) = 255
                End If
            Next
        Next
        Dim midm As New Mat
        midm = matr.Mat
        '显示标记的图像
        CvInvoke.Imshow("midm", midm)

        '灰度转为彩色
        Dim midm1 As New Mat
        CvInvoke.CvtColor(midm, midm1, ColorConversion.Gray2Bgr)
        Dim mout As New Mat
        'And运算
        CvInvoke.BitwiseAnd(m, midm1, mout)
        CvInvoke.Imshow("mout", mout)
End Sub

输出结果如下图所示:

图8-5 Grabcut法分离前景

   'Grabcut法 
    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
        Dim m As Mat = CvInvoke.Imread("C:\learnEmgucv\tower.jpg", CvEnum.ImreadModes.Color)

        Dim result As New Mat
        Dim bg As New Mat
        Dim fg As New Mat

        Dim rect As New Rectangle(80, 30, 680, 450)
        CvInvoke.GrabCut(m, result, rect, bg, fg, 5, CvEnum.GrabcutInitType.InitWithRect)

        Dim src As Image(Of Bgr, Byte) = m.ToImage(Of Bgr, Byte)
        Dim dst As New Image(Of Bgr, Byte)(New Size(src.Width, src.Height))

        Dim mask As Image(Of Gray, Byte) = result.ToImage(Of Gray, Byte)
        '直接操作Image像素点
        For i As Integer = 0 To src.Rows - 1
            For j As Integer = 0 To src.Cols - 1
                '如果是确定前景和可能前景,直接保留原像素点颜色,否则为黑色
                If mask.Data(i, j, 0) = 1 Or mask.Data(i, j, 0) = 3 Then
                    dst.Data(i, j, 0) = src.Data(i, j, 0)
                    dst.Data(i, j, 1) = src.Data(i, j, 1)
                    dst.Data(i, j, 2) = src.Data(i, j, 2)
                Else
                    dst.Data(i, j, 0) = 0
                    dst.Data(i, j, 1) = 0
                    dst.Data(i, j, 2) = 0
                End If

            Next
        Next
        ImageBox1.Image = dst
End Sub

输出结果如下图所示:

图8-6 Grabcut法分离前景

   '标记为确定前景,这里使用InitWithMask 参数
    Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
        Dim m As New Mat("c:\learnEmgucv\lena.jpg", ImreadModes.AnyColor)

        Dim mask As New Mat
        Dim bg As New Mat
        Dim fg As New Mat
        Dim rect As New Rectangle(80, 30, 340, 480)

        '使用前景为全白色
        Dim m1 As New Mat("c:\learnEmgucv\lena_fillwhite.jpg", ImreadModes.Grayscale)
        Dim mask1 As New Mat
        '二值化
        CvInvoke.Threshold(m1, mask1, 250, 1, ThresholdType.Binary)

        CvInvoke.Rectangle(m, rect, New MCvScalar(255, 255, 255), 1)

        '标记之后再调用GrabCut,使用InitWithMask参数
        CvInvoke.GrabCut(m, mask1, rect, bg, fg, 2, GrabcutInitType.InitWithMask)

        Dim matrx As New Matrix(Of Byte)(mask1.Rows, mask1.Cols)
        mask1.CopyTo(matrx)
        For i As Integer = 0 To matrx.Cols - 1
            For j As Integer = 0 To matrx.Rows - 1
                If matrx(i, j) = 0 Or matrx(i, j) = 2 Then
                    matrx(i, j) = 0
                Else
                    matrx(i, j) = 255
                End If
            Next
        Next
        Dim midm2 As New Mat
        midm2 = matrx.Mat

        Dim midm1 As New Mat
        CvInvoke.CvtColor(midm2, midm1, ColorConversion.Gray2Bgr)

        Dim mout As New Mat
        CvInvoke.BitwiseAnd(m, midm1, mout)
        CvInvoke.Imshow("mout", mout)
End Sub

输出结果如下图所示:

图8-7 Grabcut法分离前景

由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。

学习更多vb.net知识,请参看vb.net 教程 目录


http://www.niftyadmin.cn/n/5304629.html

相关文章

ASP.NET Core路由中间件[1]: 终结点与URL的映射

一、路由注册 我们演示的这个ASP.NET Core应用是一个简易版的天气预报站点。如果用户希望获取某个城市在未来N天之内的天气信息,他可以直接利用浏览器发送一个GET请求并将对应城市(采用电话区号表示)和天数设置在URL中。如下图所示&#xff…

linux 使用iniparser读取.ini文件的配置信息

为什么要用项目配置文件 对于很多程序中要用的参数如果是可变的,那么最好的处理方式就是通过main(int argc,char **argv) 函数参数传递,或者从别的地方去获取,这其中之一就是配置文件,但是在一个成熟和架构完善的系统&#xff0c…

Java业务功能并发问题处理

业务场景: 笔者负责的功能需要调用其他系统的进行审批,而接口的调用过程耗时有点长(可能长达10秒),一个订单能被多个人提交审批,当订单已提交后会更改为审批中,不能再次审批(下游系…

锂电池寿命预测 | Matlab基于LSTM长短期记忆神经网络的锂电池寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 锂电池寿命预测 | Matlab基于LSTM长短期记忆神经网络的锂电池寿命预测 程序设计 完整程序和数据获取方式:私信博主回复Matlab基于LSTM长短期记忆神经网络的锂电池寿命预测。 参考资料 [1] http://t.csdn…

字节跳动 Spark 支持万卡模型推理实践

摘要:本文整理自字节跳动基础架构工程师刘畅和字节跳动机器学习系统工程师张永强在本次 CommunityOverCode Asia 2023 中的《字节跳动 Spark 支持万卡模型推理实践》主题演讲。 背景介绍 在云原生化的发展过程中 Kubernetes 由于其强大的生态构建能力和影响力&…

可狱可囚的爬虫系列课程 10:在网站中寻找 API 接口

上一篇文章我们讲述了爬虫中一个比较重要的知识点,如何从 API 接口中获取数据,本篇文章我们继续讲述,如何在网站中寻找 API 接口,我们以“今日头条”网站 https://www.toutiao.com/ 为例。 如上图所示,如果要获取页面…

突破技术边界:R与jsonlite库探秘www.snapchat.com的数据之旅

概述 Snapchat是一款流行的社交媒体应用,它允许用户发送和接收带有滤镜和贴纸的照片和视频,以及创建和观看故事和发现内容。Snapchat的数据是非常有价值的,因为它可以反映用户的行为、偏好和趋势。然而,Snapchat的数据并不容易获…

Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。

本文主要记录遇到vscode运行HTML文件提示: Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。问题的解决办法。 目录 一、打开设置 二 、搜索Live Server Config (1)安装Live Server插件 &#xff0…