【问题标题】:Convert greyscale to Rgb将灰度转换为 Rgb
【发布时间】:2020-04-29 01:58:08
【问题描述】:

Here is my full code code - 代码摘录在问题的底部。

我对函数 policzkoloruj 有疑问。我需要将灰度位图转换为 rgb。

有一个表格显示位图应如何从n(greyscale) 转换为rgb(color)。运行下面的代码 sn-p 显示应该如何转换位图:

<table align="center"><tr><b><th align="center">n</th><th align="center">r<sub>n</sub></th><th align="center">g<sub>n</sub></th><th align="center">b<sub>n</sub></th></b></tr><tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">0</td></tr><tr><td align="center">1-85</td><td align="center">r<sub>n-1</sub>+3</td><td align="center">0</td><td align="center">0</td></tr><tr><td align="center">86</td><td align="center">255</td><td align="center">0</td><td align="center">0</td></tr><tr><td align="center">87-170</td><td align="center">255</td><td align="center">g<sub>n-1</sub>+3</td><td align="center">0</td></tr><tr><td align="center">171</td><td align="center">255</td><td align="center">255</td><td align="center">0</td></tr><tr><td align="center">172-255</td><td align="center">255</td><td align="center">255</td><td align="center">b<sub>n-1</sub>+3</td></tr></table>

我需要转换的图片:

int policz(int i, char rgb, kolor tab[])
{
    int p;
    switch (rgb)
    {
    case 'r':
        p = tab[i-1].R+3;
        if(p>255)
        {
            return 255;
        }
        else return p;
        break;
    case 'g':
        p= tab[i-1].G+3;
        if(p>255)
        {
            return 255;
        }
        else return p;
        break;
    case 'b':
        p= tab[i-1].B+3;;
        if(p>255)
        {
            return 255;
        }
        else return p;
        break;
    }
}
void koloruj(unsigned char tab[], kolor tab_k[], BITMAPINFOHEADER ob)
{
    char rgb;
    for(int i=0; i<ob.biSizeImage/3; i++)
    {



        if(tab[i]==0)
        {
            tab_k[i].R=0;
            tab_k[i].G=0;
            tab_k[i].B=0;

        }
        NULL;
        if(tab[i]>0 && tab[i]<86)
        {
            rgb = 'r';
            tab_k[i].R=policz(i, rgb,tab_k);
            tab_k[i].G=0;
            tab_k[i].B=0;
        }
        NULL;
        if(tab[i]==86)
        {
            tab_k[i].R=255;
            tab_k[i].G=0;
            tab_k[i].B=0;
        }
        NULL;
        if(tab[i]>86 && tab[i]<171)
        {
            rgb = 'b';
            tab_k[i].R=255;
            tab_k[i].G=policz(i, rgb,tab_k);
            tab_k[i].B=0;
        }
        NULL;
        if(tab[i]==171)
        {
            tab_k[i].R=255;
            tab_k[i].G=255;
            tab_k[i].B=0;
        }
        NULL;
        if(tab[i]>171 && tab[i]<256)
        {
            rgb = 'b';
            tab_k[i].R=255;
            tab_k[i].G=255;
            tab_k[i].B=policz(i, rgb, tab_k);
        }
        NULL;
    }
}

我猜两者的 1 个功能中的代码都有错误,这让我很紧张

【问题讨论】:

  • 所以你有一张只包含灰度信息的图片。您想要添加颜色信息。这些额外信息从何而来?您确定您的目标不是从颜色转换为灰色吗?这是可能的。
  • 另外,请在此处提供所有需要的信息,而不是外部链接。
  • 请直接在此处提供所有有用的信息,而不是通过链接。直接在此处以文本形式提供文本信息,而不是通过链接到图片。
  • 请通过edit提出问题添加信息,而不是将其隐藏在 cmets 中。
  • 如果您有代码,请在此处将其显示为minimal reproducible example,并说明缺少什么或行为不端。理想情况下,将所有内容都翻译成英文,这会增加您的机会。

标签: c++ bitmap rgb grayscale


【解决方案1】:

首先,您的程序正在泄漏内存。尽量不要使用new。请改用智能指针。这是从你的main() 改写为使用std::unique_ptr 的sn-p:

std::unique_ptr<uint8_t[]> pixmap =
    std::make_unique<uint8_t[]>(PictureInfo.biSizeImage / 3);

std::unique_ptr<kolor[]> kolormap =
    std::make_unique<kolor[]>(PictureInfo.biSizeImage / 3);

odczytaj_obraz(obraz, pixmap.get(), PictureInfo);
koloruj(pixmap.get(), kolormap.get(), PictureInfo);

其次,您对BITMAPFILEHEADERBITMAPINFOHEADER 的定义不正确。复制并转换后,它们应如下所示:

using WORD = uint16_t;
using DWORD = uint32_t;
using LONG = int32_t;

struct BITMAPFILEHEADER {
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
};

struct BITMAPINFOHEADER {
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
};

当涉及到实际转换时,如果我正确读取表格,它可以简化为:

&lt;table align="center"&gt;&lt;tr&gt;&lt;b&gt;&lt;th align="center"&gt;n&lt;/th&gt;&lt;th align="center"&gt;r&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;th align="center"&gt;g&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;th align="center"&gt;b&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;/b&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;0-85&lt;/td&gt;&lt;td align="center"&gt;n*3&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;86-171&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;(n-86)*3&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;172-255&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;(n-171)*3&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

在这种情况下,可以这样进行转换:

struct rgb_t {
    uint8_t r, g, b;
};

inline uint8_t scale(uint8_t n, uint8_t cutover) {
    return (n-cutover)*3;
}

rgb_t gray2rgb(uint8_t n) {
    static constexpr uint8_t cutover_rg = 86;
    static constexpr uint8_t cutover_gb = 171;

    if(n < cutover_rg) return {scale(n, 0), 0, 0};
    if(n <= cutover_gb) return {255, scale(n, cutover_rg), 0};
    return {255, 255, scale(n, cutover_gb)};
}

Demo of gray2rgb()

有趣的价值观:

n       r       g       b
---------------------------
0       0       0       0
1       3       0       0

85      255     0       0
86      255     0       0
87      255     3       0

170     255     252     0
171     255     255     0
172     255     255     3

254     255     255     249
255     255     255     252

从此输出中,n85 和 n86 给出相同的 rgb 值,而 n255 不会导致 b 为 255 ,感觉表应该调整一下:

&lt;table align="center"&gt;&lt;tr&gt;&lt;b&gt;&lt;th align="center"&gt;n&lt;/th&gt;&lt;th align="center"&gt;r&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;th align="center"&gt;g&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;th align="center"&gt;b&lt;sub&gt;n&lt;/sub&gt;&lt;/th&gt;&lt;/b&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;0-85&lt;/td&gt;&lt;td align="center"&gt;n*3&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;86-170&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;(n-85)*3&lt;/td&gt;&lt;td align="center"&gt;0&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td align="center"&gt;171-255&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;255&lt;/td&gt;&lt;td align="center"&gt;(n-170)*3&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
rgb_t gray2rgb_improved(uint8_t n) {
    static constexpr uint8_t cutover_rg = 85;
    static constexpr uint8_t cutover_gb = 170;

    if(n <= cutover_rg) return {scale(n, 0), 0, 0};
    if(n <= cutover_gb) return {255, scale(n, cutover_rg), 0};
    return {255, 255, scale(n, cutover_gb)};
}

Demo of gray2rgb_improved()

现在,这些值将与原始表格不匹配,而是平均填充整个光谱:

n       r       g       b
---------------------------
0       0       0       0
1       3       0       0

84      252     0       0
85      255     0       0
86      255     3       0
87      255     6       0

169     255     252     0
170     255     255     0
171     255     255     3
172     255     255     6

254     255     255     252
255     255     255     255

虽然gray2rgb() 可能会按照您的表格执行,但gray2rgb_improved() 可能会更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2014-02-26
    • 2016-10-18
    相关资源
    最近更新 更多