我有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
我们可以看到,
因此上面的图像实际上总共有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的所有值量化为相应的灰色阴影吗?
答案 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,那么我们将使内核中的所有像素变黑,外核中的像素为深灰色,地幔中的像素为浅灰色,外壳为白色 - 如每个肿块中原始像素的数量是相同的。这听起来很复杂但不是!
让我们运行所有可能的红色,绿色和蓝色值,并使用
计算每个值与黑色的距离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
# Process with suggested LUT
convert gradient.png -fx "@lut.fx" result.png
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
你会得到这个输出 - 正如你所看到的那样,它可以更好地区分红色和绿色,但更糟糕的是反映原始的亮度。