【发布时间】:2014-11-25 08:32:26
【问题描述】:
我正在尝试用一些用 C 编写的代码来否定位图图像。
当我第一次运行 Lena 图像(让我称之为 LenaImage1)的代码时,我得到一个黑色图像 (LenaImage2)。当我在图像上运行相同的代码时,我会取回原始图像(LenaImage1)。这意味着代码可以正常工作吗? 当我使用 MATLAB 查看和保存(作为位图)LenaImage2 时,我没有得到黑色图像,这意味着我可以将其视为补充图像(MATLAB 返回相同的输出)。
当我在第二张图像 (MountainImage1) 上运行相同的 C 代码时,我得到一个非常糟糕的图像 (MounainImage2),其中有很多伪着色,但不是黑色图像作为输出。当我在 MATLAB 中运行代码来赞美 MounainImage1 时,我得到了看起来像正确图像但没有伪着色的图像。当我在 MountainImage2 上运行 C 代码时,我得到了原始图像(即 MountainImage1)。
在第三张图像上运行代码会显示类似于 Lena 图像的行为。所有提到的图片都可以在here找到。
另一个answer 提到位图图像不支持透明度。
我在这里看到的是透明度问题吗? 如果是,为什么我没有在所有图像中看到此透明度问题的一致行为? 另外,当我使用 MATLAB 查看和保存 LenaImage2 以及 MountainImage2 时,它没有显示黑色图像或任何伪着色,这是怎么回事? 如何更正我的 C 代码?
这是反转图像的代码:
我的头文件中的文件头声明:
#pragma pack(push,1)
typedef struct bmpFileHeader
{
unsigned short bfType; /*specifies the file type*/
unsigned long bfSize; /*specifies the size in bytes of the bitmap file*/
unsigned short bfReserved1; /*reserved; must be 0*/
unsigned short bfReserved2; /*reserved; must be 0*/
unsigned long bfOffBits; /*species the offset in bytes from the bitmapfileheader to the bitmap bits*/
}bmpFileHeader;
typedef struct bmpInfoHeader
{
unsigned long biSize; /*Size of bmpInfoHeader*/
unsigned long biWidth; /*specifies width in pixels*/
unsigned long biHeight; /*species height in pixels*/
unsigned short biPlanes; /*specifies the number of color planes, must be 1*/
unsigned short biBitCount; /*specifies the number of bit per pixel*/
unsigned long biCompression; /*spcifies the type of compression*/
unsigned long biSizeImage; /*size of image in bytes*/
unsigned long biXPelsPerMeter; /*number of pixels per meter in x axis*/
unsigned long biYPelsPerMeter; /*number of pixels per meter in y axis*/
unsigned long biClrUsed; /*number of colors used by the bitmap*/
unsigned long biClrImportant; /*number of colors that are important*/
}bmpInfoHeader;
#pragma pack(pop)
完成工作的代码:
void ImageData(FILE *filePtr)
{
bmpFileHeader FileHeader;
bmpInfoHeader InfoHeader;
char *bmpImageData; /*array to hold the image data*/
size_t imagedataSize=0,check=0;
int y;
/*read the bitmap file header*/
check=fread(&FileHeader, sizeof(bmpFileHeader),1,filePtr);
printf("checkFileHeader=%d\n",check);
/*verify that this is a bmp file by check bitmap id*/
if (FileHeader.bfType !=0x4D42)
{
fclose(filePtr);
printf("ImageData:Is not a BMP file\n");
return;
}
/*read the bitmap info header*/
check=fread(&InfoHeader, sizeof(InfoHeader),1,filePtr);
printf("checkInfoHeader=%d\n",check);
/*Allocate space for the image data*/
bmpImageData=(char*)malloc(InfoHeader.biSizeImage);
if(bmpImageData==NULL){
printf("Couldn't allocate memory for ImageData\n");
return;
}
/*move the file position to the point where the aligned image data begins*/
check=fseek(filePtr,FileHeader.bfOffBits,SEEK_SET);
if(check!=0){
printf("Error seeking file\n");
return;
}
/*Copy the image data to bmpImageData*/
check=fread(bmpImageData,InfoHeader.biSizeImage,1,filePtr);
if(check!=1){
printf("Error reading image data\n");
return
}
/*Moving filePtr to position where image data begins*/
check=fseek(filePtr,FileHeader.bfOffBits,SEEK_SET);
if(check!=0){
printf("Error seeking file\n");
return;
}
/*Manipulating the image data*/
for(y=0;y<InfoHeader.biSizeImage;y++){
bmpImageData[y]=255-bmpImageData[y];
}
check=fwrite(bmpImageData,InfoHeader.biSizeImage,1,filePtr);
if(check!=1)
printf("Error writing image data to file");
free(bmpImageData);
}
我使用的所有图像都是 8 位像素深度的灰度图像。我在 x86 机器上使用 CodeBlocks IDE(GNU GCC 编译器) 运行 Windows 8。
补充: 这是 Lena 图像的标题字段读取的内容:
File Header Information
FileHeaderSize=14
bfType=4d42
bfSize=263222
bfReserved1=0
bfReserved2=0
bfOffBits=1078
Info Header Information
InfoHeaderSize=40
biSize=40
biHeight=512
biWidth=512
biPlanes=1
biBitCount=8
biCompression=0
biSizeImage=262144
biXPelsPerMeter=0
biYPelsPerMeter=0
biClrUsed=256
biClrImportant=256
【问题讨论】:
-
我对您要做什么没有高级别的概述,但您看起来好像被某种专有的、低效的(垃圾)Microsoft 文件格式纠缠不清。请看一下 Netpbm 的
PGM格式(便携式灰度图),它支持 Matlab 和 MILES 更容易编程...en.wikipedia.org/wiki/Netpbm_format -
我去看看马克!谢谢!但是在我们的图像处理课程中,我们要编写 C 代码来处理 BMP 文件格式的图像,这就是为什么我现在必须限制自己。
-
快速猜测:你的图像数据不应该是
unsigned chars 而不是chars? -
@M Oehm 我确实从
unsigned char开始,但后来将其更改为char似乎在这里没有任何区别。输出确实保持不变。 -
我没有 BMP 文档,但
bfOffBits不是 54,biClrUsed不是 0 的事实都是您拥有基于调色板的图像的线索。也就是说字节值不是灰度值。它们是调色板的索引。从 255 中减去会得到一个无意义的图像,但它是可逆的,因此您可以通过运行您的代码两次来恢复原始图像。
标签: c matlab image-processing bitmapimage