Android OpenCV(二十四):Scharr算子

Scharr算子

Scharr算子是对Sobel算子差异性的增强,因此两者之间的在检测图像边缘的原理和使用方式上相同。Scharr算子的边缘检测滤波的尺寸为3×3,因此也有称其为Scharr滤波器。可以通过将滤波器中的权重系数放大来增大像素值间的差异,弥补Sobel算子对图像中较弱的边缘提取效果较差的缺点。

Sobel与Scharr对比

API

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

函数第四个和五个参数是提取X方向边缘还是Y方向边缘的标志,该函数要求这两个参数只能有一个参数为1,并且不能同时为0,否则函数将无法提取图像边缘,该函数默认的滤波器尺寸为3×3,并且无法修改因此相比Sobel算子少一个参数

操作

/**
 * Scharr算子-边缘检测
 *
 * @author yidong
 * @date 2020-05-17
 */
class ScharrEdgeDetectionActivity : 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_scharr, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.scharr_edge_detection_x -> {
                edgeDetectionX()
            }
            R.id.scharr_edge_detection_y -> {
                edgeDetectionY()
            }
            R.id.scharr_edge_detection_x_y -> {
                edgeDetectionXAndY()
            }
        }
        return true
    }

    private fun edgeDetectionX() {
        title = "X轴方向边缘检测"
        val resultX = Mat()
        Imgproc.Scharr(mRgb, resultX, CvType.CV_16S, 1, 0)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
    }


    private fun edgeDetectionY() {
        title = "Y轴方向边缘检测"
        val resultY = Mat()
        Imgproc.Scharr(mRgb, resultY, CvType.CV_16S, 0, 1)
        Core.convertScaleAbs(resultY, resultY)
        showMat(mBinding.ivResult, resultY)
    }

    private fun edgeDetectionXAndY() {
        title = "X和Y轴方向边缘检测"
        val resultX = Mat()
        Imgproc.Scharr(mRgb, resultX, CvType.CV_16S, 1, 0)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
        val resultY = Mat()
        Imgproc.Scharr(mRgb, resultY, CvType.CV_16S, 0, 1)
        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()
    }
}

效果

X轴方向
Y轴方向
XY轴合并

源码

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币套餐、付费专栏及课程。

余额充值