Sobel 边缘检测算子「建议收藏」

Sobel 边缘检测算子「建议收藏」转自:http://blog.csdn.net/xiaqunfeng123/article/details/17302003Sobel算子是一个离散微分算子(discretedifferent

大家好,又见面了,我是你们的朋友全栈君。

转自:http://blog.csdn.net/xiaqunfeng123/article/details/17302003

    Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。

    图像边缘,相素值会发生显著的变化了。表示这一改变的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。用更加形象的图像来解释,假设我们有一张一维图形。下图2中灰度值的”跃升”表示边缘的存在,图3中使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在。

Sobel 边缘检测算子「建议收藏」

图1、lena.jpg 

Sobel 边缘检测算子「建议收藏」

 图2、像素一维图形

Sobel 边缘检测算子「建议收藏」

图3、一阶导数

       具体是采用卷积的计算方法实现的。假设被作用的图像为I ,在两个方向上求导:

水平变化求导:将 I 与一个奇数大小的内核 G_{x} 进行卷积。比如,当内核大小为3时, G_{x} 的计算结果为图4a:

垂直变化求导:将 I 与一个奇数大小的内核 G_{y} 进行卷积。比如,当内核大小为3时, G_{y} 的计算结果为图4b:

在图像的每一点,结合以上两个结果求出近似 梯度 ,如图4c:

Sobel 边缘检测算子「建议收藏」

图4a

Sobel 边缘检测算子「建议收藏」

图4b

Sobel 边缘检测算子「建议收藏」

图4c

因为Sobel算子只是求取了导数的近似值,当内核大小为3时,以上Sobel内核可能产生比较明显的误差。为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核,该函数的运算与Sobel函数一样快,但结果却更加精确。

Sobel 边缘检测算子「建议收藏」

两种实现版本:

C 版本:

cvSobel ( const cvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size =3 )

src,  dst 分别是源图像和目标图像,xorder ,yorder – 分别为x,y方向导数运算参数,可取0,1,2  。aperture_size是方形滤波器的宽,是小于7的奇数。

具体见《Learning OpenCV》那本书,P.170页

下面是代码,比较简单:

#include <highgui.h>  
#include <cv.h>  
  
using namespace cv;  
using namespace std;  
  
int main(int argc, char ** argv)  
{  
    IplImage* src, *dstx,*dsty,*dst;  
  
    src = cvLoadImage( "car.png",0 );  
    dst = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, 1 );  
    dstx = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, 1 );  
    dsty = cvCreateImage( cvGetSize( src ), IPL_DEPTH_16S, 1 );  
  
    cvNamedWindow( "src" );  
    cvNamedWindow( "sobel" );  
  
    cvShowImage( "src", src );  
  
    cvSobel( src, dstx, 1, 0, 7 );  //sobel  
    cvSobel( src, dsty, 0, 1, 7 );  
    cvAddWeighted(dstx,0.5,dsty,0.5,0,dst);  
  
    cvShowImage( "sobel", dst );  
  
    cvWaitKey(0);  
    cvReleaseImage( &src );  
    cvReleaseImage( &dst );  
  
    return 0;  
}  

效果图:

Sobel 边缘检测算子「建议收藏」

C++版本:

先来看一下C++下 Sobel 的定义

C++:   void Sobel(  InputArray src ,  OutputArray dst,  int ddepth,  int dx,  int dy,  int ksize=3,   

                                           double scale=1,double delta=0,intborderType=BORDER_DEFAULT )

各参数的意义如下:

src – 输入图像。dst – 输出图像,与输入图像同样大小,拥有同样个数的通道。

ddepth –输出图片深度;下面是输入图像支持深度和输出图像支持深度的关系:

src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F

src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F

src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F

src.depth() = CV_64F, ddepth = -1/CV_64F

当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。

xorder – x方向导数运算参数。yorder – y方向导数运算参数。

ksize – Sobel内核的大小,可以是:1,3,5,7。  注意:只可以是小于7 的奇数

scale – 可选的缩放导数的比例常数。delta – 可选的增量常数被叠加到导数中。borderType – 用于判断图像边界的模式。

下面是程序:

#include "opencv2/imgproc/imgproc.hpp"  
#include "opencv2/highgui/highgui.hpp"  
#include <stdlib.h>  
#include <stdio.h>  
  
using namespace cv;  
using namespace std;  
  
int main( int argc, char** argv )  
{  
    Mat src, src_gray;  
    Mat grad;  
    char* window_name = "求解梯度";  
    int scale = 1;  
    int delta = 0;  
    int ddepth = CV_16S;  
  
    src = imread( "car.png" );  
    if( !src.data )  
    {   
        return -1;   
    }  
    //高斯模糊  
    GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );  
    //转成灰度图  
    cvtColor( src, src_gray,CV_RGB2GRAY );  
  
    namedWindow( window_name, CV_WINDOW_AUTOSIZE );  
  
    Mat grad_x, grad_y;  
    Mat abs_grad_x, abs_grad_y;  
    //x方向梯度计算  
    Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );  
    convertScaleAbs( grad_x, abs_grad_x );  
    //y方向梯度计算  
    Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );  
    convertScaleAbs( grad_y, abs_grad_y );  
    //加权和  
    addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );  
  
    imshow( window_name, grad );  
  
    waitKey();  
    return 0;  
}  

如果要用Scharr滤波器的话,把Sobel那行代码替换掉就好了:

Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );  
Scharr( src_gray, grad_x, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );  

效果图:

Sobel 边缘检测算子「建议收藏」

Sobel 边缘检测算子「建议收藏」

参考资料:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

转载请注明出处:http://blog.csdn.net/xiaqunfeng123

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154508.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网页游戏制作_怎么制作app软件

    网页游戏制作_怎么制作app软件对于网页游戏是怎样制作的,你最起码要先学会html超文本标记语言再谈其他的工具方面我喜欢dreamweaver8.0图像及动画方面我喜欢photoshopcs3flash8.0用这三

    2022年8月3日
  • 在手写数字识别的例子中_关于人脸识别的案例

    在手写数字识别的例子中_关于人脸识别的案例1.概念介绍:图像识别(ImageRecognition)是指利用计算机对图像进行处理、分析和理解,以识别各种不同模式的目标和对像的技术。 图像识别的发展经历了三个阶段:文字识别、数字图像处理与识别、物体识别。机器学习领域一般将此类识别问题转化为分类问题。手写识别是常见的图像识别任务。计算机通过手写体图片来识别出图片中的字,与印刷字体不同的是,不同人的手写体风…

    2022年9月14日
  • 【Latex】Latex插入图片「建议收藏」

    【Latex】Latex插入图片「建议收藏」\begin{figure}[h]%H为当前位置,!htb为忽略美学标准,htbp为浮动图形\centering%图片居中\includegraphics[width=0.5\textwidth]{figure1.png}%插入图片,[]中设置图片大小,{}中是图片文件名\caption{AistheVOCdataset,BistheVisDronedataset,CistheCOCOdataset,andDistheOUC-UAV-Detdataset}

    2022年5月25日
  • 阵列信号DOA估计系列(三).MVDR/Capon波束形成(附代码)

    阵列信号DOA估计系列(三).MVDR/Capon波束形成(附代码)本文主要介绍Capn波束形成算法,又名最小方差无失真相应(MinimumVarianceDistortionlessResponse,MVDR),并将其方法应用于DOA估计。

    2022年6月26日
  • python机器学习库sklearn——Lasso回归(L1正则化)

    python机器学习库sklearn——Lasso回归(L1正则化)全栈工程师开发手册(作者:栾鹏)python数据挖掘系列教程TheLasso是估计稀疏系数的线性模型。它在一些情况下是有用的,因为它倾向于使用具有较少参数值的情况,有效地减少给定解决方案所依赖变量的数量。因此,Lasso及其变体是压缩感知领域的基础。在一定条件下,它可以恢复一组非零权重的精确集。在数学公式表达上,它由一个带有ℓ1\ell_1先验的正则项的线性模型组成。

    2022年6月14日
  • 伽马校正_预估校正算法

    伽马校正_预估校正算法自动伽马校正(AutoGammaCorrection)算法目录文章目录自动伽马校正(AutoGammaCorrection)算法目录理论代码实现参考资料理论在对图像进行处理过程中,查找到一篇对图像进行自动gamma校正的论文,论文名称及链接见参考文献1.文章的核心描述如下:Averageofbrightnessissimpleelementthatcanbecomputedintheleastamountoftime.Basicapproachin

    2022年9月1日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号