Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗

这篇具有很好参考价值的文章主要介绍了Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

漫水填充法

漫水填充算法是根据像素灰度值之间的差值寻找相同区域实现分割。我们可以将图像的灰度值理解成像素点的高度,这样一张图像可以看成崎岖不平的地面或者山区,向地面上某一个低洼的地方倾倒一定量的水,水将会掩盖低于某个高度的区域。漫水填充法利用的就是这样的原理,其形式与注水相似,因此被称形象的称为“漫水”。

与向地面注水一致,漫水填充法也需要在图像选择一个注水像素,该像素被称为种子点,种子点按照一定规则不断向外扩散,从而形成具有相似特征的独立区域,进而实现图像分割。漫水填充分割法主要分为以下三个步骤:

  • 选择种子点(x,y);
  • 以种子点为中心,判断4邻域或者8邻域的像素值与种子点像素值的差值,将差值小于阈值的像素点添加进区域内。
  • 将新加入的像素点作为新的种子点,反复执行第二步,直到没有新的像素点被添加进该区域。

计算方式:

  • in case of a grayscale image and floating range(灰度图,浮动范围)

src(x′,y′)−loDiff≤src(x,y)≤src(x′,y′)+upDiff\texttt{src} (x’,y’)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x’,y’)+ \texttt{upDiff}src(x′,y′)−loDiff≤src(x,y)≤src(x′,y′)+upDiff

  • in case of a grayscale image and fixed range(灰度图,固定范围)

src(seedPoint.x,seedPoint.y)−loDiff≤src(x,y)≤src(seedPoint.x,seedPoint.y)+upDiff\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)+ \texttt{upDiff}src(seedPoint.x,seedPoint.y)−loDiff≤src(x,y)≤src(seedPoint.x,seedPoint.y)+upDiff

  • in case of a color image and floating range(彩色图,浮动范围)

src(x′,y′)r−loDiffr≤src(x,y)r≤src(x′,y′)r+upDiffr,\texttt{src} (x’,y’)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x’,y’)_r+ \texttt{upDiff} _r,src(x′,y′)r​−loDiffr​≤src(x,y)r​≤src(x′,y′)r​+upDiffr​,

src(x′,y′)g−loDiffg≤src(x,y)g≤src(x′,y′)g+upDiffg\texttt{src} (x’,y’)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x’,y’)_g+ \texttt{upDiff} _gsrc(x′,y′)g​−loDiffg​≤src(x,y)g​≤src(x′,y′)g​+upDiffg​

and

src(x′,y′)b−loDiffb≤src(x,y)b≤src(x′,y′)b+upDiffb\texttt{src} (x’,y’)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x’,y’)_b+ \texttt{upDiff} _bsrc(x′,y′)b​−loDiffb​≤src(x,y)b​≤src(x′,y′)b​+upDiffb​

  • in case of a color image and fixed range(彩色图,固定范围)

src(seedPoint.x,seedPoint.y)r−loDiffr≤src(x,y)r≤src(seedPoint.x,seedPoint.y)r+upDiffr,\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r+ \texttt{upDiff} _r,src(seedPoint.x,seedPoint.y)r​−loDiffr​≤src(x,y)r​≤src(seedPoint.x,seedPoint.y)r​+upDiffr​,

src(seedPoint.x,seedPoint.y)g−loDiffg≤src(x,y)g≤src(seedPoint.x,seedPoint.y)g+upDiffg\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g+ \texttt{upDiff} _gsrc(seedPoint.x,seedPoint.y)g​−loDiffg​≤src(x,y)g​≤src(seedPoint.x,seedPoint.y)g​+upDiffg​

and

src(seedPoint.x,seedPoint.y)b−loDiffb≤src(x,y)b≤src(seedPoint.x,seedPoint.y)b+upDiffb\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b+ \texttt{upDiff} _bsrc(seedPoint.x,seedPoint.y)b​−loDiffb​≤src(x,y)b​≤src(seedPoint.x,seedPoint.y)b​+upDiffb​

上述公式中,src(x′,y′)表示该区域内已知的相邻像素的值。简言之,当为浮动范围时,只有和已经属于某区域内的邻域相差足够小(满足公式范围),才能被选中进入该区域;当为固定范围时,只需要和种子像素相差足够小,就可以被选中进入该区域。

API

public static int floodFill(Mat image, Mat mask, Point seedPoint, Scalar newVal, Rect rect, Scalar loDiff, Scalar upDiff, int flags)

  • 返回值:填充像素数目。

  • 参数一:image,输入和输出图像,图像可以为CV_8U或者CV_32F类型的单通道或者三通道图像。当最后一个参数设置为FLOODFILL_MASK_ONLY标志时,不改变原始图像。

  • 参数二:mask,操作掩码,为单通道8位图像,比输入图像宽2像素,高2像素。由于mask既是输入参数又是输出参数,必须初始化。漫水填充不会填充掩码中的非零区域。例如,边缘检测的输出可以用作操作掩码来防止漫水填充边缘。

  • 参数三:seedPoint,种子点。

  • 参数四:newVal,重新绘制的域像素的新值。

  • 参数五:rect,默认为 0,用于设置 floodFill 函数将要重绘的最小边界矩形区域,即若漫水填充区域 < rect,则不进行填充。

  • 参数六:loDiff,添加进种子点区域条件的下界差值。表示当前观察像素值与其邻域像素值或待加入的种子像素值之间的亮度或颜色的最大负差。

  • 参数七:upDiff,添加进种子点区域条件的上界差值。表示当前观察像素值与其邻域像素值或待加入的种子像素值之间的亮度或颜色的最大正差。

  • 参数八:flags,漫水填充法的操作标志位。该标志由3部分组成,第一部分表示邻域的种类,4邻域或者8邻域;第二部分表示掩码矩阵中被填充像素点的新像素值;第三部分是填充算法的规则标志。int 类型操作标识符,默认值为 4,一共 23 位。

  • 低八位(0~7):用于控制算法的连通性,可取 4(默认值)或 8。如果设为 4,表示填充算法只考虑当前像素水平或处置方向的相邻点,如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。

  • 中间八位(8~15):用于指定填充掩码图像的值的,如果中间八位的值为 0,则掩码会用 1 来填充。

  • 高八位(16~23):可以为 0,或者以下两种选择标识符的组合。

FLOODFILL_FIXED_RANGE:如果设置为这个标识符,就会考虑当前像素与种子之间的差,否则就考虑当前像素与其邻域像素的差。

FLOODFILL_MASK_ONLY,如果设置为这个标识符,函数不会去填充改变原始图像,而是去填充掩膜图像。也就是忽略第三个参数newVal

// C++: enum FloodFillFlags
public static final int
FLOODFILL_FIXED_RANGE = 1 << 16,
FLOODFILL_MASK_ONLY = 1 << 17;

所以, flag 可以用 按位或,即‘|’ 连接起来。例如想用 4 邻域填充,并填充固定像素范围,填充掩码而不是填充原图,以及设置填充值为 250,那么输入的参数为

4 or (250 shl 8) or Imgproc.FLOODFILL_FIXED_RANGE or Imgproc.FLOODFILL_MASK_ONLY

操作

/**

  • 图像分割–漫水填充法
  • author: yidong
  • 2020/11/7
    */
    class FloodFillActivity : AppCompatActivity() {
    private val mBinding by lazy { ActivityFloodFillBinding.inflate(layoutInflater) }
    private lateinit var mMenuDialog: BottomSheetDialog
    private lateinit var mMenuDialogBinding: LayoutFloodFillMenuBinding

private var mConnectionType = 4
private var mFloodFillFlag = 0
private var mScalarNumber = 250 shl 8

private lateinit var mRgb: Mat
private var loDiff = 0.0
set(value) {
field = value
doFloodFill()
}
private var upDiff = 0.0
set(value) {
field = value
doFloodFill()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(mBinding.root)
val bgr = Utils.loadResource(this, R.drawable.wedding)
mRgb = Mat()
Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
mBinding.ivLena.showMat(mRgb)
mBinding.sbLow.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
mBinding.tvLoDiff.text = p1.toString()
loDiff = p1.toDouble()
}

override fun onStartTrackingTouch(p0: SeekBar?) {
}

override fun onStopTrackingTouch(p0: SeekBar?) {
}

})
mBinding.sbUp.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
mBinding.tvUpDiff.text = p1.toString()
upDiff = p1.toDouble()
}

override fun onStartTrackingTouch(p0: SeekBar?) {
}

override fun onStopTrackingTouch(p0: SeekBar?) {
}

})
mBinding.btFlag.setOnClickListener {
showMenuDialog()
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗,程序员,android,opencv,计算机视觉

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-845976.html

特别适合有3-5年开发经验的Android程序员们学习。**

[外链图片转存中…(img-pkDEvD3n-1712341308844)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

到了这里,关于Android OpenCV(四十一):图像分割(漫水填充法),看完豁然开朗的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • python opencv实现找到图像的轮廓,填充颜色

    python opencv实现找到图像的轮廓,填充颜色

    我想找到图片中的闭合圈,然后填充颜色 所需要的cv函数: 1。 OpenCV提供的findContours()方法可以通过计算图像梯度来判断出图像的边缘,然后将边缘的点封装成数组返回。    image : 为检测的图像,必须是8位单通道二值图像。如果原图为彩色的,必须转为灰度图,并通过二值

    2024年02月04日
    浏览(9)
  • 【opencv】示例-inpaint.cpp 图像修复是通过填充损坏图像部分从而修复这些损坏的过程...

    【opencv】示例-inpaint.cpp 图像修复是通过填充损坏图像部分从而修复这些损坏的过程...

    原始图像 这段代码展示了一个使用OpenCV库进行图像修复的例子。它首先包含了处理图像编码、解码、显示、处理和照片处理所必要的OpenCV模块的头文件。然后利用cv和std命名空间下的类和方法。通过定义一个鼠标回调函数onMouse来处理图像上的绘图操作,并通过主函数main处理

    2024年04月25日
    浏览(11)
  • OpenCV(十一):图像仿射变换

    OpenCV(十一):图像仿射变换

    目录 1.图像仿射变换介绍  仿射变换: 仿射变换矩阵: 仿射变换公式: 2.仿射变换函数 仿射变换函数:warpAffine() 图像旋转:getRotationMatrix2D() 计算仿射变换矩阵:getAffineTransform()  3.demo 1.图像仿射变换介绍  仿射变换:        仿射变换是由平移、缩放、旋转、翻转和错切组

    2024年02月10日
    浏览(35)
  • Android OpenCV(四十三),Android程序员面试必备的知识点

    Android OpenCV(四十三),Android程序员面试必备的知识点

    标志位 值 含义 GC_INIT_WITH_RECT 0 使用提供的矩形初始化状态和掩码。 之后根据算法进行迭代更新 GC_INIT_WITH_MASK 1 使用提供的掩码初始化状态。 可以组合使用GC_INIT_WITH_RECT和GC_INIT_WITH_MASK。 然后,使用GC_BGD自动初始化ROI之外的所有像素。 GC_EVAL 2 表示算法应该恢复 GC_EVAL_FREEZE_

    2024年04月09日
    浏览(14)
  • 图像分割简单介绍,并给出opencv图像分割的示例代码

    图像分割简单介绍,并给出opencv图像分割的示例代码

    图像分割是计算机视觉中的一项重要任务,其目标是将图像中的对象与背景进行分离,或将图像分割成不同的区域。本教程将介绍图像分割的基本概念和方法,以及如何在实践中应用它们。 什么是图像分割? 图像分割方法 实践:使用Python和OpenCV进行图像分割 总结及拓展阅读

    2024年02月09日
    浏览(9)
  • 【OpenCV】第十一章: 图像金字塔

    【OpenCV】第十一章: 图像金字塔

    第十一章: 图像金字塔 一、什么是图像金字塔¶ 同一张图片不同分辨率的子图的集合。 图像金字塔底部是待处理的高分辨率图像,也就是原始图像,顶部是低分辨率的近似图像。一般情况下,都是每向上移动一级,图像的宽和高都降低为原来的1/2 。 二、为什么要生成图像金

    2024年02月03日
    浏览(11)
  • OpenCV图像处理-图像分割-MeanShift

    OpenCV图像处理-图像分割-MeanShift

    MeanShift严格说来并不是用来对图像进行分割的,而是在色彩层面的平滑滤波。它会中和色彩分布相近的颜色,平滑色彩细节,侵蚀掉面积较小的的颜色区域,它以图像上任意一点P为圆心,半径为sp,色彩幅值为sr进行不断地迭代。 语法:pyrMeanShiftFiltering(img, double sp, double sr,

    2024年02月16日
    浏览(16)
  • OpenCV(三)——图像分割

    OpenCV(三)——图像分割

    目录 1.图像分割 2.固定阈值法——直方图双峰法 3.自动阈值法 3.1 自适应阈值法

    2024年02月03日
    浏览(7)
  • OpenCV(三)——图像分割(三)

    目录 6.区域生长算法 6.1 区域生长概要 6.2 区域生长原理 7.分水岭算法

    2024年02月13日
    浏览(5)
  • 【Opencv】图像分割——区域生长

    【Opencv】图像分割——区域生长

    Python 3.8.8 PyCharm 2021 opencv-python   区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素具有相同或相似性质的像素(根据某种事先确定的生长或相似准则来判定

    2024年02月05日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包