灰度图像转换 Turbo C++
灰度图像转换 Turbo C++
我正在尝试将一个RGB图像转换为灰度图像。RGB图像的尺寸是160*120*4,而我想要的灰度图像尺寸是160*120*1。然而,它只给我纯黑色的图像,并且花费了很长时间。
这是我写的代码,请给予指导,谢谢。
int i, j, sum; Image = new unsigned char [ 160 * 120 * 1 ]; for( int j = 0; j < 120; j++ ) { for( int i = 0; i < 160; i++ ) { sum=0; sum += PaintBox1->Canvas->Pixels[ i ][ j ]; sum += PaintBox1->Canvas->Pixels[ i ][ j ]; sum += PaintBox1->Canvas->Pixels[ i ][ j ]; sum += PaintBox1->Canvas->Pixels[ i ][ j ]; *Image = sum/4; PaintBox2->Canvas->Pixels[ i ][ j ] = *Image; Image++; } }
问题原因:
代码中的一个问题是在最内层的循环中。在这里,你只是将相同的值添加到sum中四次,然后再除以四。这使得这六行代码等同于 *Image = PaintBox1->Canvas->Pixels[i][j]。显然,你实际上想要计算每个通道的平均值。如果你的RGB图像被实现为一个三维数组,那么代码应该是这样的:
sum = 0;
sum += PaintBox1->Canvas->Pixels[i][j][0];
sum += PaintBox1->Canvas->Pixels[i][j][1];
sum += PaintBox1->Canvas->Pixels[i][j][2];
sum += PaintBox1->Canvas->Pixels[i][j][3];
*Image = sum/4;
然而,根据你的代码示例,你的RGB图像实际上被实现为一个二维数组的(无)符号整数。在这种情况下,下面的代码就够用了(假设整数在你的机器上是四字节):
sum = 0;
unsigned int pixel = PaintBox1->Canvas->Pixels[i][j];
for(int k = 0; k < 4; ++k)
{
sum += pixel & 0xFF;
pixel >>= 1;
}
*Image = sum/4;
解决方法:
另一个主要问题是你没有保留灰度数组的开头指针。你将其初始化为 Image = new unsigned char[160 * 120 * 1];,这是对的。但是在循环的每一轮中,你写了 Image++;。而你应该保留一个指向数组开头的指针,并有一个临时指针作为迭代器:
// 在for循环之前
Image = new unsigned char[160 * 120 * 1];
unsigned char * temp = Image;
// 在内部for循环的末尾:
temp++;
你只需要移动 temp 指针,而 Image 保持不变。
关于灰度转换的问题,你希望在目标灰度图像中匹配源RGB图像的亮度。可以使用以下标准公式:Y = 0.299*R + 0.587*G + 0.114*B。
相关链接:stackoverflow.com/questions/687261
在使用Turbo C++中进行灰度图像转换的过程中,出现了以下问题和解决方法。
问题的原因:
1. VCL画布使用TColor来保存颜色,但是内部格式是由Canvas的PixelFormat格式定义的。
2. TColor始终是32位的,无论图像的PixelFormat如何,会经过很多次转换(这就是为什么它很慢)。
3. 不同的PixelFormat设置可能会颠倒RGB顺序,导致预定义颜色也被颠倒。
解决方法:
1. 如果使用VCL的Graphics::TBitmap类,则每个像素是一个32位值。可以安全地对位图使用这种设置,但是对于Form/PaintBox Canvas,由于它们与窗口绑定,所以PixelFormat可能是类似的(很可能是24位),因此需要稍微更改代码。
2. 使用VCL位图而不是Canvas的Pixels属性,可以使用它的ScanLine属性,速度大约是Pixels属性的1000倍以上,还实现了加载/保存功能,可以轻松使用bmp文件。
3. 可以参考以下链接获取更多相关信息和方法。
代码示例:
Graphics::TBitmap *bmp = new Graphics::TBitmap; bmp->PixelFormat = pf32bit; int x, y, xs = 160, ys = 120; DWORD rgb, bw; Image = new unsigned char[xs * ys * 1]; for (y = 0; y < ys; y++) { for (x = 0; x < xs; x++) { rgb = PaintBox1->Canvas->Pixels[x][y]; bw = (rgb & 255) + ((rgb >> 8) & 255) + ((rgb >> 16) & 255); bw /= 3; *Image = bw; Image++; bw *= 0x00010101; PaintBox2->Canvas->Pixels[x][y] = TColor(bw); } } Image -= xs * ys;
以上是关于Turbo C++中灰度图像转换问题的原因和解决方法。可以参考提供的链接获取更多信息和其他转换RGB到灰度的方法。