sobel边缘检测算法_Android OpenCV(二十三):Sobel算子边缘检测

本文介绍了Sobel算子在计算机视觉中的应用,用于边缘检测。通过与图像进行3x3矩阵卷积,计算图像的梯度大小和方向。在Android环境中使用OpenCV库,详细阐述了API参数设置和操作过程,展示了使用Sobel算子进行边缘检测的效果和源代码。
摘要由CSDN通过智能技术生成

91371ece80f06980237e8767dedaa017.png

Sobel算子

索贝尔算子是计算机视觉领域的一种重要处理方法。
主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。
索贝尔算子是把图像中每个像素的上下左右四领域的灰度值加权差,在边缘处达到极值从而检测边缘。在技术上,它是一离散性差分算子,用来运算图像亮度函数的梯度之近似值。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。索贝尔算子不但产生较好的检测效果,而且对噪声具有平滑抑制作用,但是得到的边缘较粗,且可能出现伪边缘。
该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

2859f38a15e65a8f3b235acf745d3a2d.png

图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。

2ec3ef7f02c5079c65adaabda9ea2db4.png

然后可用以下公式计算梯度方向。

2c49df6a165196fe63e16d4b05dffcc7.png

在以上例子中,如果以上的角度θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗 【引用:百度百科】

API

public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
  • 参数一:src,输入图像。
  • 参数二:dst,输出图像,与输入图像具有相同的尺寸和通道数。
  • 参数三:ddepth,输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围。当赋值为-1时,输出图像的数据类型自动选择。
  • 参数四:dx,X方向的差分阶数。
  • 参数五:dy,Y方向的差分阶数
  • 参数六:ksize,Sobel边缘算子的尺寸,必须是1、3、5或者7
  • 参数七:scale,对导数计算结果进行缩放的缩放因子,默认系数为1,不进行缩放
  • 参数八:delta,偏值,在计算结果中加上偏值。
  • 参数九:borderType,像素外推法选择标志。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
函数中第三个、第四个和第五个参数是控制图像边缘检测效果的关键参数,这三者存在的关系是任意一个方向的差分阶数都需要小于滤波器的尺寸,特殊情况是当ksize=1时,任意一个方向的阶数需要小于3。一般情况中,差分阶数的最大值为1时,滤波器尺寸选3;差分阶数的最大值为2时,滤波器尺寸选5;差分阶数最大值为3时,滤波器尺寸选7。当滤波器尺寸ksize=1时,程序中使用的滤波器尺寸不再是正方形,而是3×1或者1×3。最后三个参数为图像放缩因子、偏移量和图像外推填充方法的标志,多数情况下并不需要设置,只需要采用默认参数即可。

操作

/**
 * Sobel算子-边缘检测
 *
 * @author yidong
 * @date 2020-01-07
 */
class SobelEdgeDetectionActivity : 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)
    }
​
    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)
    }
​
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_sobel, menu)
        return true
    }
​
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.sobel_edge_detection_x -> {
                edgeDetectionX()
            }
            R.id.sobel_edge_detection_y -> {
                edgeDetectionY()
            }
            R.id.sobel_edge_detection_x_y -> {
                edgeDetectionXAndY()
            }
        }
        return true
    }
​
    private fun edgeDetectionX() {
        title = "X轴方向边缘检测"
        val resultX = Mat()
        Imgproc.Sobel(mRgb, resultX, CvType.CV_16S, 2, 0, 1)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
    }
​
​
    private fun edgeDetectionY() {
        title = "Y轴方向边缘检测"
        val resultY = Mat()
        Imgproc.Sobel(mRgb, resultY, CvType.CV_16S, 0, 1, 3)
        Core.convertScaleAbs(resultY, resultY)
        showMat(mBinding.ivResult, resultY)
    }
​
    private fun edgeDetectionXAndY() {
        title = "X和Y轴方向边缘检测"
        val resultX = Mat()
        Imgproc.Sobel(mRgb, resultX, CvType.CV_16S, 2, 0, 1)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
        val resultY = Mat()
        Imgproc.Sobel(mRgb, resultY, CvType.CV_16S, 0, 1, 3)
        Core.convertScaleAbs(resultY, resultY)
        showMat(mBinding.ivResult, resultY)
​
        val resultXY = Mat()
        Core.add(resultX, resultY, resultXY)
        showMat(mBinding.ivResult, resultXY)
​
        resultX.release()
        resultY.release()
        resultXY.release()
    }
}

效果

160b95d70534608eb6b040a27acc9349.png

09549a4917331a70c4380716af34bc34.png

94fbbb4ecc9dd5af52054942ca15171c.png

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV​github.com

8c24bd85a55b4f256281549e2e7d7624.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值