图像模糊优化

 

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
78
79
80
81
82
83
#include <windows.h>
 
HANDLE WINAPI BIPImgSoften(HANDLE hDib, long soften = 8) {
    if (!hDib || soften <= -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;  // 每像素字节数(一般 3 或 4)
    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 kernelSize = 3;
    int kernelSum = (soften + 9);  // 核的归一化系数
    int kernel[3][3] = {
        { 1,  1,  1 },
        { 1,  soften,  1 },
        { 1,  1,  1 }
    };
 
    // 遍历图像像素(忽略边界)
    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;
 
                // 计算 3×3 卷积区域
                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];
                    }
                }
 
                // 归一化处理,防止像素值溢出
                int pixelOffset = (y * rowSize) + (x * bytesPerPixel) + c;
                pDstData[pixelOffset] = min(255, max(0, sum / kernelSum));
            }
        }
    }
 
    // 处理边界(简单复制原图像)
    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;
}

  

 

你是对的,在上面的代码中,soften 变量没有真正影响模糊效果。我们可以使用 soften 值来调整模糊核的权重,使其产生不同程度的模糊效果。以下是修正后的代码:


📌 关键修改

  1. 调整模糊核的强度

    • 之前的 3×3 均值滤波器使用的是固定的均值 1/9
    • 现在 soften 变量用于调整核的强度: 1(soften+9)[1111soften1111]\frac{1}{(soften + 9)} \begin{bmatrix} 1 & 1 & 1 \\ 1 & soften & 1 \\ 1 & 1 & 1 \end{bmatrix}(soften+9)11111soften1111
    • soften 取值范围 > -8,当 soften = 8 时,中心权重大,边缘影响较小,减少模糊程度。
    • soften 越小(接近 -8),则所有像素更平均参与计算,使图像更加模糊。
  2. 优化循环计算

    • 直接在 for 循环中应用 soften 控制模糊权重,而不是固定的均值滤波。

✅ 修正后代码

cpp
#include <windows.h> HANDLE WINAPI BIPImgSoften(HANDLE hDib, long soften = 8) { if (!hDib || soften <= -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; // 每像素字节数(一般 3 或 4) 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 kernelSize = 3; int kernelSum = (soften + 9); // 核的归一化系数 int kernel[3][3] = { { 1, 1, 1 }, { 1, soften, 1 }, { 1, 1, 1 } }; // 遍历图像像素(忽略边界) 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; // 计算 3×3 卷积区域 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]; } } // 归一化处理,防止像素值溢出 int pixelOffset = (y * rowSize) + (x * bytesPerPixel) + c; pDstData[pixelOffset] = min(255, max(0, sum / kernelSum)); } } } // 处理边界(简单复制原图像) 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; }

📌 关键改进

soften 变量真正影响模糊程度

  • soften > 0:中心像素影响更大,边缘像素影响小,减少模糊感。
  • soften < 0:所有像素均匀加权,增强模糊效果。

避免固定的 1/9 平均值,可以动态控制模糊核的中心权重。

边界像素复制,防止模糊后边缘出现黑边。


🚀 进一步优化

  1. 改进 soften 取值范围

    • 目前 soften > -8,可以进一步放宽,或者动态计算更大的模糊核(如 5×5)。
  2. 高斯模糊

    • 目前是 均值模糊,可以使用 高斯核,模糊更自然: [121242121]\begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix}121242121 归一化后除以 16,实现更平滑的模糊。
  3. SIMD 加速

    • 使用 SSE / AVX 进行 向量化计算,提高处理速度。

🎯 结果

  • 模糊效果增强soften 变量现在可以 真正影响模糊程度
  • 适用于 24-bit / 32-bit DIB,并保持 RGB 色彩信息。
  • 边界复制修复,防止边缘变黑。

posted on   lydstory  阅读(10)  评论(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

统计

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