精华内容
下载资源
问答
  • prewitt算子边缘检测

    2018-07-26 14:26:34
    简单的prewitt算子边缘检测,文档内含两幅试验图片(效果不太好,可以换图)
  • Prewitt算子边缘检测 Prewitt算子边缘检测 1. 前言 Prewxtt算子的边缘检测描述 代码实现 1. 前言 在图像中,灰度或结构等信息的突变处称为边缘。边缘可以看作一个区域的结束,另一个区域的开始。利用边缘的...

    Prewitt算子边缘检测

    1. 前言

    在图像中,灰度或结构等信息的突变处称为边缘。边缘可以看作一个区域的结束,另一个区域的开始。利用边缘的特征,可以对图像进行分割。根据定义可以知道,利用各种算法检测到的边缘,并不代表目标的实际边缘。由于图像是二维的,而目标实物是三维的,从三维到二维的投影,已经造成了信息的丢失,再加上成像过程受光照、噪声的影响,使得有边缘的地方不一定被检测出来,而检测出来的边缘也不一定代表实际边缘。
    图像的边缘有方向和幅度两个属性,沿边缘方向像素变化平缓,垂直于边缘方向像素变化剧烈。因此,利用图像边缘的变化特性,通过微分算子可以将边缘检查出来,通常用一阶或二阶导数来检测边缘。一阶导数以最大值对应边缘位置,二阶导数以过零点为边缘位置。

    Prewxtt算子的边缘检测描述

    Prewxtt算子属于一阶微分算子,Prewitt利用周围邻域8个点的灰度值来估计中心的梯

    展开全文
  • Prewitt算子边缘检测

    2020-12-10 15:02:00
    } void edge_Prewitt(cv::Mat& src, cv::Mat& dst1, cv::Mat& dst2, cv::Mat& dst3, cv::Mat& dst4, cv::Mat& dst, int ddepth, double delta = 0, int borderType = cv::BORDER_DEFAULT) { //获取Prewitt算子 cv::...
    #include <iostream>
    #include <opencv2/core.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    
    void getPrewitt_oper(cv::Mat& getPrewitt_horizontal, cv::Mat& getPrewitt_vertical, cv::Mat& getPrewitt_Diagonal1, cv::Mat& getPrewitt_Diagonal2)
    {
    	//水平方向
    	getPrewitt_horizontal = (cv::Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
    	//垂直方向
    	getPrewitt_vertical = (cv::Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
    	//对角135°
    	getPrewitt_Diagonal1 = (cv::Mat_<float>(3, 3) << 0, 1, 1, -1, 0, 1, -1, -1, 0);
    	//对角45°
    	getPrewitt_Diagonal2 = (cv::Mat_<float>(3, 3) << -1, -1, 0, -1, 0, 1, 0, 1, 1);
    
    	//逆时针反转180°得到卷积核
    	cv::flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);
    	cv::flip(getPrewitt_vertical, getPrewitt_vertical, -1);
    	cv::flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);
    	cv::flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1);
    }
    
    void edge_Prewitt(cv::Mat& src, cv::Mat& dst1, cv::Mat& dst2, cv::Mat& dst3, cv::Mat& dst4, cv::Mat& dst, int ddepth, double delta = 0, int borderType = cv::BORDER_DEFAULT)
    {
    	//获取Prewitt算子
    	cv::Mat getPrewitt_horizontal;
    	cv::Mat getPrewitt_vertical;
    	cv::Mat getPrewitt_Diagonal1;
    	cv::Mat getPrewitt_Diagonal2;
    	getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);
    
    	//卷积得到水平方向边缘
    	cv::filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到4垂直方向边缘
    	cv::filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到45°方向边缘
    	cv::filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到135°方向边缘
    	cv::filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);
    
    	//边缘强度(近似)
    	cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst2, dst2);
    
    	cv::convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst4, dst4);
    	dst = dst1 + dst2;
    
    }
    
    
    int main()
    {
    	cv::Mat src = cv::imread("avatar.jpg");
    	if (src.empty())
    	{
    		return -1;
    	}
    	if (src.channels() > 1) cv::cvtColor(src, src, CV_RGB2GRAY);
    	cv::Mat dst, dst1, dst2, dst3, dst4;
    
    	//注意:要采用CV_32F,因为有些地方卷积后为负数,若用8位无符号,则会导致这些地方为0
    	edge_Prewitt(src, dst1, dst2, dst3, dst4, dst, CV_32F);
    
    	cv::namedWindow("src", CV_WINDOW_NORMAL);
    	imshow("src", src);
    	cv::namedWindow("水平边缘", CV_WINDOW_NORMAL);
    	imshow("水平边缘", dst1);
    	cv::namedWindow("垂直边缘", CV_WINDOW_NORMAL);
    	imshow("垂直边缘", dst2);
    	cv::namedWindow("45°边缘", CV_WINDOW_NORMAL);
    	imshow("45°边缘", dst3);
    
    	cv::Mat dst302 = 255 - dst3;
    	cv::namedWindow("dst302", CV_WINDOW_NORMAL);
    	imshow("dst302", dst302);
    
    	cv::namedWindow("135°边缘", CV_WINDOW_NORMAL);
    	imshow("135°边缘", dst4);
    	cv::namedWindow("边缘强度", CV_WINDOW_NORMAL);
    	imshow("边缘强度", dst);
    	cv::waitKey(0);
    	return 0;
    }

     

    展开全文
  • 自编matlab下的边缘检测算法,以prewitt算子示例
  • Prewitt算子边缘检测原理及实现

    万次阅读 2019-06-10 18:22:36
    Prewitt算子同样也是一种一阶微分算子,利用像素点上下左右邻点灰度差,在边缘处达到极值检测边缘,对噪声具有平滑的作用。 原理 其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板...

    写在前面

    Prewitt算子同样也是一种一阶微分算子,利用像素点上下左右邻点灰度差,在边缘处达到极值检测边缘,对噪声具有平滑的作用。

    原理

    其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。

    相比Roberts算子,Prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,因此噪声较多的图像处理得比较好,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位却不如Roberts算子。

    那么为啥Prewitt算子对噪声有抑制作用呢?请看Prewitt算子的卷积核:

    ââ

                                                             Prewitt_X                                     Prewitt_Y 

    图像与Prewitt_X卷积后可以反映图像的垂直边缘,与Prewitt_Y卷积后可以反映图像的水平边缘。最重要的是,这两个卷积是可分离的:

                                        Prewitt_X =\begin{bmatrix}1 \\ 1 \\ 1 \end{bmatrix} *\begin{bmatrix} -1 & 0 &1 \end{bmatrix}        ,          Prewitt_Y =\begin{bmatrix} 1 & 1 &1 \end{bmatrix}*\begin{bmatrix}1 \\ 0 \\ -1 \end{bmatrix}

    从分离的结果来看, Prewitt_X算子实际上是先对图像进行垂直方向的非归一化的均值平滑,然后进行水平方向的差分; 然而Prewitt_Y算子实际上是先对图像进行水平方向的非归一化的均值平滑,然后进行垂直方向的差分。这就是Prewitt算子能够抑制噪声的原因。

    同理,我们也可以得到对角上的Prewitt算子算子,见代码即可。

     

    代码实现

    #include <iostream>
    #include <opencv2/core.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    
    void getPrewitt_oper(cv::Mat& getPrewitt_horizontal, cv::Mat& getPrewitt_vertical, cv::Mat& getPrewitt_Diagonal1,cv::Mat& getPrewitt_Diagonal2){
    	//水平方向
    	getPrewitt_horizontal = (cv::Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
    	//垂直方向
    	getPrewitt_vertical = (cv::Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
    	//对角135°
    	getPrewitt_Diagonal1 = (cv::Mat_<float>(3, 3) << 0, 1, 1, -1, 0, 1, -1, -1, 0);
    	//对角45°
    	getPrewitt_Diagonal2 = (cv::Mat_<float>(3, 3) << -1, -1, 0, -1, 0, 1, 0, 1, 1);
    
    	//逆时针反转180°得到卷积核
    	cv::flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);
    	cv::flip(getPrewitt_vertical, getPrewitt_vertical, -1);
    	cv::flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);
    	cv::flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1);
    }
    
    void edge_Prewitt(cv::Mat& src, cv::Mat& dst1, cv::Mat& dst2, cv::Mat& dst3, cv::Mat& dst4, cv::Mat& dst, int ddepth, double delta = 0, int borderType = cv::BORDER_DEFAULT){
    	//获取Prewitt算子
    	cv::Mat getPrewitt_horizontal;
    	cv::Mat getPrewitt_vertical;
    	cv::Mat getPrewitt_Diagonal1;
    	cv::Mat getPrewitt_Diagonal2;
    	getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);
    
    	//卷积得到水平方向边缘
    	cv::filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到4垂直方向边缘
    	cv::filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到45°方向边缘
    	cv::filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到135°方向边缘
    	cv::filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);
    
    	//边缘强度(近似)
    	cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst2, dst2);
    
    	cv::convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst4, dst4);
    	dst = dst1 + dst2 ;
    
    }
    
    
    int main(){
    	cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\(embedded_square_noisy_512).tif");
    	if (src.empty()){
    		return -1;
    	}
    	if (src.channels() > 1) cv::cvtColor(src, src, CV_RGB2GRAY);
    	cv::Mat dst, dst1, dst2, dst3, dst4;
    
    	//注意:要采用CV_32F,因为有些地方卷积后为负数,若用8位无符号,则会导致这些地方为0
    	edge_Prewitt(src, dst1, dst2, dst3, dst4, dst, CV_32F);
    
    	cv::namedWindow("src", CV_WINDOW_NORMAL);
    	imshow("src", src);
    	cv::namedWindow("水平边缘", CV_WINDOW_NORMAL);
    	imshow("水平边缘", dst1);
    	cv::namedWindow("垂直边缘", CV_WINDOW_NORMAL);
    	imshow("垂直边缘", dst2);
    	cv::namedWindow("45°边缘", CV_WINDOW_NORMAL);
    	imshow("45°边缘", dst3);
    	cv::namedWindow("135°边缘", CV_WINDOW_NORMAL);
    	imshow("135°边缘", dst4);
    	cv::namedWindow("边缘强度", CV_WINDOW_NORMAL);
    	imshow("边缘强度", dst);
    	cv::waitKey(0);
    	return 0;
    }

    效果

     

    展开全文
  • dsp图像处理Prewitt算子边缘检测

    千次阅读 2013-07-11 19:47:33
    Prewitt算子边缘检测 一、实验背景与意义 图像处理就是对信息加工以满足人的视觉心理或应用需求的方法。图像处理的方法有光学方法和电子学方法。从20世纪60年代起随着电子计算机和计算技术的不断提高和普及,数字...

    ——(完整工程文件到我的资源下载)

    Prewitt 算子边缘检测

    一、实验背景与意义

    图像处理就是对信息加工以满足人的视觉心理或应用需求的方法。图像处理的方法有光学方法和电子学方法。从20世纪60年代起随着电子计算机和计算技术的不断提高和普及,数字图像处理进入了高速发展时期,而数字图像处理就是利用数字计算机或其它的硬件设备对图像信息转换而得到的电信号进行某些数学处理以提高图像的实用性。图像处理在遥感技术、医学领域、安全领域,工业生产中有着广泛的应用。其中在医学应用中的超声、核磁共振和CT等技术,安全领域和模式识别技术,工业中的无损检测技术尤其引人注目。计算机进行图像处理一般有两个目的:(1)生产更适合人观察和识别的图像。(2)希望能由计算机自动识别和理解图像。数字图像的边缘检测是图像分割、目标区域的识别、区域形状提取等图像分析领域的重要基础。图像处理分析的第一步往往就是边缘检测。物体的边缘是以图像的局部特征不连续的形状出现的,也就是指图像局部亮度变化最显著的部分,例如灰度值的突变、颜色的突变、纹理结构的突变等,同时物体的边缘也是不同的区域分界处。图像边缘有方向和幅度两个特性,通常沿边缘的走向灰度变化平缓,垂直于边缘走向的像素灰度变化剧烈。根据灰度变化的特点,图像边缘可分为阶跃型、房顶型和凸缘型。

    边缘检测是图像处理、目标识别和计算机视觉等领域中最经典的研内容之一,已有较长的研究历史,边缘检测是所有基于边界分割方法的第一步。经典的边缘检测方法是对原始图像按像素的某邻域构造边缘检测算子。应用边缘检测的算法是基于边界的分割方法,常用的边缘检测算子有RobertsSobelKirschPrewitt以及Laplace等。其中Prewitt算子通过对图像进行八个方向的边缘检测,将其中方向响应最大的作为边缘幅度图像的边缘,且对噪声具有平滑作用。传统的边缘检测算子的噪声平滑能力和边缘定位能力是矛盾的。为了克服这个不足,正确地得到图像的边缘信息,已经提出了很多方法,其中边缘检测和边缘细化相结合可以有效地调节噪声平滑和边缘定位能力的矛盾。

    二、基于Prewitt算法边缘检测的原理

    Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。

    Prewitt边缘检测算法是一种类似Sobel边缘检测算法的边缘模板算法。Prewitt边缘检测算子并不把重点放在相邻的像素上,它对噪声具有平滑作用。采用3*3邻域可以避免在像素之间内插点上计算梯度。Prewitt算子也是一种梯度幅值,该算子包含两组3*3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,及分别代表经横向及纵向边缘检测的图像,其模板的卷积因子如下:

                        

      该算子包含两组3*3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。具体卷积算法如下:

       经典Prewitt算子认为:凡灰度新值大于或等于阈值的像素点都是边缘点。即选择适当的阈值T,若G(i,j)≥T,则(i,j)为边缘点,G(i,j)为边缘图像。这种判定是欠合理的,会造成边缘点的误判,因为许多噪声点的灰度值也很大,而且对于幅值较小的边缘点,其边缘反而丢失了。Prewitt算子利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。对噪声具有平滑作用,定位精度不够高。

    三、算法编程步骤

    1、为了对图像利用Prewitt算子进行边缘检测,编程主要步骤如下:

       输入:原灰度图像sourceIMG;

       输入:噪声强度range;

    输出:加噪后的高斯噪声图像resultIMG;

    Step 1:获取原图像的高rows与宽度cols;

    Step 2:为输出图像resultIMG申请空间;

    Step 3:for ( i=0; i< cols*(rows-2) - 2; i++)

             取3*3模板对应的原始像素;

             利用Prewitt垂直算子和水平算子计算相应差分并取绝对值输出像素=垂直方向差分+水平方向差分;

    end for     

    Step 4: 输出图像resultIMG,程序结束。

    2、C语言代码如下:

    /* ======================================================================== */

    /*  Copyright 2006 by Wintech Digital System Technology Corp.               */

    /*  All rights reserved. Property of Texas Instruments Incorporated.        */

    /*  Restricted rights to use, duplicate or disclose this code are           */

    /*  granted through contract.                                             */

    /* ======================================================================== */

    /*========  头文件引用===========*/

    #include "stdio.h"

    #include "math.h"

    /*============= 工作变量定义======*/

    unsigned char *pr_n;    //指针定义

    unsigned char *pr_s;    //指针定义

    //说明:定义数据存放变量

    #pragma        DATA_SECTION(IMG,"data"); 

    int  IMG[30000];

    #pragma        DATA_SECTION(Noise_IMG,"data");

    unsigned char  Noise_IMG[30000];

    #pragma        DATA_SECTION(Smooth_IMG,"data");

    unsigned char  Smooth_IMG[30000];

    void  IMG_Smooth();

    void IMG_sobel

    (

        const unsigned char *restrict in,   /* Input image data   */

        unsigned char       *restrict out,  /* Output image data  */

        short cols, short rows              /* Image dimensions   */

    );

    ///

    //使用说明:

    //   1. 本程序可以在Simulator下运动;

    //   2. 程序编译、链接、加载成功后,先

    //      执行File/data/load,将要进行颜色转换的图像数据从RGB_peppers96x128.dat 

    //     (说明:*.dat格式,内部存放了某图像各像素的RGB颜色值)加载入数据存储器存储地址RGB_IMG中

    //   3. 数据加载成功后,再Debug/Go Main, 一步一步运行程序

    ///

    int CoefArray[9]={1,1,1,1,1,1,1,1,1};

    /*================= 主程序 ================*/

    main()

    {   

    long n;

    int imgH,imgW;

        int *ptr;

        imgH=160;  //图像高与宽,因为数据文件中的图像是160X160像素的

        imgW=160; 

    /*=========== 初始化 ==========*/

        //1 把图像数据从IMG中移到Noise_IMG数组中

        ptr=IMG;

        pr_n=Noise_IMG;

        for (n=0;n<imgH*imgW;n++)

           *pr_n++=*ptr++;

        //说明:在此暂停,可看到噪声图像 

    //指针指向数组

    pr_n=Noise_IMG;

    pr_s=Smooth_IMG;

    ptr=IMG;

        //2 调用子程序,进行彩色图像变换成灰度图像

        while (1)

        { 

           

           //IMG_Smooth(pr_n,pr_s,imgW,imgH);

           

           IMG_sobel(pr_n,pr_s,imgW,imgH);

           //说明:上面子程序执行后,在此暂停,可看平滑后的图像 

         }

        //说明:在此暂停,可看变换后的灰度图像 

    }

    /*============== 子程序 =============*/

    void IMG_Smooth

    (   unsigned char   *F,         /* 输入带有噪声的灰度图像      */

        unsigned char   *G,         /* 输出的平滑后的灰度图像      */

        int cols, int rows      /* 图像的宽度与高度            */

    )

    {    //定义局部变量

        unsigned char *ptr, *pp, *newpp;

        int tmpNum,x, y,k,m,temp;

        int tmp[9];

        //图像四周的像素不进衅交扔谠?

        for (x=0; x< cols -1; x++)  //处理第一行的像素

             G[x] = F[x];

          //处理最后一行的像素

          newpp  =  G + (rows-1)* cols;    //指针指向平滑图像

          pp     =  F+ (rows-1)* cols;     //指针指向噪声图像        

          for (x=0; x< cols -1; x++) 

              * newpp++ = * pp++;

          //处理最左边一列的像素

          newpp  =  G;    //指针指向平滑图像

          pp     =  F;     //指针指向噪声图像        

          for (y=0; y< rows -1; y++) 

          {

              *newpp = *pp;  

              newpp+=cols; pp+=cols;  //指针偏移到下一行像素的位置

          }

          //处理最右边一列的像素

          newpp  =  G+cols;    //指针指向平滑图像

          pp     =  F+cols;     //指针指向噪声图像        

          for (y=0; y< rows -1; y++) 

          {

             * newpp = * pp;  

             newpp+=cols; pp+=cols;  //指针偏移到下一行像素的位置

          }

          //采用中值滤波的方式对图像中的每个像素进行平滑

          for (y=1; y< rows -1; y++)

               for (x=1; x<cols -1; x++)

               {

                    newpp   = G + y* cols +x;    //指针指向平滑图像

                    pp      = F + y* cols +x;     //指针指向噪声图像        

                    //累加第一排的3个像素的值

                    ptr      =   pp-cols-1;             

                    tmp[1]  =  (*ptr++)*CoefArray[0];

                    tmp[2]=  (*ptr++)*CoefArray[1];

                    tmp[3]=  (*ptr++)*CoefArray[2];

                    //累加第二排的3个像素的值

                    ptr      = pp-1;             

                    tmp[4]=  (*ptr++)*CoefArray[3];

                    tmp[5]=  (*ptr++)*CoefArray[4];

                    tmp[6]=  (*ptr++)*CoefArray[5];

                    //累加第三排的3个像素的值

                    ptr      = pp+cols-1;             

                    tmp[7]=  (*ptr++)*CoefArray[6];

                    tmp[8]=  (*ptr++)*CoefArray[7];

                    tmp[9]=  (*ptr++)*CoefArray[8];

                   //累加的结果除以9

                    tmpNum /=9;                      

                   //检测数据是否溢出,且将平均值赋给平滑图像

                   if (tmpNum > 255)

                        *newpp=255;

                   else

                         

                        

                {

                   for(k=0;k<7;k++)

                      for(m=k+1;m<8;m++)

                       {

                 if ( tmp[m]>tmp[m+1] )

                      {

                     temp=tmp[m];

                      tmp[m]=tmp[m+1];

                     tmp[m+1]=temp;

                       }

                   }    

                 *newpp=tmp[4];

              

              }

           //取排序好的数组的中值赋给当前像素

          // *newpp=tmp[4];

          // newpp++;                                

           //pp++;                                                   

                                             

    }

                 

                     

    } //程序结束

    void IMG_sobel

    (

        const unsigned char *restrict in,   /* Input image data   */

        unsigned char       *restrict out,  /* Output image data  */

        short cols, short rows              /* Image dimensions   */

    )

    {

        int H, O, V, i;

        int i00, i01, i02;

        int i10,      i12;

        int i20, i21, i22;

        int w = cols;

        /* -------------------------------------------------------------------- */

        /*  Iterate over entire image as a single, continuous raster line.      */

        /* -------------------------------------------------------------------- */

        for (i = 0; i < cols*(rows-2) - 2; i++)

        {

            /* ---------------------------------------------------------------- */

            /*  Read in the required 3x3 region from the input.                 */

            /* ---------------------------------------------------------------- */

            i00=in[i    ]; i01=in[i    +1]; i02=in[i    +2];

            i10=in[i+  w];                  i12=in[i+  w+2];

            i20=in[i+2*w]; i21=in[i+2*w+1]; i22=in[i+2*w+2];

            /* ---------------------------------------------------------------- */

            /*  Apply horizontal and vertical filter masks.  The final filter   */

            /*  output is the sum of the absolute values of these filters.      */

            /* ---------------------------------------------------------------- */

            H = -   i00 - 2*i01 -   i02 +

                +   i20 + 2*i21 +   i22;

            V = -   i00         +   i02

                - 2*i10         + 2*i12

                -   i20         +   i22;

            O = abs(H) + abs(V);

            /* ---------------------------------------------------------------- */

            /*  Clamp to 8-bit range.  The output is always positive due to     */

            /*  the absolute value, so we only need to check for overflow.      */

            /* ---------------------------------------------------------------- */

            if (O > 255) O = 255;

            else O = 0;

            /* ---------------------------------------------------------------- */

            /*  Store it.                                                       */

            /* ---------------------------------------------------------------- */

            out[i + 1] = O;

        }

    }  

    /* ======================================================================== */

    /*             Copyright (c) 2012 LDX Digital System Technology Corp.   */

    /*                         All Rights Reserved.                             */

    /* ======================================================================== */

    四、实验步骤与结果

    1、设置CCS 2.2工作在软件仿真环境

    (1)双击桌面上Setup CCS studio图标,运行CCS Setup,进入CCS设置窗口;

    (2)在出现的窗口中,按下图所示的方法与顺序进行CCS设置;

      

    (3)在弹出的窗口中点击“是”按键保存设置,退出CCS Setup,进入CCS开发环境,此时CCS被设置成Simulator仿真模式。

    2、启动CCS。

    双击桌面上CCS 2 (C6000)图标,运行CCS。

    3、创建工程

    (1)创建新的“BYJC”工程文件

       选择菜单“Project”的“New…”项

    弹出如下对话框:


    输入项目名称BYJC后,点击完成即可。

    3先新建源程序窗口:点击“File/New/Source File”,输入源代码(上一步已给出)

    点击“File/Save”,在弹出的保存对话框中,选择保存目录为“BYJC”,选择保存类型为“C Source Files”,保存源程序为main.c。

    4. 运行程序,观察试验结果。

    按如下方法观看试验结果:(1)编译、链接程序:执行菜单Project/Rebuild All,汇编结果在将汇编信息输出窗口中给出。编译后将在Bebug目录中产生一个ImgSmooth.out文件。

    2)加载程序:执行File/Load Program,选择ImgSmooth.out并打开,即将可执行文件加载到DSP软件仿真器simulator中,此时CCS将自动打开一个反汇编窗口。

    3)将RGB彩色图像的数据从dat文件读入到内存:执行File/data/load,将要进行颜色转换的图像数据从Gray_Lenna160x160.dat (说明:*.dat格式,内部存放了某图像各像素的RGB颜色值)文件中加载入到数据存储器,即在弹出的窗口中输入存储地址IMG与数据的长度,如下图所示。


    4)运行程序:执行Debug/Run。为了便于观看试验前后的结果,可以在程序中设置断点,采用单步执行的方法运行程序。

    5)显示平滑前的噪声图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入RGB彩色图像三个通道数据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。这样,原始的噪声图像如图1所示。




    图1 原始图像

    (6)显示平滑后的图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入灰度图像据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。


    图二为Prewitt算子边缘检测结果


    五、分析与总结

      Prewitt算子:利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。对噪声具有平滑作用,但定位精度不够高。对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位不如Roberts算子。图像的峰值处对应着图像的边缘点,边缘位置和导数(微分)间具有一定对应关系,可通过微分进行边缘检测。无噪声时,可用Roberts算子;Prewitt和Sobel算子同时具有平均,即抑制噪声作用;对阶跃状边缘,Roberts得到的边缘宽度≥1个像素,Prewitt和Sobel算子得到的边缘宽度≥2个像素。


    展开全文
  • 第八节:边缘检测 边缘检测边缘检测指的是灰度值发生急剧变化的位置,边缘检测的目的是制作一个线图,在不会损害理解图像内容的情况下, 有大大减少了图像的数据量,提供了对图像数据的合适概述。 一:...
  • 边缘检测VS2017编译通过,可直接运行 包括 Roberts边缘算子 Sobel边缘检测算子 Prewitt边缘检测算子 Kirsch边缘检测算子 拉普拉斯算子 高斯拉普拉斯算子
  • 2 边缘检测算子分类 3 梯度 3.1 图像梯度 3.2 梯度算子 4 Roberts 算子 4.1 基本原理 4.2 代码示例 5 Prewitt 算子 5.1 基本原理 5.2 代码示例 6 Sobel 算子 6.1 基本原理 6.2 代码示例 7 Laplacian ...
  • OpenCV (11):Canny 算子边缘检测技术」 引言 前文介绍了 Canny 算子边缘检测,本篇继续介绍 Roberts 算子、 Prewitt 算子、 Sobel 算子和 Laplacian 算子等常用边缘检测技术。 Roberts 算子 Roberts 算子,又称...
  • 图像边缘检测Prewitt算子

    千次阅读 2020-05-10 19:45:49
    Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用 3x3 模板对区域内的像素值进行计算,而Robert算子的模板为 2x2,故Prewitt算子边缘检测...
  • 本文分别采用Laplacian算子、Robert算子、Prewitt算子和Sobel算子进行图像锐化边缘处理实验。本文主要讲解灰度线性变换,基础性知识希望对您有所帮助。 1.Roberts算子 2.Prewitt算子 3.Sobel算子 4.Laplacian算子 5....
  • 本资源提供了五种边缘检测算子,包括Sobel 算子、roberts 算子prewitt 算子、log算子、canny算子,用于图像处理中的图像边缘检测
  • Robert算子、sobel算子、Prewitt算子、canny边缘检测算子 之前做的笔记,懒得再敲一遍了,先传上来,方便自己以后加深记忆
  • java 边缘检测 sobel算子和Prewitt算子

    千次阅读 2014-07-27 17:15:16
    Prewitt算子
  • 垂直水平方向 垂直水平方向的Prewitt算子是可分离的卷积核。 45°、135°方向
  • Sobel和 Prewitt算子思想 之所以把这个两个算子拿出来一起说,是因为...Sobel(Prewiit算子亦是如此)边缘检测算子用两个3*3的模板来近似计算图像在某点(i,j)对x和y的偏导数Gx,Gy。而梯度幅值往往有三种表达式:...
  • Matlab图像边缘检测–梯度算子–Roberts、Prewitt、Sobel、LOG、Canny算子边缘检测 I = imread('0.jpg'); I =rgb2gray(I); % edge()函数:边缘检测,门限值采用...% Prewitt算子边缘检测 BW2=edge(I,'prewitt'); %...
  • 边缘检测Prewitt 算子

    千次阅读 2010-12-09 14:32:00
    边缘检测Prewitt 算子 <br />  Prewitt 算子采用以下算子分别计算一阶 x 方向和 y 方向的图像差分: <br />-101-101-101-1-1-1000111 <br />  #include // Prewitt 算子 // 1. ...
  • https://blog.csdn.net/fengye2two/article/details/79190759 https://www.jianshu.com/p/bed4ffe996a1

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,848
精华内容 1,139
关键字:

prewitt算子边缘检测