图像二值化

二值化(Binarization)是将灰度图像转换为黑白图像的方法。通常,选择一个 阈值(threshold),如果像素值大于该阈值,则设为 白色 (255),否则设为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#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 通道(如果存在)


🚀 进一步优化

    1. 改进二值化阈值

      • 目前固定 128,可以使用 Otsu’s Method 自动选择最佳阈值。
    2. 支持 1-bit DIB

      • 目前仍然是 24-bit / 32-bit 颜色格式,若要优化存储,可转换为 1-bit 黑白位图。

  

黑色 (0)

posted on   lydstory  阅读(8)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2023-02-01 杭州天谷信息电子章子
2023-02-01 icepdf
2022-02-01 中国红歌在线
2018-02-01 智能家居

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示