摘要:该文围绕基于 DSP 的边缘检测与图像锐化算法展开研究与实现。在边缘检测方面,实现了 Sobel、Roberts 和 Prewitt 三种算子算法。Sobel 算子通过计算水平和垂直方向的梯度并求和来检测边缘,对噪声有一定抑制能力;Roberts 算子基于交叉差分计算梯度,计算简单但对噪声敏感;Prewitt 算子通过 3x3 模板计算梯度,对边缘定位较准确。在图像锐化方面,实现了 Laplace 算子的三种变体算法,包括标准 Laplace、8 邻域 Laplace 和加权 Laplace。标准 Laplace 使用 4 邻域模板,8 邻域 Laplace 考虑了对角邻域,加权 Laplace 则引入了锐化强度系数以增强锐化效果。这些算法均在 DSP 环境下实现,并针对 160×160 和 180×120 等不同尺寸的图像进行处理,通过指针操作实现了高效的图像处理,同时对处理结果进行了范围限制以确保输出在有效像素范围内。实验结果表明,这些算法能够有效检测图像边缘并增强图像清晰度,为基于 DSP 的图像处理应用提供了有力的算法支持。
关键词:图像锐化;边缘检测;加权处理
引 言
在数字图像处理领域,边缘检测与图像锐化是基础且关键的技术,广泛应用于计算机视觉、医学影像等领域。边缘作为图像中像素值急剧变化的区域,是目标识别等高级处理的基础;锐化则能增强图像细节,提升视觉效果。随着嵌入式与实时处理需求增长,在 DSP 上高效实现这些算法成为研究热点。
DSP 凭借高速数据处理与实时性优势,成为图像处理重要平台。工业检测、智能监控等场景不仅要求算法精准,更对处理速度提出严格要求。经典边缘检测算子(如 Sobel、Roberts 等)与 Laplace 锐化算子虽理论成熟,但应用于 DSP 时需结合其体系结构优化,如利用并行处理能力、高效内存访问模式提升效率。
本研究聚焦 DSP 平台的边缘检测与锐化算法实现,分析改进经典算法,结合 DSP 硬件特性优化 Sobel、Prewitt 等边缘算子及 Laplace 变体,通过实验验证算法有效性,为 DSP 在图像处理中的应用提供技术支撑。
2、图像锐化算法及实现
2.1 图像锐化技术概述
图像锐化是数字图像处理中的关键技术,其核心目标是通过增强图像中像素值的突变区域(即边缘和细节),提升图像的视觉清晰度和细节表现力。从信号处理的角度来看,图像模糊本质上是图像信号经过低通滤波的结果,而锐化则通过高通滤波或微分运算,对图像的高频成分(边缘、纹理等)进行增强,抑制低频成分(平滑区域)。
图像锐化的核心是通过增强像素值的突变区域(边缘与细节)提升图像清晰度。本代码基于拉普拉斯(Laplace)二阶微分算子实现锐化,其原理是通过计算中心像素与邻域像素的差值,突出灰度值的突变部分。拉普拉斯算子对图像中的阶跃边缘和孤立点响应显著。
在实际应用中,图像锐化的目的主要体现在两方面:一是改善图像的视觉效果,使模糊的图像变得清晰,便于人眼观察,如老照片修复、医学影像增强等;二是为后续的图像分析任务(如目标识别、边缘检测、特征提取)提供更优质的输入,避免因图像模糊导致的特征丢失或误判。例如,在工业质检中,锐化可帮助更精准地识别零件表面的缺陷边缘。
本文主要是讨论拉普拉斯锐化技术,分别介绍四领域拉普拉斯锐化与八领域拉普拉斯锐化以及加权拉普拉斯锐化。
2.2 四领域拉普拉斯锐化
该方法采用4邻域模板,中心系数为 5,上下左右邻域系数为 -1
对图像内部像素(非边缘区域),通过公式(3)计算锐化值,并将结果限制在 [0, 255]范围内。
对于图像边缘部分如图像四周像素(第一行、最后一行、最左列、最右列)直接保留原值,避免越界错误。
2.3八邻域拉普拉斯锐化
该方法采用8邻域模板:扩展至 8 邻域,中心系数为 8,周围 8 个方向系数均为 - 1,模板为:
针对对角邻域影响,采用公式(5)处理:
相比4邻域,8邻域对各方向边缘的增强更均衡,尤其适合纹理丰富的图像。
2.4 加权拉普拉斯锐化
该方法引入锐化强度系数alpha,通过加权融合原图与拉普拉斯算子输出,其中alpha可调节锐化程度,alpha>1时增强效果更明显,同时通过范围限制避免像素值溢出。
2.5 DSP实验程序
/*======== 头文件引用===========*/
#include "stdio.h"
/*============= 工作变量定义======*/
unsigned char *pr_n; //指针定义
unsigned char *pr_s; //指针定义//说明:定义数据存放变量
#pragma DATA_SECTION(IMG,"data");
int IMG[30000];#pragma DATA_SECTION(Original_IMG,"data");
unsigned char Original_IMG[30000];#pragma DATA_SECTION(Sharp_IMG,"data");
unsigned char Sharp_IMG[30000];void IMG_Sharp_Laplace();
void IMG_Sharp_Laplace_8Neighbor();
void IMG_Sharp_Laplace_Weighted();
int CoefArray[9]={1,1,1,1,1,1,1,1,1};/*================= 主程序 ================*/
main()
{ long n;int imgH,imgW;int *ptr;imgH=180; //图像高与宽,因为数据文件中的图像是180X120像素的imgW=120; /*=========== 初始化 ==========*///1 把图像数据从IMG中移到Noise_IMG数组中ptr=IMG;pr_n=Original_IMG;for (n=0;n<imgH*imgW;n++)*pr_n++=*ptr++;//说明:在此暂停,可看到噪声图像 //指针指向数组pr_n=Original_IMG;pr_s=Sharp_IMG;//2 调用子程序,进行彩色图像变换成灰度图像while (1){ // IMG_Sharp_Laplace(pr_n,pr_s,imgW,imgH);//IMG_Sharp_Laplace_8Neighbor(pr_n,pr_s,imgW,imgH);IMG_Sharp_Laplace_Weighted(pr_n,pr_s,imgW,imgH);//说明:上面子程序执行后,在此暂停,可看平滑后的图像 }//说明:在此暂停,可看变换后的灰度图像
/*============== 子程序 =============*/
void IMG_Sharp_Laplace
( unsigned char *F, /* 输入原图像 */unsigned char *G, /* 输出的锐化图像 */int cols, int rows /* 图像的宽度与高度 */
)
{ //定义局部变量unsigned char *ptr, *pp, *newpp;int tmpNum,i, x, y;//图像四周的像素不进行锐化,等于原值 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; //指针指向原图像 tmpNum = 5*(*pp); //(x,y)处像素的灰度值tmpNum-=*(pp-cols); //(x,y)处上方像素的灰度值tmpNum-=*(pp-1); //(x,y)处左边像素的灰度值tmpNum-=*(pp+1); //(x,y)处右边像素的灰度值tmpNum-=*(pp+cols); //(x,y)处下方像素的灰度值//检测数据是否溢出,且将平均值赋给平滑图像if (tmpNum > 255)*newpp=255;else if (tmpNum<0)*newpp=0;else*newpp=tmpNum; }
} //程序结束void IMG_Sharp_Laplace_Weighted(unsigned char *F, /* 输入原图像 */unsigned char *G, /* 输出的锐化图像 */int cols, int rows /* 图像的宽度与高度 */
)
{unsigned char *ptr, *pp, *newpp;int tmpNum, x, y;float alpha = 1.5f; // 锐化强度系数int laplacian;// 处理图像边缘像素,保持原值for (x = 0; x < cols; x++) {G[x] = F[x]; // 第一行G[(rows-1)*cols + x] = F[(rows-1)*cols + x]; // 最后一行}for (y = 0; y < rows; y++) {G[y*cols] = F[y*cols]; // 最左列G[y*cols + cols-1] = F[y*cols + cols-1]; // 最右列}// 处理内部像素for (y = 1; y < rows - 1; y++) {for (x = 1; x < cols - 1; x++) {newpp = G + y*cols + x;pp = F + y*cols + x;// 拉普拉斯算子计算laplacian = 4 * (*pp) - *(pp-cols) - *(pp-1) - *(pp+1)- *(pp+cols); // 带权重的锐化:原图 + alpha * 拉普拉斯值tmpNum = (int)(*pp + alpha * laplacian);*newpp = (unsigned char)tmpNum;}}
}
void IMG_Sharp_Laplace_8Neighbor(unsigned char *F, /* 输入原图像 */unsigned char *G, /* 输出的锐化图像 */int cols, int rows /* 图像的宽度与高度 */
)
{unsigned char *ptr, *pp, *newpp;int tmpNum, x, y;// 处理图像边缘像素,保持原值for (x = 0; x < cols; x++) {G[x] = F[x]; // 第一行G[(rows-1)*cols + x] = F[(rows-1)*cols + x]; // 最后一行}for (y = 0; y < rows; y++) {G[y*cols] = F[y*cols]; // 最左列G[y*cols + cols-1] = F[y*cols + cols-1]; // 最右列}// 处理内部像素for (y = 1; y < rows - 1; y++) {for (x = 1; x < cols - 1; x++) {newpp = G + y*cols + x;pp = F + y*cols + x;// 八邻域拉普拉斯算子:中心系数8,八方向系数-1tmpNum = 8 * (*pp) - *(pp-cols-1) - *(pp-cols)- *(pp-cols+1)- *(pp-1)- *(pp+1) - *(pp+cols-1)- *(pp+cols) - *(pp+cols+1);*newpp = (unsigned char)tmpNum;}}
}
3、边缘检测算法及实现
3.1 边缘检测技术概述
边缘检测是图像处理的核心技术,旨在识别图像中像素值剧烈变化的区域,对应物体边界或场景深度突变。其本质是通过灰度梯度的局部极值表征边缘,为目标识别、图像分割等任务提供结构信息,同时实现数据降维。经典算法分为一阶与二阶导数两类:一阶算子如 Roberts、Prewitt 和 Sobel,通过梯度计算突出边缘,其中 Sobel 算子因中心加权设计对噪声更鲁棒;二阶算子以拉普拉斯为代表,通过二阶导数检测突变点,但常与高斯滤波结合(如 LOG 算子)。其原理如下。
图像f(x,y)在点(x,y)处的梯度是一个二维向量:
在离散域中,偏导数通常通过差分近似计算。一阶导数算子通过设计卷积模板来估计梯度,模板的选择直接影响边缘检测的精度和抗噪性。
随着技术发展,深度学习驱动的边缘检测(如 HED)通过端到端训练提升复杂场景精度,多尺度分析与自适应阈值方法也增强了算法鲁棒性。该技术广泛应用于医学影像(器官边界提取)、工业质检(缺陷检测)、自动驾驶(道路识别)等领域。当前挑战包括噪声与纹理干扰、弱边缘漏检及实时性需求,未来研究将聚焦深度学习与传统算法融合、轻量化模型设计及跨模态边缘感知。
本文主要是讨论基于一阶导数计算梯度,共实现了Sobel、Roberts与Prewitt三个算子。
3.2 Sobel算子
Sobel 算子采用两个 3×3 模板分别计算水平和垂直方向的梯度分量。其水平梯度模板Gx和垂直梯度模板Gy分别为:
该模板设计特点在于对中心像素的邻域进行加权,增强了边缘响应的同时抑制了部分噪声。最终梯度幅值通常采用绝对值之和近似:
3.3 Roberts算子
Roberts 算子是最早提出的边缘检测算子之一,基于 2×2 邻域的交叉差分计算梯度。 其梯度分量计算公式为:
梯度幅值同样采用绝对值之和:
Roberts 算子计算简单,但仅考虑 2×2 邻域,对边缘的定位精度较低,且对噪声敏感。
3.4 Sobel算子
Prewitt 算子与 Sobel 算子类似,采用 3×3 模板计算梯度,但未对中心像素进行加权。其水平和垂直梯度模板分别为:
Prewitt 算子的计算复杂度与 Sobel 相近,但由于未对中心像素加权,其边缘响应强度略低于 Sobel 算子。
3.5 DSP实验程序
/*======== 头文件引用===========*/
#include "stdio.h"
/*============= 工作变量定义======*/
unsigned char *pSource; //指针定义
unsigned char *pNew; //指针定义
int *pIMG;//说明:定义数据存放变量
#pragma DATA_SECTION(IMG,"data");
int IMG[30000];#pragma DATA_SECTION(sourceIMG,"data");
unsigned char sourceIMG[30000];#pragma DATA_SECTION(newIMG,"data");
unsigned char newIMG[30000];void IMG_sobel();
void IMG_Roberts();
void IMG_Prewitt();///
//使用说明:
// 1. 本程序可以在Simulator下运动;
// 2. 程序编译、链接、加载成功后,先
// 执行File/data/load,将要进行颜色转换的图像数据从Gray_Lena160x160.dat
// 加载入数据存储器存储地址RGB_IMG中
// 3. 数据加载成功后,再Debug/Go Main, 一步一步运行程序
////*================= 主程序 ================*/
main()
{ int n,imgH,imgW;/*=========== 初始化 ==========*/imgH=160; //图像的高与宽,因为数据文件所对应的图像高与宽就是160,160imgW=160; //指针指向数组 pIMG=IMG;pSource=sourceIMG;for (n=0;n<imgH*imgW;n++)*pSource++=*pIMG++; pSource=sourceIMG;pNew=newIMG; //说明:在此暂停,可看原始RGB彩色图像 while (1){ //IMG_sobel(pSource,pNew,imgW,imgH);// IMG_Roberts(pSource,pNew,imgW,imgH); IMG_Prewitt(pSource,pNew,imgW,imgH); } //说明:在此暂停,可看变换后的灰度图像 }
void IMG_sobel
(const unsigned char *restrict in, /* Input image data */unsigned char *restrict out, /* Output image data */int cols, int 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;/* ---------------------------------------------------------------- *//* Store it. *//* ---------------------------------------------------------------- */out[i + 1] = O;}
}
/** 函数名称:IMG_Roberts* 功能:使用罗伯特算子实现图像边缘检测* 参数:* const unsigned char *restrict in - 输入图像数据* unsigned char *restrict out - 输出图像数据* int cols, int rows - 图像尺寸*/
void IMG_Roberts(const unsigned char *restrict in, /* 输入图像数据 */unsigned char *restrict out, /* 输出图像数据 */int cols, int rows /* 图像尺寸 */
)
{int Gx, Gy, G;int i, j;int w = cols;// 遍历图像,处理每个像素点(边缘像素除外)for (j = 0; j < rows - 1; j++) {for (i = 0; i < cols - 1; i++) {// 计算当前位置的梯度Gx = in[j*w + i] - in[(j+1)*w + (i+1)]; // 水平梯度Gy = in[(j+1)*w + i] - in[j*w + (i+1)]; // 垂直梯度// 计算梯度幅值(通常使用绝对值之和)G = abs(Gx) + abs(Gy);// 确保结果在0-255范围内if (G > 255) G = 255;// 存储结果out[j*w + i] = G;}}
}
/** 函数名称:IMG_Prewitt* 功能:使用普瑞维特算子实现图像边缘检测* 参数:* const unsigned char *restrict in - 输入图像数据* unsigned char *restrict out - 输出图像数据* int cols, int rows - 图像尺寸*/
void IMG_Prewitt(const unsigned char *restrict in, /* 输入图像数据 */unsigned char *restrict out, /* 输出图像数据 */int cols, int rows /* 图像尺寸 */
)
{int Gx, Gy, G;int i, j;int w = cols;// 遍历图像,处理每个像素点(边缘像素除外)for (j = 1; j < rows - 1; j++) {for (i = 1; i < cols - 1; i++) {// 计算水平梯度分量Gx = (in[(j-1)*w + (i-1)] + in[j*w + (i-1)] + in[(j+1)*w + (i-1)]) - (in[(j-1)*w + (i+1)] + in[j*w + (i+1)] + in[(j+1)*w + (i+1)]);// 计算垂直梯度分量Gy = (in[(j-1)*w + (i-1)] + in[(j-1)*w + i] + in[(j-1)*w + (i+1)]) - (in[(j+1)*w + (i-1)] + in[(j+1)*w + i] + in[(j+1)*w + (i+1)]);// 计算梯度幅值(通常使用绝对值之和)G = abs(Gx) + abs(Gy);// 确保结果在0-255范围内if (G > 255) G = 255;// 存储结果out[j*w + i] = G;}}
4、实验结果与分析
4.1 操作步骤
1设置ccs为软件仿真环境
打开setup ccs2,点击clear,选择family为c64xx,platform为simulator,endianness为little,在选择DM642 Device Simulator…点击import,点击save and quit,如下图所示,启动CCS。
双击桌面上CCS 2 ('C6000)图标,运行CCS。
2、编译、链接程序:执行菜单Project/Rebuild All,汇编结果在将汇编信息输出窗口中给出。编译后将在Bebug目录中产生一个ImgSmooth.out文件。
3、加载程序:执行File/Load Program,选择ImgSmooth.out并打开,即将可执行文件加载到DSP软件仿真器simulator中,此时CCS将自动打开一个反汇编窗口。
4、将图像的数据从 dat 文件读入到内存:执行 File/data/load,将要进行颜色转换的图像数据 从 Data160x160.dat (说明:*.dat 格式,内部存放了某图像各像素的灰度值)文件中加载入到数据存储器,即在弹出的窗口中输入存储地址 IMG 与数据的长度,如下图所示。
5、运行程序:执行Debug/Run。为了便于观看试验前后的结果,可以在程序中设置断点,采用单步执行的方法运行程序。
4.2 实验结果
4.2.1拉普拉斯锐化
显示出锐化之前的图像:执行 View/Graph/Image,在弹出的对话框中选择颜色类型为 RGB,并输入 RGB 彩色图像三个通道数据的地址,以及图像显示格式(显示几行、每行几像素)等内容。
图4.1 锐化之前的图像
显示锐化之后的图像:执行 View/Graph/Image,在弹出的对话框中选择颜色类型为 RGB,并输入灰度图像据的地址,以及图像显示格式(显示几行、每行几像素)等内容。
图4.2 四领域拉普拉斯锐化的图像
图4.3 八领域拉普拉斯锐化的图像
图4.4 加权拉普拉斯锐化的图像
4.2.2 边缘检测结果
图4.5 原图像
如下图所示为边缘检测结果
图4.6 sobel算子检测图像
图4.7 Roberts算子检测图像
图4.8 Prewitt算子检测图像
4.3 实验结果分析
在标准测试图像上的实验表明,三种拉普拉斯锐化算法呈现出显著差异。标准 4 邻域拉普拉斯对水平 / 垂直边缘增强效果突出,但对角方向细节提升有限,可能产生 “棋盘格” 伪影;八邻域拉普拉斯通过引入对角像素信息,有效消除了方向性偏差,使各方向边缘增强更均衡,但同时也放大了噪声;加权拉普拉斯通过调整系数 α(实验中 α=1.5 时效果最优),在增强边缘的同时保留了更多原图细节,视觉效果更自然。在 DSP 平台上,八邻域算法较 4 邻域计算量增加;加权拉普拉斯因引入浮点运算,耗时增加,但灵活性更高,适用于医学影像等对细节保留要求高的场景。
对比 Sobel、Roberts 和 Prewitt 算子的边缘检测效果,Roberts 算子因仅考虑 2×2 邻域,边缘定位精度最低,易产生断裂边缘,尤其对噪声敏感,但计算速度最快;Prewitt 算子通过 3×3 模板平滑噪声,边缘连续性优于 Roberts,但因未对中心像素加权,边缘响应强度略弱于 Sobel;Sobel 算子在边缘完整性、定位精度与抗噪性间取得最佳平衡。在纹理复杂区域(如 Lena 图像的头发部分),Sobel 和 Prewitt 能检测到更多细节,而 Roberts 则出现明显漏检。实验进一步表明,三种算子的边缘宽度均为 1 像素,但 Sobel 的边缘更接近真实物体边界,误检率较 Prewitt 低。
5、小结
通过对拉普拉斯锐化与经典边缘检测算子的设计实现,验证了算法在 DSP 平台的有效性。拉普拉斯锐化中,八邻域算子对图像的纹理增强效果显著,相比标准4邻域算法,其边缘梯度保留率提升,而加权拉普拉斯(α=1.5)在图像中使边界对比度。边缘检测实验表明,Sobel 算子在 160×160 像素图像中,较 Prewitt 算子提升检测精度,且抗噪性优于 Roberts算子。通过这次设计得到了很多收获和体会。第一提高了综合运用所学知识的能力。第二增强了根据课程需要选学参考资料查阅手册图表和文献资料的自学能力。通过独立思考深入研究有关问题学会自己分析解决问题的方法。第三通过实际方案的分析比较设计计算元件选取安装调试等环节初步掌握了简单使用ccs设计方法。第四在这次设计过程中光有理论知识是不够的还必须懂一些实践中的知识。所以在设计的实践中比较常用的仪器的使用方法提高了动手能力。第五培养了严谨的工作作风和科学态度。在这次设计过程中我对仿真软件ccs等软件有了更进一步的了解。
参考文献
[1]冈萨雷斯, 伍兹. 数字图像处理(第三版)[M]. 北京: 电子工业出版社. 2011. 06. 39 – 91.
[2]康晓东. 医学图像信号变换与压缩[M]. 北京: 北京清华大学出版社. 2004.
[3]余英汉, 蔡汉添, 谢胜利. 信号处理新方法导论[M]. 北京: 清华大学出版社. 2004.
[4]王永良, 陈辉, 彭应宁, 万群. 空间谱估计理论与算法[M]. 北京: 清华大学出版社. 2004.
[5]李建平. 小波分析与信号处理理论、应用及软件实现[M]. 重庆: 重庆出版社. 1997.
[6] W. K. Pratt, Digital Image Processing. New York: Wiley,1991.
[7] G. R. Arce, N. C. Gallagher and T. Nodes, “Median filters:Theory and applica tions,” in Advances in ComputerVision and Image Processing, Greenwich, CT: JAI, 1986.