Android OpenCV(四十一),程序员必看

Android OpenCV(四十一),程序员必看,第1张

Android OpenCV(四十一),程序员必看
  • 参数五: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

*** 作


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()
}
doFloodFill()
}

private fun doFloodFill() {
val tmp = mRgb.clone()
val mask

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

浏览器打开:qq.cn.hn/FTe 免费领取

ers = Mat(mRgb.rows() + 2, mRgb.cols() + 2, CV_8UC1, Scalar.all(0.0))
Imgproc.floodFill(
tmp,
maskers,
Point(7.0, 7.0),
Scalar(65.0, 105.0, 225.0),
Rect(),
Scalar.all(loDiff),
Scalar.all(upDiff),
mConnectionType or mFloodFillFlag or mScalarNumber
)
if (mFloodFillFlag and Imgproc.FLOODFILL_MASK_onLY == Imgproc.FLOODFILL_MASK_ONLY) {
mBinding.ivResult.showMat(maskers)
} else {
mBinding.ivResult.showMat(tmp)
}

tmp.release()
maskers.release()
}

private fun showMenuDialog() {
if (!this::mMenuDialog.isInitialized) {
mMenuDialog = BottomSheetDialog(this)
mMenuDialogBinding = LayoutFloodFillMenuBinding.inflate(layoutInflater)
mMenuDialog.setContentView(mMenuDialogBinding.root)
mMenuDialog.setonDismissListener {
mConnectionType =
if (mMenuDialogBinding.rgFirst.checkedRadioButtonId == R.id.rb_8) {
8
} else {
4
}
mFloodFillFlag = if (mMenuDialogBinding.cbFixed.isChecked) {
mFloodFillFlag or Imgproc.FLOODFILL_FIXED_RANGE
} else {
mFloodFillFlag and Imgproc.FLOODFILL_FIXED_RANGE.inv()
}
mFloodFillFlag = if (mMenuDialogBinding.cbMaskOnly.isChecked) {
mFloodFillFlag or Imgproc.FLOODFILL_MASK_ONLY

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5437417.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存