0

我正在尝试在 VB6 中开发 OCR,但 BMP 格式存在一些问题。我一直在研究 OCR 过程,第一步是使用阈值将图像转换为“黑白”。转换过程很容易理解,我已经做到了。但是,我试图减小生成图像的大小,因为它使用较少的颜色(每个像素只有 256 个可能的灰度值)。在原始图像中,我有 3 种颜色(红色、绿色和蓝色),但现在我只需要一种颜色(灰度值)。在这一刻,我已经实现了转换,但生成的灰度图像与原始彩色图像具有相同的大小(我在三个通道中分配了相同的颜色值)。

我试图修改 BMP 文件的标题,但我没有取得任何成果,现在我不明白它是如何工作的。例如,如果我使用绘画转换图像,则标题中指定的偏移量会更改其值。如果标头是恒定的,为什么偏移量会改变它的值?

4

2 回答 2

1

问题是灰度位图图像与彩色位图图像大小相同,因为用于保存灰色颜色的数据与颜色占用的空间一样多。

唯一的区别是灰色只是相同值的 3 倍。(160,160,160)例如,颜色给出类似(123,200,60). 灰度值只是 RGB 字段的一小部分。

例如,通过将其从 24 位转换为 16 位或 8 位,您可以在转换为灰度后缩小尺寸。尽管这取决于您用于进行转换的内容是否已经提供给您。否则你必须自己做。

您也可以尝试使用 BMP 图像以外的其他东西。PNG 文件也是无损的,使用 24 位版本甚至可以节省空间。图像处理库通常为您提供多种输出格式选项。否则,您可能会找到一个为您执行此操作的库。

于 2012-12-27T12:06:22.743 回答
0

您可以使用“lockbits”方法编写自己的转换。理解如何正确锁定/解锁位需要一段时间,但付出的努力是值得的,一旦你的代码工作了,你就会看到它如何应用于其他场景。例如,使用锁定/解锁位技术,您可以从位图中访问像素值,将这些像素值复制到数组中,操作数组,然后将修改后的数组复制回位图中。这比调用 GetPixel() 和 SetPixel() 快得多。这仍然不是可以编写的最快的图像处理代码,但它相对容易实现和维护代码。

我已经有一段时间没有编写 VB6 代码了,但是 Bob Powell 经常有很好的例子,他有一个关于锁位的页面:

https://web.archive.org/web/20121203144033/http://www.bobpowell.net/lockingbits.htm

在紧要关头,您可以创建一个适当格式的新位图并为每个像素调用 SetPixel():

  1. 24 位彩色图像中的每个像素 (x,y) 都有一个颜色值 (r,g,b)
  2. 转换为 24 位灰度图像后,每个像素 (x,y) 对于每个颜色通道将具有三个相等的值;正如威廉在他的回复中所写的那样,这可以表示为 (n,n,n)。如果所有三种颜色 R、G、B 具有相同的值,那么您可以说颜色值是该像素的“灰度”值。这与您将在最终 8 位位图中看到的灰色阴影相同。
  3. 为新创建的 8 位位图中的每个像素 (x,y) 调用 SetPixel,该位图中的宽度和高度与原始彩色图像相同。
于 2013-01-04T03:25:47.547 回答