将8位彩色图像转换为灰色VGA

时间:2015-10-12 15:16:05

标签: image-processing

我有8 bit color image。将此转换为Grayscale Image的方法是什么。

对于普通的24位真彩色RGB图像,我们要么进行平均(R + G + B)/ 3

然后是'Weighted Averaging,其中我们计算0.21 R + 0.72 G + 0.07 B。

然而,上述公式适用于24位图像(如果我错了,请纠正我)。其中8位用于表示R,G,B各自的含量。因此,当我们应用上述平均方法时,我们从24位真彩色图像中获得合成的8位灰度图像。

那么如何计算8位彩色图像的灰度图像:

请注意: 8位彩色图像的结构如下: Refer this link

Bit    7  6  5  4  3  2  1  0
Data   R  R  R  G  G  G  B  B

我们可以看到,

  • 第7,6,5位表示红色内容
  • 第4,3,2位表示绿色内容
  • 位数1,0表示蓝色内容

因此上面的图像实际上总共有4个阴影 (因为,在灰度级中,当每个R,G,B分量的贡献为100%时,获得白色像素。并且由于蓝色分量仅有2位,因此有效地存在2 2 组合,即4个级别。)

因此,如果我考虑R,G和B的2位,我设法获得如下灰度级:

R   G   B   GrayLevel
00  00  00   Black
01  01  01   Gray 1
10  10  10   Gray 2
11  11  11   White 

从红色和绿色组件中考虑哪些位以及要忽略哪些位。

如何量化除上述位之外的位值的灰度级。

修改

我想在FPGA上实现上述系统,因此内存是一个敏锐的方面。图像质量无关紧要。不知何故,有可能将8位颜色img的所有值量化为相应的灰色阴影吗?

3 个答案:

答案 0 :(得分:2)

此方法提供灰色0..255的输出范围(并非使用所有灰度级):

b = rgb8 & 3;
g = (rgb8 >> 2) & 7;
r = rgb8 >> 5;
gray255 = 8 * b + 11 * r + 22 * g;

如果你有256个字节可用,你可以填写LUT(查询表)一次,然后用它代替计算:

grayimage[i] = LUT[rgb8image[i]];

答案 1 :(得分:0)

如果你真的想坚持每个灰色像素2位,你可以买得起简单的乘数,你可以想到公式

G = 5×R + 9×G + 4 B

其中R和G采用3位,B采用2(系数已经适应)。这将产生7位值,范围为[0,110],其中您将保持最重要的2。

您可能会考虑调整系数以更均匀地占据四个级别。

答案 2 :(得分:0)

你基本上有一个魔方的颜色立方体,如果你可以花一点时间来想象它,它的尺寸为8 x 8 x 4。一面有8个正方形,从黑色到红色,一面有8个正方形,从黑色到绿色,一面有4个正方形,从黑色到蓝色。

从本质上讲,你可以按照自己喜欢的方式进行分类,因为你不太在乎质量。因此,如果你想要4个输出灰度级,你基本上可以做任何你喜欢的两个切割,并将每个结果形状内的所有内容整合为一个灰度级。通常情况下,你的目标是使每个肿块的体积相同 - 这样你就可以将红色侧面切成两半,将绿色侧面切成两半,并忽略蓝色通道中的任何差异作为一种选择。

这样做的一种方法可能是根据距离原点的距离(即黑色)制作等量的肿块。我没有可用的8x8x4立方体,但想象地球是8x8x4,那么我们将使内核中的所有像素变黑,外核中的像素为深灰色,地幔中的像素为浅灰色,外壳为白色 - 如每个肿块中原始像素的数量是相同的。这听起来很复杂但不是!

enter image description here

让我们运行所有可能的红色,绿色和蓝色值,并使用

计算每个值与黑色的距离
d=R^2 +G^2 +B^2

然后按该距离对值进行排序,然后对这些行进行编号:

#!/bin/bash
for r in 0 1 2 3 4 5 6 7; do
   for g in 0 1 2 3 4 5 6 7; do
      for b in 0 1 2 3; do
         # Calculate distance from black corner (r=g=b=0) - actually squared but it doesn't matter
         ((d2=(r*r)+(g*g)+(b*b)))
         echo $d2 $r $g $b
      done
   done
done | sort -n | nl 
# sort numerically by distance from black, then number output lines sequentially

这给出了第一列是行号,第二列是黑色的距离(值按此列排序),然后是R,G和B:

     1  0 0 0 0          # From here onwards, pixels map to black
     2  1 0 0 1
     3  1 0 1 0
     4  1 1 0 0
     5  2 0 1 1
     6  2 1 0 1
     7  2 1 1 0
     8  3 1 1 1
     9  4 0 0 2
    10  4 0 2 0
    11  4 2 0 0
    12  5 0 1 2
    13  5 0 2 1
    14  5 1 0 2
    15  5 1 2 0
    16  5 2 0 1
    17  5 2 1 0
    18  6 1 1 2
    19  6 1 2 1
    20  6 2 1 1
    21  8 0 2 2
    22  8 2 0 2
    23  8 2 2 0
    24  9 0 0 3
    25  9 0 3 0
    26  9 1 2 2
    27  9 2 1 2
    28  9 2 2 1
    29  9 3 0 0
    30  10 0 1 3
    31  10 0 3 1
    32  10 1 0 3
    33  10 1 3 0
    34  10 3 0 1
    35  10 3 1 0
    36  11 1 1 3
    37  11 1 3 1
    38  11 3 1 1
    39  12 2 2 2
    40  13 0 2 3
    41  13 0 3 2
    42  13 2 0 3
    43  13 2 3 0
    44  13 3 0 2
    45  13 3 2 0
    46  14 1 2 3
    47  14 1 3 2
    48  14 2 1 3
    49  14 2 3 1
    50  14 3 1 2
    51  14 3 2 1
    52  16 0 4 0
    53  16 4 0 0
    54  17 0 4 1
    55  17 1 4 0
    56  17 2 2 3
    57  17 2 3 2
    58  17 3 2 2
    59  17 4 0 1
    60  17 4 1 0
    61  18 0 3 3
    62  18 1 4 1
    63  18 3 0 3

    64  18 3 3 0          # From here onwards pixels map to dark grey
    65  18 4 1 1
    66  19 1 3 3
    67  19 3 1 3
    68  19 3 3 1
    69  20 0 4 2
    70  20 2 4 0
    71  20 4 0 2
    72  20 4 2 0
    73  21 1 4 2
    74  21 2 4 1
    75  21 4 1 2
    76  21 4 2 1
    77  22 2 3 3
    78  22 3 2 3
    79  22 3 3 2
    80  24 2 4 2
    81  24 4 2 2
    82  25 0 4 3
    83  25 0 5 0
    84  25 3 4 0
    85  25 4 0 3
    86  25 4 3 0
    87  25 5 0 0
    88  26 0 5 1
    89  26 1 4 3
    90  26 1 5 0
    91  26 3 4 1
    92  26 4 1 3
    93  26 4 3 1
    94  26 5 0 1
    95  26 5 1 0
    96  27 1 5 1
    97  27 3 3 3
    98  27 5 1 1
    99  29 0 5 2
   100  29 2 4 3
   101  29 2 5 0
   102  29 3 4 2
   103  29 4 2 3
   104  29 4 3 2
   105  29 5 0 2
   106  29 5 2 0
   107  30 1 5 2
   108  30 2 5 1
   109  30 5 1 2
   110  30 5 2 1
   111  32 4 4 0
   112  33 2 5 2
   113  33 4 4 1
   114  33 5 2 2
   115  34 0 5 3
   116  34 3 4 3
   117  34 3 5 0
   118  34 4 3 3
   119  34 5 0 3
   120  34 5 3 0
   121  35 1 5 3
   122  35 3 5 1
   123  35 5 1 3
   124  35 5 3 1
   125  36 0 6 0
   126  36 4 4 2
   127  36 6 0 0
   128  37 0 6 1

   129  37 1 6 0          # From here onwards pixels map to light grey
   130  37 6 0 1
   131  37 6 1 0
   132  38 1 6 1
   133  38 2 5 3
   134  38 3 5 2
   135  38 5 2 3
   136  38 5 3 2
   137  38 6 1 1
   138  40 0 6 2
   139  40 2 6 0
   140  40 6 0 2
   141  40 6 2 0
   142  41 1 6 2
   143  41 2 6 1
   144  41 4 4 3
   145  41 4 5 0
   146  41 5 4 0
   147  41 6 1 2
   148  41 6 2 1
   149  42 4 5 1
   150  42 5 4 1
   151  43 3 5 3
   152  43 5 3 3
   153  44 2 6 2
   154  44 6 2 2
   155  45 0 6 3
   156  45 3 6 0
   157  45 4 5 2
   158  45 5 4 2
   159  45 6 0 3
   160  45 6 3 0
   161  46 1 6 3
   162  46 3 6 1
   163  46 6 1 3
   164  46 6 3 1
   165  49 0 7 0
   166  49 2 6 3
   167  49 3 6 2
   168  49 6 2 3
   169  49 6 3 2
   170  49 7 0 0
   171  50 0 7 1
   172  50 1 7 0
   173  50 4 5 3
   174  50 5 4 3
   175  50 5 5 0
   176  50 7 0 1
   177  50 7 1 0
   178  51 1 7 1
   179  51 5 5 1
   180  51 7 1 1
   181  52 4 6 0
   182  52 6 4 0
   183  53 0 7 2
   184  53 2 7 0
   185  53 4 6 1
   186  53 6 4 1
   187  53 7 0 2
   188  53 7 2 0
   189  54 1 7 2
   190  54 2 7 1
   191  54 3 6 3
   192  54 5 5 2

   193  54 6 3 3          # From here onwards pixels map to white
   194  54 7 1 2
   195  54 7 2 1
   196  56 4 6 2
   197  56 6 4 2
   198  57 2 7 2
   199  57 7 2 2
   200  58 0 7 3
   201  58 3 7 0
   202  58 7 0 3
   203  58 7 3 0
   204  59 1 7 3
   205  59 3 7 1
   206  59 5 5 3
   207  59 7 1 3
   208  59 7 3 1
   209  61 4 6 3
   210  61 5 6 0
   211  61 6 4 3
   212  61 6 5 0
   213  62 2 7 3
   214  62 3 7 2
   215  62 5 6 1
   216  62 6 5 1
   217  62 7 2 3
   218  62 7 3 2
   219  65 4 7 0
   220  65 5 6 2
   221  65 6 5 2
   222  65 7 4 0
   223  66 4 7 1
   224  66 7 4 1
   225  67 3 7 3
   226  67 7 3 3
   227  69 4 7 2
   228  69 7 4 2
   229  70 5 6 3
   230  70 6 5 3
   231  72 6 6 0
   232  73 6 6 1
   233  74 4 7 3
   234  74 5 7 0
   235  74 7 4 3
   236  74 7 5 0
   237  75 5 7 1
   238  75 7 5 1
   239  76 6 6 2
   240  78 5 7 2
   241  78 7 5 2
   242  81 6 6 3
   243  83 5 7 3
   244  83 7 5 3
   245  85 6 7 0
   246  85 7 6 0
   247  86 6 7 1
   248  86 7 6 1
   249  89 6 7 2
   250  89 7 6 2
   251  94 6 7 3
   252  94 7 6 3
   253  98 7 7 0
   254  99 7 7 1
   255  102 7 7 2
   256  107 7 7 3

显然,最好的方法是使用查找表,这正是这个。

如果我们使用ImageMagick制作一些示例图像并使用此查找表处理它们,我们可以看看它是如何执行的:

# Make a sample
convert -size 100x100 xc: -sparse-color  Bilinear '30,10 red  10,80 blue  70,60 lime  80,20 yellow' -resize 400x400! gradient.png

enter image description here

# Process with suggested LUT
convert gradient.png -fx "@lut.fx" result.png

enter image description here

lut.fx实现了LUT,看起来像这样:

dd=(49*r*r)+(49*g*g)+(16*b*b);
(dd < 19) ? 0.0 : ((dd < 38) ? 0.25 : ((dd < 54) ? 0.75 : 1.0))

相比之下,如果您在我的回答开头实施我的初步建议,请执行以下操作:

R < 0.5 && G < 0.5   => black result
R < 0.5 && G >= 0.5  => dark grey result
R >= 0.5 && G < 0.5  => light grey result
r >= 0.5 && G >= 0.5 => white result

你会得到这个输出 - 正如你所看到的那样,它可以更好地区分红色和绿色,但更糟糕的是反映原始的亮度。

enter image description here