图像处理之图像锐化算法
目录
1 图像锐化算法简介
图像锐化处理的目的是使模糊的图像变得更加清晰起来,通常针对引起图像模糊的原因而进行相应地锐化操作属于图像复原的内容。图像的模糊实质就是图像受到平均或积分运算造成的,因此可以对图像进行还原运算如微分运算来使图像清晰化。从频谱角度来分析,图像模糊的实质是其高频分量被衰减,因而可以通过高通滤波操作来清晰图像。但要注意,能够进行锐化处理的图像必须有较高的信噪比,否则锐化后图像信噪比反而更低,从而使噪声的增加得比信号还要多,因此一般是先取出或减轻噪声后再进行锐化处理。
本文介绍两个基础的图像锐化算法--拉普拉斯锐化和USM锐化。
2 图像拉普拉斯锐化
图像拉普拉斯锐化是根据图像某个像素的周围像素到此像素的突变程度有关,也就是说它的依据是图像像素的变化程度。我们知道,一个函数的一阶微分描述了函数图像是朝哪里变化的,即增长或者降低;而二阶微分描述的则是图像变化的速度,急剧增长下降还是平缓的增长下降。那么据此我们可以猜测出依据二阶微分能够找到图像的色素的过渡程度,例如白色到黑色的过渡就是比较急剧的。
或者用官方点的话说:当邻域中心像素灰度低于它所在的领域内其它像素的平均灰度时,此中心像素的灰度应被进一步降低,当邻域中心像素灰度高于它所在的邻域内其它像素的平均灰度时,此中心像素的灰度应被进一步提高,以此实现图像的锐化处理。
拉普拉斯锐化实际上是一个拉普拉斯算子模板的图像卷积计算,同高斯模板类似,只不过这里的权重模板是拉普拉斯算子,这样讲可能更容易理解。
常见的拉普拉斯算子模板有4邻域模板和8邻域模板,如下所示
假设有像素P(x,y),拉普拉斯锐化结果为G(x,y)。
对于4邻域模板,拉普拉斯算子的公式如下:
对于8邻域模板,拉普拉斯算子的公式如下:
拉普拉斯锐化计算:
C语言实现拉普拉斯锐化算法代码如下
/*************************************************
功 能:图像拉普拉斯锐化
参 数:srcData - [输入/输出] 原始图像,格式为32位BGRA格式,执行后修为结果图像
width - [输入] 原始图像宽度
height - [输入] 原始图像高度
stride - [输入] 原始图像的Stride(也就是行字节数width*4)
mode - [输入] 0-4邻域模板,1-8邻域模板
返 回: 0-成功,其他-失败.
*************************************************/
int laplaceSharpen(unsigned char* srcData, int width, int height, int stride, int mode)
{
int ret = 0;
unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);
int offset = stride - width * 4;
int pos;
memcpy(tempData, srcData, sizeof(unsigned char) * height * stride);
if (mode == 0)
{
for (int j = 1; j < height - 1; j++)
{
for (int i = 1; i < width - 1; i++)
{
pos = i * 4 + j * stride;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 4 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride]), 0, 255);
pos++;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 4 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride]), 0, 255);
pos++;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 4 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride]), 0, 255);
}
}
}
else
{
for (int j = 1; j < height - 1; j++)
{
for (int i = 1; i < width - 1; i++)
{
pos = i * 4 + j * stride;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 8 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride] - tempData[pos - 4 - stride] - tempData[pos + 4 - stride] - tempData[pos - 4 + stride] - tempData[pos + 4 + stride]), 0, 255);
pos++;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 8 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride] - tempData[pos - 4 - stride] - tempData[pos + 4 - stride] - tempData[pos - 4 + stride] - tempData[pos + 4 + stride]), 0, 255);
pos++;
srcData[pos] = CLIP3(tempData[pos] + (tempData[pos] * 8 - tempData[pos - stride] - tempData[pos - 4] - tempData[pos + 4] - tempData[pos + stride] - tempData[pos - 4 - stride] - tempData[pos + 4 - stride] - tempData[pos - 4 + stride] - tempData[pos + 4 + stride]), 0, 255);
}
}
}
free(tempData);
return ret;
};
3 图像USM锐化
图像USM锐化即 Unsharp Masking,是数字图像处理软件中常用的锐化算法,它可以去除细小的干扰细节和噪声,比拉普拉斯等卷积锐化算法效果更加可信,主要表现在边界清晰和细小噪声较少上。
USM锐化有三个参数,分别是半径 Radius、数量 Amount 和阈值 Threshold,假设原图为 S,锐化结果为D,算法逻辑如下:
(1)根据半径 Radius 参数,对S进行高斯滤波并得到图 A
(2)计算校正信号Z: Z = S - A
(3)根据 Z 和 Threshold 计算二值蒙版 Mask M:
(4)根据半径 Radius 对 M 进行高斯滤波,得到 Alpha 通道: Alpha = Guass(M)
(5)根据 Amount 和 Alpha 计算 D:
C语言实现USM锐化算法代码如下
/*************************************************
功 能:图像USM锐化
参 数:srcData - [输入/输出] 原始图像,格式为32位BGRA格式,执行后修为结果图像
width - [输入] 原始图像宽度
height - [输入] 原始图像高度
stride - [输入] 原始图像的Stride(也就是行字节数width*4)
radius - [输入] 滤波半径
amount - [输入] 数量
threshold - [输入] 阈值
返 回: 0-成功,其他-失败.
*************************************************/
int USM(unsigned char* srcData, int width, int height, int stride, int radius, int amount, int threshold)
{
int ret = 0;
if (radius == 0)
return ret;
radius = CLIP3(radius, 0, 100);
amount = CLIP3(amount, 0, 500);
threshold = CLIP3(threshold, 0, 255);
unsigned char* gaussData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);
memcpy(gaussData, srcData, sizeof(unsigned char) * height * stride);
mxFastGaussFilter(gaussData, width, height, stride, radius);
int i, j, r, g, b, offset;
offset = stride - width * 4;
amount = amount * 128 / 100;
unsigned char* pSrc = srcData;
unsigned char* pDst = gaussData;
unsigned char* maskData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);
unsigned char* pMask = maskData;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
pMask[0] = abs(pSrc[0] - pDst[0]) < threshold ? 0 : 128;
pMask[1] = abs(pSrc[1] - pDst[1]) < threshold ? 0 : 128;
pMask[2] = abs(pSrc[2] - pDst[2]) < threshold ? 0 : 128;
pDst += 4;
pSrc += 4;
pMask += 4;
}
pDst += offset;
pSrc += offset;
pMask += offset;
}
pDst = gaussData;
pSrc = srcData;
pMask = maskData;
mxFastGaussFilter(maskData, width, height, stride, radius);
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
b = pSrc[0] - pDst[0];
g = pSrc[1] - pDst[1];
r = pSrc[2] - pDst[2];
b = (pSrc[0] + ((b * amount) >> 7));
g = (pSrc[1] + ((g * amount) >> 7));
r = (pSrc[2] + ((r * amount) >> 7));
b = (b * pMask[0] + pSrc[0] * (128 - pMask[0])) >> 7;
g = (g * pMask[1] + pSrc[1] * (128 - pMask[1])) >> 7;
r = (r * pMask[2] + pSrc[2] * (128 - pMask[2])) >> 7;
pSrc[0] = CLIP3(b, 0, 255);
pSrc[1] = CLIP3(g, 0, 255);
pSrc[2] = CLIP3(r, 0, 255);
pSrc += 4;
pDst += 4;
pMask += 4;
}
pSrc += offset;
pDst += offset;
pMask += offset;
}
free(gaussData);
free(maskData);
return ret;
};
4 演示Demo
4.1 开发环境
-
Windows 10 Pro x64
-
Visual Studio 2015
4.2 功能介绍
演示程序主界面如下图所示,具有图像读取、显示、保存、显示RGBA值、HSV调整、提取YUV分量、灰度化、二值化、直方图、亮度/对比度调整、饱和度调整、均值滤波、高斯滤波、拉普拉斯锐化、USM锐化等功能。

原图

拉普拉斯锐化(8邻域模板)效果图

USM锐化(半径为10,数量为100,阈值为20)效果图
4.3 下载地址
开发环境:
-
Windows 10 pro x64
-
Visual Studio 2015
下载地址:图像处理之图像锐化算法Demo
参考
图像视频滤镜与人像美颜美妆算法详解. 胡耀武、谭娟、李云夕. 电子工业出版社、2020-07
更多推荐



所有评论(0)