图像锐化原理与实现
锐化通常使用拉普拉斯算子或高通滤波器。以下代码基于 3×3 锐化核:
主要步骤:
- 获取 DIB 头部信息(如宽度、高度、位深度)。
- 复制 BITMAPINFOHEADER 并创建新 DIB 以存储处理后的图像。
- 使用卷积操作进行锐化:
- 使用 3×3 锐化核: [0−10−1S−10−10]\begin{bmatrix} 0 & -1 & 0 \\ -1 & S & -1 \\ 0 & -1 & 0 \end{bmatrix}0−10−1S−10−10 其中,
S = 4 + sharpen,sharpen控制锐化强度(大于 8)。
- 使用 3×3 锐化核: [0−10−1S−10−10]\begin{bmatrix} 0 & -1 & 0 \\ -1 & S & -1 \\ 0 & -1 & 0 \end{bmatrix}0−10−1S−10−10 其中,
- 边界处理(简单处理边界像素)。
- 解锁并返回新 DIB 句柄。
HANDLE WINAPI BIPImgSharpen(HANDLE hDib, long sharpen = 15) {
if (!hDib || sharpen <= 8) return NULL;
// 锁定 DIB 句柄,获取 BITMAPINFOHEADER
BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*)GlobalLock(hDib);
if (!pBIH) return NULL;
int width = pBIH->biWidth;
int height = abs(pBIH->biHeight);
int bitCount = pBIH->biBitCount;
int bytesPerPixel = bitCount / 8;
int rowSize = ((width * bitCount + 31) / 32) * 4;
int imageSize = rowSize * height;
// 申请新 DIB 内存
HANDLE hNewDib = GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + imageSize);
if (!hNewDib) {
GlobalUnlock(hDib);
return NULL;
}
// 锁定新 DIB,获取 BITMAPINFOHEADER
BITMAPINFOHEADER* pNewBIH = (BITMAPINFOHEADER*)GlobalLock(hNewDib);
if (!pNewBIH) {
GlobalFree(hNewDib);
GlobalUnlock(hDib);
return NULL;
}
// 复制头部信息
*pNewBIH = *pBIH;
BYTE* pSrcData = (BYTE*)(pBIH + 1);
BYTE* pDstData = (BYTE*)(pNewBIH + 1);
// 定义锐化核
int kernel[3][3] = {
{ 0, -1, 0 },
{ -1, 4 + sharpen, -1 },
{ 0, -1, 0 }
};
// 遍历图像像素(忽略边界)
for (int y = 1; y < height - 1; y++) {
for (int x = 1; x < width - 1; x++) {
for (int c = 0; c < bytesPerPixel; c++) {
int sum = 0;
// 计算卷积
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
int pixelOffset = ((y + ky) * rowSize) + ((x + kx) * bytesPerPixel) + c;
sum += pSrcData[pixelOffset] * kernel[ky + 1][kx + 1];
}
}
// 限制值域 [0, 255]
int pixelOffset = (y * rowSize) + (x * bytesPerPixel) + c;
pDstData[pixelOffset] = min(255, max(0, sum));
}
}
}
// 处理边界(简单复制)
memcpy(pDstData, pSrcData, rowSize); // 复制第一行
memcpy(pDstData + (height - 1) * rowSize, pSrcData + (height - 1) * rowSize, rowSize); // 复制最后一行
for (int y = 0; y < height; y++) {
int rowOffset = y * rowSize;
memcpy(pDstData + rowOffset, pSrcData + rowOffset, bytesPerPixel); // 复制左侧像素
memcpy(pDstData + rowOffset + (width - 1) * bytesPerPixel,
pSrcData + rowOffset + (width - 1) * bytesPerPixel, bytesPerPixel); // 复制右侧像素
}
// 解锁 DIB
GlobalUnlock(hDib);
GlobalUnlock(hNewDib);
return hNewDib;
}
说明:
- 卷积计算:遍历图像像素,对每个像素应用
3x3锐化核计算加权和。 - 边界处理:避免溢出,边界像素简单复制原值(可以改进为镜像填充)。
- 性能优化:
- 可优化为多线程(如 OpenMP)。
- 通过SIMD 指令(如 SSE/AVX)加速矩阵计算。
这样就实现了一个基本的 DIB 图像锐化函数!
浙公网安备 33010602011771号