dsp图像处理Prewitt算子边缘检测

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

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个像素。


©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页