Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 改进灰度转换结果_Image Processing_Mfc_Cbitmap - Fatal编程技术网

Image processing 改进灰度转换结果

Image processing 改进灰度转换结果,image-processing,mfc,cbitmap,Image Processing,Mfc,Cbitmap,这是彩色菜单: 这是同一个菜单,其中一些菜单项被禁用,位图设置为灰度: 转换为灰度的代码: auto col = GetRValue(pixel) * 0.299 + GetGValue(pixel) * 0.587 + GetBValue(pixel) * 0.114; pixel = RGB(col, col, col); 我是色盲,但似乎有些色盲看起来没什么不同。我想它首先与原色有关吧 如果能更明显地看出他们是残疾的,那就太好了。就像,

这是彩色菜单:

这是同一个菜单,其中一些菜单项被禁用,位图设置为灰度:

转换为灰度的代码:

auto col = GetRValue(pixel) * 0.299 + 
           GetGValue(pixel) * 0.587 + 
           GetBValue(pixel) * 0.114;
pixel = RGB(col, col, col);
我是色盲,但似乎有些色盲看起来没什么不同。我想它首先与原色有关吧

如果能更明显地看出他们是残疾的,那就太好了。就像,这是非常明确的文字


我们能吗?

对于非色盲的人来说,这是很明显的

只需对图像应用与文本相同的强度降低

我没有检查你的价值观。假设文本为白色(100%强度)

灰色文本的强度为50%

那么位图的最大强度也应该是50%

for each gray pixel:
  pixel_value = pixel_value / max_pixel_value * gray_text_value

这样可以进一步降低每个位图的对比度,避免任何像素比文本更亮。

对于没有色盲的人来说,这是非常明显的

只需对图像应用与文本相同的强度降低

我没有检查你的价值观。假设文本为白色(100%强度)

灰色文本的强度为50%

那么位图的最大强度也应该是50%

for each gray pixel:
  pixel_value = pixel_value / max_pixel_value * gray_text_value

这样可以进一步降低每个位图的对比度,避免任何像素比文本更亮。

这与您的问题没有直接关系,但由于您正在更改颜色,因此还可以修复突出的角点像素(所谓角点像素,我不是指位图矩形边缘的像素,我是指人类可识别图像的角点)

例如,在下图中,在页面的角落处有一个红色像素。我们希望找到那个红色像素并将其与背景色混合,这样它就不会突出

若要查找角点像素,请检查左侧和顶部的像素,如果左侧和顶部都是背景色,则有一个角点像素。对右上角、左下角和右下角重复相同的操作。将角点像素与背景混合

您可以按照zett42的建议更改alpha透明度,而不是更改为灰度

void change(HBITMAP hbmp, bool enabled)
{
    if(!hbmp)
        return;
    HDC memdc = CreateCompatibleDC(nullptr);

    BITMAP bm;
    GetObject(hbmp, sizeof(bm), &bm);
    int w = bm.bmWidth;
    int h = bm.bmHeight;
    BITMAPINFO bi = { sizeof(BITMAPINFOHEADER), w, h, 1, 32, BI_RGB };

    std::vector<uint32_t> pixels(w * h);
    GetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);

    //assume that the color at (0,0) is the background color
    uint32_t old_color = pixels[0];

    //this is the new background color
    uint32_t bk = GetSysColor(COLOR_MENU);

    //swap RGB with BGR
    uint32_t new_color = RGB(GetBValue(bk), GetGValue(bk), GetRValue(bk));

    //define lambda functions to swap between BGR and RGB
    auto bgr_r = [](uint32_t color) { return GetBValue(color); };
    auto bgr_g = [](uint32_t color) { return GetGValue(color); };
    auto bgr_b = [](uint32_t color) { return GetRValue(color); };

    BYTE new_red = bgr_r(new_color);
    BYTE new_grn = bgr_g(new_color);
    BYTE new_blu = bgr_b(new_color);

    //change background and modify disabled bitmap
    for(auto &p : pixels)
    {
        if(p == old_color)
        {
            p = new_color;
        }
        else if(!enabled)
        {
            //blend color with background, similar to 50% alpha
            BYTE red = (bgr_r(p) + new_red) / 2;
            BYTE grn = (bgr_g(p) + new_grn) / 2;
            BYTE blu = (bgr_b(p) + new_blu) / 2;
            p = RGB(blu, grn, red); //<= BGR/RGB swap
        }
    }

    //fix corner edges
    for(int row = h - 2; row >= 1; row--)
    {
        for(int col = 1; col < w - 1; col++)
        {
            int i = row * w + col;
            if(pixels[i] != new_color)
            {
                //check the color of neighboring pixels:
                //if that pixel has background color,
                //then that pixel is the background 

                bool l = pixels[i - 1] == new_color; //left pixel is background
                bool r = pixels[i + 1] == new_color; //right  ...
                bool t = pixels[i - w] == new_color; //top    ...
                bool b = pixels[i + w] == new_color; //bottom ...

                //we are on a corner pixel if:
                //both left-pixel and top-pixel are background or
                //both left-pixel and bottom-pixel are background or
                //both right-pixel and bottom-pixel are background or
                //both right-pixel and bottom-pixel are background
                if(l && t || l && b || r && t || r && b)
                {
                    //blend corner pixel with background
                    BYTE red = (bgr_r(pixels[i]) + new_red) / 2;
                    BYTE grn = (bgr_g(pixels[i]) + new_grn) / 2;
                    BYTE blu = (bgr_b(pixels[i]) + new_blu) / 2;
                    pixels[i] = RGB(blu, grn, red);//<= BGR/RGB swap
                }
            }
        }
    }

    SetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);
    DeleteDC(memdc);
}

这与您的问题没有直接关系,但由于您正在更改颜色,您还可以修复突出的角点像素(角点像素不是指位图矩形边缘的像素,而是指人类可识别图像的角点)

例如,在下图中,在页面的角落处有一个红色像素。我们希望找到那个红色像素并将其与背景色混合,这样它就不会突出

若要查找角点像素,请检查左侧和顶部的像素,如果左侧和顶部都是背景色,则有一个角点像素。对右上角、左下角和右下角重复相同的操作。将角点像素与背景混合

您可以按照zett42的建议更改alpha透明度,而不是更改为灰度

void change(HBITMAP hbmp, bool enabled)
{
    if(!hbmp)
        return;
    HDC memdc = CreateCompatibleDC(nullptr);

    BITMAP bm;
    GetObject(hbmp, sizeof(bm), &bm);
    int w = bm.bmWidth;
    int h = bm.bmHeight;
    BITMAPINFO bi = { sizeof(BITMAPINFOHEADER), w, h, 1, 32, BI_RGB };

    std::vector<uint32_t> pixels(w * h);
    GetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);

    //assume that the color at (0,0) is the background color
    uint32_t old_color = pixels[0];

    //this is the new background color
    uint32_t bk = GetSysColor(COLOR_MENU);

    //swap RGB with BGR
    uint32_t new_color = RGB(GetBValue(bk), GetGValue(bk), GetRValue(bk));

    //define lambda functions to swap between BGR and RGB
    auto bgr_r = [](uint32_t color) { return GetBValue(color); };
    auto bgr_g = [](uint32_t color) { return GetGValue(color); };
    auto bgr_b = [](uint32_t color) { return GetRValue(color); };

    BYTE new_red = bgr_r(new_color);
    BYTE new_grn = bgr_g(new_color);
    BYTE new_blu = bgr_b(new_color);

    //change background and modify disabled bitmap
    for(auto &p : pixels)
    {
        if(p == old_color)
        {
            p = new_color;
        }
        else if(!enabled)
        {
            //blend color with background, similar to 50% alpha
            BYTE red = (bgr_r(p) + new_red) / 2;
            BYTE grn = (bgr_g(p) + new_grn) / 2;
            BYTE blu = (bgr_b(p) + new_blu) / 2;
            p = RGB(blu, grn, red); //<= BGR/RGB swap
        }
    }

    //fix corner edges
    for(int row = h - 2; row >= 1; row--)
    {
        for(int col = 1; col < w - 1; col++)
        {
            int i = row * w + col;
            if(pixels[i] != new_color)
            {
                //check the color of neighboring pixels:
                //if that pixel has background color,
                //then that pixel is the background 

                bool l = pixels[i - 1] == new_color; //left pixel is background
                bool r = pixels[i + 1] == new_color; //right  ...
                bool t = pixels[i - w] == new_color; //top    ...
                bool b = pixels[i + w] == new_color; //bottom ...

                //we are on a corner pixel if:
                //both left-pixel and top-pixel are background or
                //both left-pixel and bottom-pixel are background or
                //both right-pixel and bottom-pixel are background or
                //both right-pixel and bottom-pixel are background
                if(l && t || l && b || r && t || r && b)
                {
                    //blend corner pixel with background
                    BYTE red = (bgr_r(pixels[i]) + new_red) / 2;
                    BYTE grn = (bgr_g(pixels[i]) + new_grn) / 2;
                    BYTE blu = (bgr_b(pixels[i]) + new_blu) / 2;
                    pixels[i] = RGB(blu, grn, red);//<= BGR/RGB swap
                }
            }
        }
    }

    SetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);
    DeleteDC(memdc);
}


我只对菜单项图像本身应用灰度。文本由MFC框架处理。你能在实践中给我看一下你的建议吗?谢谢。@AndrewTruckle截图,使用允许在鼠标位置显示像素值的许多免费图像程序之一,找出文本使用的灰度值。屏幕显示为灰色out text的亮度为92(在inverval 0-255中)。您只需计算像素值,然后确定最大像素值,并使用该值将值标准化为[0-92]或者简单地降低标准化值,直到您满意为止。屏幕截图中显示的暗主题可能会使亮度降低,但我相信如果使用亮主题,情况会更糟。这就是为什么我会将图像的整体透明度更改为50%,以便图像与背景混合,而不管背景是否为暗主题声音是暗的或亮的。我只对菜单项图像本身应用灰度。文本由MFC框架处理。请在实践中向我展示您的建议好吗?谢谢。@AndrewTruckle截图,使用允许在鼠标上显示像素值的众多免费图像程序之一,找出文本的强度位置。灰显文本的亮度为92(在inverval 0-255中)。您只需计算像素值,然后确定最大像素值,并使用该值将值规格化为[0-92]或者简单地降低标准化值,直到您满意为止。屏幕截图中显示的暗主题可能会使亮度降低,但我相信如果使用亮主题,情况会更糟。这就是为什么我会将图像的整体透明度更改为50%,以便图像与背景混合,而不管背景是否为暗主题颜色是暗的或浅的。彩色位图看起来比灰色位图更糟糕,因为它们在暗背景下具有锐利的浅色边缘。若要修复此问题,请编辑位图,例如在箭头末端找到浅灰色像素,将其更改为白色或任何背景颜色。或者,您可以将其保留。这可能与灯光有关主题背景。大多数人使用浅色背景主题,因此大多数客户都应该感到高兴!最后一个值应该是
0.114
,而不是
0.144
,并且需要采用
RGB
值,正如@BarmakShemirani所指出的那样,我处理了我的问题代码,而不是答案代码。哦,实际的屏幕截图是正确的值ues。我建议使用32 bpp图像和alpha通道来去除锯齿状边缘(尤其是在“周末会议”图标上,它看起来非常难看)。对于禁用的图像,除了灰度效果之外,或作为灰度效果的替代,将整体透明度设置为50%左右。我将禁用的图像变暗,然后我会更清楚地看到它们被禁用。彩色位图看起来比灰色位图更差,因为它们