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

纯粹阅读,请移步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);
时间: 2024-11-05 15:58:26

OpenCV使用Canny边缘检测器实现图像边缘检测的相关文章

图像边缘检测--OpenCV之cvCanny函数

图像边缘检测--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 ); image单通道输入图像.edges单通道存储边缘的输出图像threshold1第一个阈值threshold2第二个阈值aperture_sizeSobel 算子内核大小 (见 cvSobel). 函数 cvCa

OpenCV使用Sobel滤波器实现图像边缘检测

纯粹阅读,请移步OpenCV使用Sobel滤波器实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo Sobel滤波器也叫Sobel算子,与Canny边缘检测一样,需要计算像素的灰度梯度,只不过是换用另一种方式. 使用Sobel算子计算边缘的步骤 将图像转为灰度图像 // 原图置灰 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY); 计算水平方向灰度梯度的绝对值 Imgproc.Sobel(grayMat, gra

OpenCV高斯差分技术实现图像边缘检测

纯粹阅读,请移步OpenCV高斯差分技术实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo 边缘是图像中像素亮度变化明显的点. 高斯差分算法步骤 将图像转为灰度图像 // 原图置灰 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY); 用两个不同的模糊半径对灰度图像执行高斯模糊(取得两幅高斯模糊图像) // 以两个不同的模糊半径对图像做模糊处理 Imgproc.GaussianBlur(grayMat, blur1

OpenCV学习 3:平滑过度与边缘检测

原创文章,欢迎转载,转载请注明出处  用来记录学习的过程,这个是简单的相关函数的熟悉,内部机制和选择何种选择函数参数才能达到自己的要求还不太清楚,先学者吧..后面会慢慢清楚的.     和前面相比,主要用了三个新的函数cvCreateImage,cvSmooth,cvCanny.      cvCreateImage用来创建分配图像空间,创建两个,分别保存平滑处理后的图片,然后将平滑处理后的图片(相当于滤波了)进行边缘检测..代码很简单,opencv很强大,简单的几个函数就完成了如此牛逼的东西.

OpenCV3入门(八)图像边缘检测

1.边缘检测基础 图像的边缘是图像的基本特征,边缘点是灰度阶跃变化的像素点,即灰度值的导数较大或极大的地方,边缘检测是图像识别的第一步.用图像的一阶微分和二阶微分来增强图像的灰度跳变,而边缘也就是灰度变化的地方.因此,这些传统的一阶微分算子如Robert.Sobel.prewitt等,以及二阶微分算子Laplacian等等本质上都是可以用于检测边缘的.这些算子都可以称为边缘检测算子. 边缘检测可以大幅度的减少数据量,剔除那些不相关的信息,保留图像重要的结构属性,一般的边缘检测的步骤有: 1)滤波

基于matlab的经典图像边缘检测算法

图像边缘检测算法 (1)Robert算子边缘检测 (2)Sobel算子边缘检测 (3)Prewitt算子边缘检测 (4)LOG算子边缘检测 (5)Canny边缘检测 Matlab的实现. 其实还只是掉包侠,一点算法没有写 争取有空用openCV写一遍 I=imread('1.jpg'); I0=rgb2gray(I); subplot(231); imshow(I); BW1=edge(I0,'Roberts',0.16); subplot(232); imshow(BW1); title('R

图像边缘检测——Sobel算子

边缘是图像最基本的特征,其在计算机视觉.图像分析等应用中起着重要的作用,这是因为图像的边缘包含了用于识别的有用信息,是图像分析和模式识别的主要特征提取手段. 1.何为“图像边缘”? 在图像中,“边缘”指的是临界的意思.一幅图像的“临界”表示为图像上亮度显著变化的地方,边缘指的是一个区域的结束,也是另一个区域的开始.“边缘点”指的是图像中具有坐标[x,y],且处在强度显著变化的位置上的点. 2.如何表示边缘检测? 在数学上,用导数来表示改变的快慢.基于此,有许多方法用于边缘检测,他们绝大部分可以划

python库skimage 应用canny边缘探测算法

Canny算法 请参考:Canny算法python手动实现 请参考:Canny边缘检测算法原理及opencv实现 skimage库中函数 skimage.feature.canny(image, sigma=1.0, low_threshold=None, high_threshold=None, mask=None, use_quantiles=False) sigma:高斯滤波器的标准差 low_threshold:Canny算法最后一步中,小于该阈值的像素直接置为0 high_thresh

python计算机视觉2:图像边缘检测

我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢 如果需要检测到图像里面的边缘,首先我们需要知道边缘处具有什么特征. 对于一幅灰度图像来说,边缘两边的灰度值肯定不相同,这样我们才能分辨出哪里是边缘,哪里不是. 因此,如果我们需要检测一个灰度图像的边缘,我们需要找出哪里的灰度变化最大.显然,灰度变化越大,对比度越强,边缘就越明显. 那么问题来了,我们怎么知道哪里灰度变化大,哪里灰度变化小呢? 导数,梯度,边缘信息 在数学中,与变化率有关的就是导数. 如果灰度图像的像素是连续的(实际不是),