OpenCV使用Canny边缘检测器实现图像边缘检测

简介: 纯粹阅读,请移步OpenCV使用Canny边缘检测器实现图像边缘检测效果图源码KqwOpenCVFeaturesDemoCanny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化。

纯粹阅读,请移步OpenCV使用Canny边缘检测器实现图像边缘检测

效果图

边缘检测结果

原图

源码

KqwOpenCVFeaturesDemo

Canny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化。

Canny边缘检测器算法基本步骤

  1. 平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声。
  2. 计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直、水平和斜对角。这一步的输出用于在下一步中计算真正的边缘。
  3. 非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则抑制该像素(像素不属于边缘)。这是一种边缘细化技术,用最急剧的变换选出边缘点。
  4. 用滞后阈值化选择边缘:最后一步,检查某一条边缘是否明显到足以作为最终输出,最后去除所有不明显的边缘。

算法比较复杂,但是使用很简单,首先将图像灰度化

// 原图置灰
Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY);

然后调用Imgproc.Canny()方法即可

// Canny边缘检测器检测图像边缘
Imgproc.Canny(grayMat, cannyEdges, 10, 100);
  • 第一个参数表示图像输入
  • 第二个参数表述图像输出
  • 第三个参数表示低阈值
  • 第四个参数表示高阈值

在Canny边缘检测算法中,将图像中的点归为三类:

  • 被抑制点

    灰度梯度值 < 低阈值

  • 弱边缘点

    低阈值 <= 灰度梯度值 <= 高阈值

  • 强边缘点

    高阈值 < 灰度梯度值

封装

/**
 * Canny边缘检测算法
 *
 * @param bitmap 要检测的图片
 */
public void canny(Bitmap bitmap) {
    if (null != mSubscriber)
        Observable
                .just(bitmap)
                .map(new Func1<Bitmap, Bitmap>() {

                    @Override
                    public Bitmap call(Bitmap bitmap) {

                        Mat grayMat = new Mat();
                        Mat cannyEdges = new Mat();

                        // Bitmap转为Mat
                        Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
                        Utils.bitmapToMat(bitmap, src);

                        // 原图置灰
                        Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY);
                        // Canny边缘检测器检测图像边缘
                        Imgproc.Canny(grayMat, cannyEdges, 10, 100);

                        // Mat转Bitmap
                        Bitmap processedImage = Bitmap.createBitmap(cannyEdges.cols(), cannyEdges.rows(), Bitmap.Config.ARGB_8888);
                        Utils.matToBitmap(cannyEdges, processedImage);

                        return processedImage;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(mSubscriber);
}

使用

// 图片特征提取的工具类
mFeaturesUtil = new FeaturesUtil(new Subscriber<Bitmap>() {
    @Override
    public void onCompleted() {
        // 图片处理完成
        dismissProgressDialog();
    }

    @Override
    public void onError(Throwable e) {
        // 图片处理异常
        dismissProgressDialog();
    }

    @Override
    public void onNext(Bitmap bitmap) {
        // 获取到处理后的图片
        mImageView.setImageBitmap(bitmap);
    }
});

// Canny边缘检测器检测图像边缘
mFeaturesUtil.canny(mSelectImage);
相关文章
|
8天前
|
存储 编解码 API
【图像文本化】Base64编解码OpenCV4中 Mat 对象
【图像文本化】Base64编解码OpenCV4中 Mat 对象
10 0
|
8天前
|
机器学习/深度学习 编解码 计算机视觉
【一秒梵高】基于OpenCV4实现图像九种风格迁移
【一秒梵高】基于OpenCV4实现图像九种风格迁移
12 0
|
8天前
|
计算机视觉
OpenCV中图像算术操作与逻辑操作
OpenCV中图像算术操作与逻辑操作
9 1
|
8天前
|
存储 计算机视觉
OpenCV3.1中读写图像与读写像素
OpenCV3.1中读写图像与读写像素
9 0
|
9天前
|
计算机视觉
OpenCV图像二值化
OpenCV图像二值化
|
9天前
|
存储 Cloud Native Linux
OpenCV图像翻转和旋转
OpenCV图像翻转和旋转
|
9天前
|
存储 Cloud Native Linux
OpenCV鼠标操作(画红色方框截取图像)
OpenCV鼠标操作(画红色方框截取图像)
|
9天前
|
计算机视觉
OpencV图像几何形状绘制
OpencV图像几何形状绘制
|
9天前
|
计算机视觉
OpenCV图像像素值统计
OpenCV图像像素值统计
|
9天前
|
计算机视觉
OpenCV图像色彩空间转换
OpenCV图像色彩空间转换