EmguCV学习笔记 VB.Net 11.6 图像分割

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

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问: EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问: EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步: EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

学习C#知识,请移步: C# 教程 目录_c#教程目录-CSDN博客

11.6 图像分割

11.6.1 语义分割Fcn

FCN(Fully Convolutional Network)是一种流行的语义分割算法,它通过将传统的卷积神经网络转化为全卷积网络来实现像素级别的语义分割,将输入图像传入网络中,得到每个像素的标签,并根据标签来分割出不同的物体。FCN在语义分割任务中表现优秀,可以实现像素级别的精细分割,被广泛应用于自动驾驶、智能监控等领域。

【代码位置:frmChapter11】Button5_Click、getColorTable、showColorTable

'语义分割fcn

Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

'对象分类,object_detection_classes_pascal_voc.txt文件提供了21类对象(含background)

Dim classnames() As String

classnames = File.ReadAllLines("C:\learnEmgucv\fcn\object_detection_classes_pascal_voc.txt")

'获得输出颜色表

Dim colorTable() As Bgr = getColorTable()

'显示颜色表及对应对象名称

Call showColorTable(classnames, colorTable)

'需要测试的图像文件

Dim m As New Mat("C:\learnEmgucv\dnntest1.jpg", ImreadModes.Color)

Dim hm As Single = m.Height

Dim wm As Single = m.Width

Dim net As Dnn.Net

net = DnnInvoke.ReadNetFromCaffe("C:\learnEmgucv\fcn\fcn8s-heavy-pascal.prototxt",

"C:\learnEmgucv\fcn\fcn8s-heavy-pascal.caffemodel"

)

Dim mcopy As New Mat

CvInvoke.Resize(m, mcopy, New Drawing.Size(500, 500))

Dim blob As Mat

blob = DnnInvoke.BlobFromImage(mcopy, 1, New Size(500, 500),

New MCvScalar(0, 0, 0), False, False)

net.SetInput(blob)

'

Dim mout As New Mat

mout = net.Forward()

Dim fout(,,,) As Single

fout = mout.GetData()

'通道数=21,即21类对象

Dim chan As Integer = fout.GetLength(1)

'高度=500

Dim row As Integer = fout.GetLength(2)

'宽度=500

Dim col As Integer = fout.GetLength(3)

'记录21个通道对应坐标点的最大值

Dim matrMaxValue As New Matrix(Of Single)(New Size(row, col))

matrMaxValue.SetZero()

''记录对应通道号

'Dim matrMaxChan As New Matrix(Of Single)(New Size(row, col))

'matrMaxChan.SetZero()

'记录对应颜色

Dim imgOut As New Image(Of Bgr, Byte)(col, row)

imgOut.SetZero()

'遍历21个通道

For c As Integer = 0 To chan - 1

For h As Integer = 0 To row - 1

'遍历高度和宽度,获得对应坐标的值

For w As Integer = 0 To col - 1

'比较最大值

If fout(0, c, h, w) > matrMaxValue(h, w) Then

'取得最大值

matrMaxValue(h, w) = fout(0, c, h, w)

''取得通道号

'matrMaxChan(h, w) = c

'最重要的是获取通道对应颜色表的值

imgOut(h, w) = colorTable(c)

End If

Next

Next

Next

'显示输出的图像

'ImageBox1.Image = imgOut.Mat

'设置掩膜

Dim mask As New Mat

mask = imgOut.Mat

'掩膜大小必须和源图像一致

CvInvoke.Resize(mask, mask, m.Size)

'将上面的输出图像和源图像叠加

Dim mFinalOut As New Mat

CvInvoke.AddWeighted(m, 0.3, mask, 0.7, 0, mFinalOut)

ImageBox1.Image = mFinalOut

End Sub

'为了更好地观察,这里没有使用随机颜色

Private Function getColorTable() As Bgr()

Dim newColors(20) As Bgr

newColors(0) = New Bgr(0, 0, 0) 'background

newColors(1) = New Bgr(128, 0, 0) 'aeroplane

newColors(2) = New Bgr(0, 128, 0) 'bicycle

newColors(3) = New Bgr(128, 128, 0) 'bird

newColors(4) = New Bgr(0, 0, 128) 'boat

newColors(5) = New Bgr(128, 0, 128) 'bottle

newColors(6) = New Bgr(0, 128, 128) 'bus

newColors(7) = New Bgr(128, 128, 128) 'car

newColors(8) = New Bgr(255, 0, 0) 'cat

newColors(9) = New Bgr(0, 255, 0) 'chair

newColors(10) = New Bgr(0, 0, 255) 'cow

newColors(11) = New Bgr(255, 255, 0) 'diningtable

newColors(12) = New Bgr(64, 0, 128) 'dog

newColors(13) = New Bgr(192, 0, 128) 'horse

newColors(14) = New Bgr(64, 128, 128) 'motorbike

newColors(15) = New Bgr(192, 128, 128) 'person

newColors(16) = New Bgr(0, 64, 0) 'pottedplant

newColors(17) = New Bgr(128, 64, 64) 'sheep

newColors(18) = New Bgr(0, 192, 0) 'sofa

newColors(19) = New Bgr(128, 192, 0) 'train

newColors(20) = New Bgr(0, 64, 128) 'tvmonitor

Return newColors

End Function

'显示颜色表及对象名称

'参数1:对象名称的字符串数组

'参数2:bgr颜色数组

Private Sub showColorTable(ByVal names() As String, ByVal colors() As Bgr)

Dim lstmoutV As New List(Of Mat)

For i As Integer = 0 To 20

Dim moutV As New Mat(40, 200, DepthType.Cv8U, 3)

moutV.SetTo(New MCvScalar(colors(i).Blue, colors(i).Green, colors(i).Red))

CvInvoke.PutText(moutV, names(i), New Point(20, 25), FontFace.HersheyTriplex, 0.4, New MCvScalar(255, 255, 255))

lstmoutV.Add(moutV)

Next

Dim mout As New Mat

'垂直方向拼接

CvInvoke.VConcat(lstmoutV.ToArray, mout)

CvInvoke.Imshow("colortable", mout)

End Sub

输出结果如下图所示:

图11-4 FCN分割获得不同对象区域

11.6.2 实例分割 MASK RCNN

Mask RCNN是一种基于Faster R-CNN的实例分割算法,它是一种联合目标检测和语义分割的方法,能够同时检测图像中的对象并得到每个对象的位置、类别和像素级别的分割结果。Mask RCNN在实例分割任务中表现优秀,是目前最先进的实例分割算法之一,被广泛应用于自动驾驶、智能监控等领域。

【代码位置:frmChapter11】Button6_Click、getRadomColor

'实例分割 mask rcnn

Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click

'对象分类,object_detection_classes_coco.txt文件提供了90类对象(含background)

Dim classnames() As String

classnames = File.ReadAllLines("C:\learnEmgucv\maskrcnn\object_detection_classes_coco.txt")

'需要测试的图像文件

Dim m As New Mat("C:\learnEmgucv\dnntest.jpg", ImreadModes.Color)

Dim hm As Single = m.Height

Dim wm As Single = m.Width

Dim net As Dnn.Net

net = DnnInvoke.ReadNetFromTensorflow("C:\learnEmgucv\maskrcnn\frozen_inference_graph.pb",

"C:\learnEmgucv\maskrcnn\mask_rcnn_inception_v2_coco_2018_01_28.pbtxt"

)

Dim mcopy As New Mat

mcopy = m.Clone

Dim blob As Mat

blob = DnnInvoke.BlobFromImage(mcopy, 1, New Size(500, 500),

New MCvScalar(0, 0, 0), False, False)

net.SetInput(blob)

Dim names(1) As String

names(0) = "detection_out_final"

names(1) = "detection_masks"

'返回的mout包含两个mat

Dim mout As New VectorOfMat

net.Forward(mout, names)

'第一个mat标识返回的置信度候选框,是一个四维数组

Dim moutBox As New Mat

moutBox = mout(0)

'返回维度:

'第1维:1,

'第2维:1,

'第3维:100,100个候选置信矩形框

'第4维:7,0:?;1:对应类别;2:置信度;3-6:候选框位置(源图像百分比)

Dim foutBox(,,,) As Single

foutBox = moutBox.GetData()

'第二个mat标识返回的掩膜,是一个四维数组

Dim moutMask As New Mat

moutMask = mout(1)

'返回维度:

'第1维:100,100个对象对应的100个掩膜

'第2维:90,对象的置信度

'第3维:15,掩膜高度

'第4维:15,掩膜宽度

Dim foutMask(,,,) As Single

foutMask = moutMask.GetData()

Dim maskH As Integer = 15 'foutMask.GetLength(2)

Dim maskW As Integer = 15 'foutMask.GetLength(3)

'新建Mat,用来在这上面绘制掩膜

Dim mbg As New Mat(New Size(m.Width, m.Height), DepthType.Cv8U, 3)

mbg.SetTo(New MCvScalar(0, 0, 0))

For i As Integer = 0 To 100 - 1

'置信度

Dim conf As Single = foutBox(0, 0, i, 2)

'当置信度满足时

If conf > 0.53 Then

'对应检测对象的序号

Dim objID As Integer = foutBox(0, 0, i, 1)

Dim ltX As Single = foutBox(0, 0, i, 3) * wm '左上角X

Dim ltY As Single = foutBox(0, 0, i, 4) * hm '左上角Y

Dim rbX As Single = foutBox(0, 0, i, 5) * wm '右下角X

Dim rbY As Single = foutBox(0, 0, i, 6) * hm '右下角Y

Dim w As Single = rbX - ltX '宽度

Dim h As Single = rbY - ltY '高度

'绘制包围矩形框

CvInvoke.Rectangle(m, New Rectangle(ltX, ltY, w, h), New MCvScalar(0, 0, 255), 1)

'绘制对象名称

CvInvoke.PutText(m, classnames(objID), New Point(ltX, ltY - 10), FontFace.HersheyTriplex, 0.3, New MCvScalar(255, 0, 0))

'开始处理掩膜

Dim mmask As New Mat()

'掩膜大小为15*15,对应foutMask最后两个维度

Dim bmask(14, 14) As Single

For j As Integer = 0 To 14

For k As Integer = 0 To 14

bmask(j, k) = foutMask(i, objID, j, k)

Next

Next

'将数组转为Mat

Dim matrmask As New Matrix(Of Single)(bmask)

mmask = matrmask.Mat

'大小放大与对应包围矩形框一致

CvInvoke.Resize(mmask, mmask, New Drawing.Size(w, h))

'二值化

CvInvoke.Threshold(mmask, mmask, 0.3, 255, ThresholdType.Binary)

'由于本身是CV32F,需要处理为CV8U,才能使用FindContours

mmask.ConvertTo(mmask, DepthType.Cv8U)

'定义关注区域,当修改关注区域时,也就修改了源图像

Dim mRoi As New Mat(mbg, New Rectangle(ltX, ltY, w, h))

'查找轮廓

Dim contours As New VectorOfVectorOfPoint

CvInvoke.FindContours(mmask, contours, Nothing, RetrType.External, ChainApproxMethod.ChainApproxSimple)

'填充轮廓

CvInvoke.DrawContours(mRoi, contours, -1, getRadomColor(), -1)

End If

Next

Dim mresult As New Mat

'加法

CvInvoke.AddWeighted(m, 1, mbg, 0.4, 0, mresult)

ImageBox1.Image = mresult

End Sub

'获得随机颜色

Private Function getRadomColor() As MCvScalar

Dim rd As New Random(Now.Millisecond)

Dim r, g, b As Byte

b = rd.Next(256)

g = rd.Next(256)

r = rd.Next(256)

Return New MCvScalar(b, g, r)

End Function

输出结果如下图所示:

图11-5 Mask RCNN 分割得到对象区域和类别

相关推荐
Jasmine_llq26 分钟前
《 火星人 》
算法·青少年编程·c#
军训猫猫头2 小时前
20.抽卡只有金,带保底(WPF) C#
ui·c#·wpf
黑色叉腰丶大魔王3 小时前
基于 MATLAB 的图像增强技术分享
图像处理·人工智能·计算机视觉
向宇it12 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
菜狗woc13 小时前
opencv-python的简单练习
人工智能·python·opencv
向宇it14 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
paixiaoxin15 小时前
CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究
人工智能·深度学习·机器学习·生成对抗网络·计算机视觉·ocr·.net
西猫雷婶15 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
AI视觉网奇15 小时前
人脸生成3d模型 Era3D
人工智能·计算机视觉
云空15 小时前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv