荐 Android OpenCV(三十一):图像形态学
简介
形态学(morphology
)一词通常表示生物学的一个分支,它是研究动植物的形态和结构的学科。而我们图像处理中指的形态学,往往表示的是数学形态学。数学形态学(Mathematical morphology
) 的语言是集合论
。同样,形态学为大量的图像处理问题提供了一种一致的有力方法。数字形态学中的集合表示图像中的不同对象。例如,在二值图像中,所有的黑色像素的集合是图像完整的形态学描述。形态学的基本操作有图像腐蚀
、图像膨胀
、开操作
、闭操作
、击中不击中
等。主要应用于边界提取
、区域填充
、连通分量的提取
、凸壳
、细化
、粗化
等方面。
定义
开操作
使用结构元素B对A进行开操作。其实就是B对A腐蚀以后,在用B对腐蚀结果进行膨胀。
闭操作
使用结构元素B对A进行闭操作。其实就是B对A膨胀以后,在用B对膨胀结果进行腐蚀。
形态学梯度
形态学梯度能够描述目标的边界,根据图像腐蚀和膨胀与原图之间的关系计算得到,形态学梯度可以分为基本梯度、内部梯度和外部梯度。基本梯度是原图像膨胀后图像和腐蚀后图像间的差值图像,内部梯度图像是原图像和腐蚀后图像间的差值图像,外部梯度是膨胀后图像和原图像间的差值图像
。
顶帽
图像顶帽运算是原图像与开运算结果之间的差值
,往往用来分离比邻近点亮一些的斑块,因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域。
黑帽
图像黑帽运算是与图像顶帽运算相对应的形态学操作,与顶帽运算相反,黑帽运算是原图像与闭运算结果之间的差值
,往往用来分离比邻近点暗一些的斑块。
击中不击中
击中击不中变换是比图像腐蚀要求更加苛刻的一种形态学操作,图像腐蚀只需要图像能够将结构元素中所有非0元素包含即可,但是击中击不中变换要求原图像中需要存在与结构元素一模一样的结构,即结构元素中非0元素也需要同时被考虑。
API
public static void morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations, int borderType, Scalar borderValue)
-
参数一:src,输入的待形态学操作图像,图像的通道数可以是任意的,但是图像的数据类型必须是
CV_8U
,CV_16U
,CV_16S
,CV_32F
或CV_64F
-
参数二:dst,形态学操作后的输出图像,与输入图像src具有相同的尺寸和数据类型
-
参数三:op,形态学操作类型的标志
标志位 值 作用 MORPH_ERODE 0 图像腐蚀 MORPH_DILATE 1 图形膨胀 MORPH_OPEN 2 开操作 MORPH_CLOSE 3 闭操作 MORPH_GRADIENT 4 形态学梯度 MORPH_TOPHAT 5 顶帽操作 MORPH_BLACKHAT 6 黑帽操作 MORPH_HITMISS 7 击中击不中运算 -
参数四:kernel,用于形态学操作的结构元素,可以自己定义,也可以用
getStructuringElement()
函数生成 -
参数五:anchor,中心点在结构元素中的位置,默认参数为结构元素的几何中心点
-
参数六:iterations,操作次数,默认值为1
-
参数七:borderType,像素外推法选择标志
-
参数八:borderValue,使用边界不变外推法时的边界值
操作
/**
* 形态学
* author: yidong
* 2020/7/5
*/
class MorphologyExActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityMorphologyExBinding
private lateinit var mBinary: Mat
private var mFlag = Imgproc.MORPH_OPEN
set(value) {
field = value
doMorphology(value, mSize.toDouble())
}
private var mSize = 3
set(value) {
field = value
doMorphology(mFlag, value.toDouble())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_morphology_ex)
mBinding.seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
mSize = progress
mBinding.tvSize.text = progress.toString()
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
mBinary = Mat()
val bgr = Utils.loadResource(this, R.drawable.number)
val gray = Mat()
Imgproc.cvtColor(bgr, gray, Imgproc.COLOR_BGR2GRAY)
Imgproc.threshold(gray, mBinary, 125.0, 255.0, Imgproc.THRESH_BINARY_INV)
mBinding.ivLena.showMat(mBinary)
bgr.release()
gray.release()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_morphology_ex, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
title = item.title
mFlag = when (item.itemId) {
R.id.morphology_close -> {
Imgproc.MORPH_CLOSE
}
R.id.morphology_gradient -> {
Imgproc.MORPH_GRADIENT
}
R.id.morphology_top_hat -> {
Imgproc.MORPH_TOPHAT
}
R.id.morphology_black_hat -> {
Imgproc.MORPH_BLACKHAT
}
R.id.morphology_hit_miss -> {
Imgproc.MORPH_HITMISS
}
else -> Imgproc.MORPH_OPEN
}
return true
}
private fun doMorphology(flag: Int, width: Double) {
val kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_RECT, Size(width, width))
val dst = Mat()
Imgproc.morphologyEx(mBinary, dst, flag, kernel)
mBinding.ivResult.showMat(dst)
dst.release()
}
}
效果
源码
https://github.com/onlyloveyd/LearningAndroidOpenCV
扫码关注,持续更新
回复【计算机视觉】【Android】【Flutter】【数字图像处理】获取对应学习资料。
留言可帮觅学习资料。
本文地址:https://blog.csdn.net/poorkick/article/details/107144251
下一篇: 三大运营商物联卡哪家网络稳定
推荐阅读
-
荐 Python数字图像处理——OpenCV实例解析
-
荐 图像轮廓(二)【OpenCV&Python】
-
荐 opencv进阶学习笔记3:像素运算和图像亮度对比度调节
-
荐 opencv新手入门----图像的基本操作(一)
-
荐 opencv进阶学习笔记2:numpy操作图像,色彩空间,查找指定颜色范围,通道分离与合并
-
OpenCV 图像的形态学操作----膨胀腐蚀
-
荐 Machine Learning——CV系列(一)——Python+OpenCV核心操作(2)——图像滤波
-
荐 opencv学习笔记11:图像滤波(均值,方框,高斯,中值)
-
android bitmap转成opencv的mat(图像扫描)
-
荐 Python数字图像处理——OpenCV实例解析