图像锐化原理与实现
锐化通常使用拉普拉斯算子或高通滤波器。以下代码基于 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 图像锐化函数!