图像二值化
二值化(Binarization)是将灰度图像转换为黑白图像的方法。通常,选择一个 阈值(threshold),如果像素值大于该阈值,则设为 白色 (255),否则设为
#include <windows.h>
HANDLE WINAPI BIPImgUnicolor(HANDLE hDib) {
if (!hDib) 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; // 每像素字节数(24-bit: 3, 32-bit: 4)
int rowSize = ((width * bitCount + 31) / 32) * 4;
int imageSize = rowSize * height;
// 仅支持 24-bit 或 32-bit 图像
if (bitCount != 24 && bitCount != 32) {
GlobalUnlock(hDib);
return NULL;
}
// 创建新的 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);
// 设定二值化的阈值
const int threshold = 128;
// 遍历所有像素
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixelOffset = y * rowSize + x * bytesPerPixel;
// 计算灰度值(灰度化公式:Y = 0.299 * R + 0.587 * G + 0.114 * B)
int gray = (int)(0.299 * pSrcData[pixelOffset + 2] +
0.587 * pSrcData[pixelOffset + 1] +
0.114 * pSrcData[pixelOffset]);
// 应用二值化
BYTE newValue = (gray > threshold) ? 255 : 0;
// 设置 R、G、B 通道
pDstData[pixelOffset] = newValue; // B
pDstData[pixelOffset + 1] = newValue; // G
pDstData[pixelOffset + 2] = newValue; // R
// 32-bit DIB 需要处理 Alpha 通道
if (bitCount == 32) {
pDstData[pixelOffset + 3] = pSrcData[pixelOffset + 3]; // 保留 Alpha
}
}
}
// 解锁 DIB
GlobalUnlock(hDib);
GlobalUnlock(hNewDib);
return hNewDib;
}
📌 关键点
✅ 支持 24-bit 和 32-bit BMP(RGB & RGBA)
✅ 使用 0.299R + 0.587G + 0.114B 计算灰度(标准加权公式)
✅ 固定阈值 128(可改为 Otsu 阈值算法 提高效果)
✅ 防止溢出,保持 Alpha 通道(如果存在)
🚀 进一步优化
-
改进二值化阈值
- 目前固定
128,可以使用 Otsu’s Method 自动选择最佳阈值。
- 目前固定
-
支持
1-bitDIB- 目前仍然是
24-bit / 32-bit颜色格式,若要优化存储,可转换为1-bit黑白位图。
- 目前仍然是
黑色 (0)
浙公网安备 33010602011771号