Android OpenCV(二十五): Laplacian 算子

Laplacian 算子

Laplacian算子具有各方向同性的特点,能够对任意方向的边缘进行提取,具有无方向性的优点,因此使用Laplacian算子提取边缘不需要分别检测X方向的边缘和Y方向的边缘,只需要一次边缘检测即可。Laplacian算子是一种二阶导数算子,对噪声比较敏感,因此常需要配合高斯滤波一起使用。

如果邻域系统是4邻域,Laplacian 算子的模板为:
[010141010] \begin{bmatrix} 0&1&0\\1&-4&1\\0&1&0 \end{bmatrix} \quad

如果邻域系统是8邻域,Laplacian 算子的模板为:
[111181111] \begin{bmatrix} 1 & 1 & 1\\ %第一行元素 1 & -8 & 1\\ %第二行元素 1 & 1 & 1 \end{bmatrix} \quad

API

public static void Laplacian(Mat src, Mat dst, int ddepth, int ksize, double scale, double delta, int borderType)
  • 参数一:src,输入图像。
  • 参数二:dst,输出图像,与输入图像具有相同的尺寸和通道数。
  • 参数三:ddepth,输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围。当赋值为-1时,输出图像的数据类型自动选择。
  • 参数四:ksize,滤波器的大小,必须为正奇数。
  • 参数五:scale,对导数计算结果进行缩放的缩放因子,默认系数为1,不进行缩放
  • 参数六:delta,偏值,在计算结果中加上偏值。
  • 参数七:borderType,像素外推法选择标志。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

函数的前两个参数分别为输入图像和输出图像,第三个参数为输出图像的数据类型,这里需要注意由于提取边缘信息时有可能会出现负数,因此不要使用CV_8U数据类型的输出图像,否则会使得图像边缘提取不准确。函数第四个参数是滤波器尺寸的大小,必须是正奇数,当该参数的值大于1时,该函数通过Sobel算子计算出图像X方向和Y方向的二阶导数,将两个方向的导数求和得到Laplacian算子。

操作

/**
 * Laplacian算子-边缘检测
 *
 * @author yidong
 * @date 2020-05-18
 */
class LaplacianEdgeDetectionActivity : AppCompatActivity() {


    private lateinit var mBinding: ActivityEdgeDetectionBinding
    private lateinit var mRgb: Mat

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_edge_detection)
        val bgr = Utils.loadResource(this, R.drawable.lena)
        mRgb = Mat()
        Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
        showMat(mBinding.ivLena, mRgb)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_laplacian, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.without_blur_edge_detection -> {
                edgeDetection()
            }
            R.id.with_blur_edge_detection -> {
                edgeDetectionAfterBlur()
            }
        }
        return true
    }

    private fun showMat(view: ImageView, source: Mat) {
        val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)
        bitmap.density = 360
        Utils.matToBitmap(source, bitmap)
        view.setImageBitmap(bitmap)
    }

    private fun edgeDetection() {
        title = "Laplacian边缘检测"
        val result = Mat()
        Imgproc.Laplacian(mRgb, result, CvType.CV_16S, 3, 1.0, 0.0)
        Core.convertScaleAbs(result, result)
        showMat(mBinding.ivResult, result)
    }

    private fun edgeDetectionAfterBlur() {
        title = "高斯滤波后Laplacian边缘检测"
        val resultG = Mat()
        val result = Mat()
        Imgproc.GaussianBlur(mRgb, resultG, Size(3.0, 3.0), 5.0, 0.0)
        Imgproc.Laplacian(resultG, result, CvType.CV_16S, 3, 1.0, 0.0)
        Core.convertScaleAbs(result, result)
        showMat(mBinding.ivResult, result)
    }
}

效果

直接Laplacian边缘检测
高斯滤波后Laplacian边缘检测

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

扫码关注,持续更新

回复【计算机视觉】获取计算机视觉相关必备学习资料
回复【Android】获取Android,Kotlin必备学习资料

onlyloveyd CSDN认证博客专家 Android Kotlin OpenCV
个人公众号【Android or OpenCV】,热爱Android、Kotlin、Flutter和OpenCV。毕业于华中科技大学计算机专业,曾就职于华为武汉研究所。目前在三线小城市生活,专注技术与研发。
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值