阅读PPM图像问题
Read PPM image issues
我一直有吨的麻烦让我的算法成功读取PPM图像…它可以完美地处理一些图像,但在处理其他图像时却失败了,导致图像呈现半灰色(RGB 205,205,205)。
我已经尝试了我能找到的一切,并研究了几个小时。我已经被困了一个星期了。
我希望你们能帮忙。
Image* pnm_read(char* filePath)
{
FILE* file;
char token[20];
int imageWidth, imageHeight, maximumColorValue;
Image* image;
/* Abre arquivo PNM. */
file = fopen(filePath, "r");
if (file == NULL)
{
fprintf(stderr, "Não foi possível localizar o arquivo de imagem %s.n", filePath);
return 0;
}
/* Lê Magic Number do cabecalho e vê se é P6*/
pnm_get_token(file, token, sizeof token);
if (strcmp(token, "P6"))
{
fprintf(stderr, "%s não é um arquivo PPM válido.n", filePath);
fclose(file);
return 0;
}
//Lê widht, height e valor máximo rgb
if (sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageWidth) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageHeight) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &maximumColorValue) != 1)
{
fprintf(stderr, "%s não é um arquivo PNM válido.n", filePath);
fclose(file);
return 0;
}
//Se não for RGB com componentes de 8 bits (0-255) dá erro
if (maximumColorValue != 255)
{
fprintf(stderr, "%s does not have 8-bit components: maximumColorValue=%dn", filePath, maximumColorValue);
fclose(file);
return 0;
}
image = new Image(imageWidth, imageHeight);
unsigned char* pixelComponents = new unsigned char[imageWidth * imageHeight * 3];
fread(pixelComponents, sizeof(unsigned char), imageWidth * imageHeight * 3, file);
fclose(file);
int r, g, b, pixel;
for(int i = 3; i <= imageWidth * imageHeight * 3; i += 3)
{
r = pixelComponents[i-3] & 0xff;
g = pixelComponents[i-2] & 0xff;
b = pixelComponents[i-1] & 0xff;
/*fread(&r, sizeof(char), sizeof(char), file);
fread(&g, sizeof(char), sizeof(char), file);
fread(&b, sizeof(char), sizeof(char), file);
r = r & 0xff;
g = g & 0xff;
b = b & 0xff;*/
pixel = (255 << 24) | (r << 16) | (g << 8) | b;
// Atribuindo os pixels e virando imagem de cabeca para baixo
image->pixels[ (imageWidth * imageHeight) - (i/3) - 1] = pixel;
}
printf("Lido arquivo PNM (%s): %dx%d pixels.n", filePath, image->width, image->height);
return image;
}
我修改了你的代码,使用结构体来帮助理解和帮助调试。我还删除了难以调试的片段,如"(imageWidth * imageHeight) - (I/3) - 1",并引入了一些临时变量来辅助。
一些注意事项:你的图像像素似乎包括一个alpha通道,所以我添加了一个到RGBA像素类型。这些pragma也假定与gcc保持一致。我假设这是可以接受的,因为没有提到编译器。最后,这个例子更倾向于可读性而不是效率。有"更好"的方法来处理RGB和RGBA像素类型,但希望这能让你在正确的方向上开始。
typedef unsigned char u8; // define a more concise data type
// Save current packing to ensure the pixel struct is 3 bytes in size
#pragma pack(push)
// Pack on 1-byte boundaries
#pragma pack(1)
typedef struct
{
u8 red;
u8 green;
u8 blue;
u8 alpha;
} RgbaPixel;
typedef struct
{
u8 red;
u8 green;
u8 blue;
} RgbPixel;
// Restore previous packing
#pragma pack(pop)
Image* pnm_read(char* filePath)
{
FILE* file = NULL;
char token[20] = "";
int imageWidth = 0;
int imageHeight = 0;
int maximumColorValue = 0;
int numPixels = 0;
int numRead = 0;
Image* image = NULL;
/* Abre arquivo PNM. */
file = fopen(filePath, "r");
if (file == NULL)
{
fprintf(stderr, "Não foi possível localizar o arquivo de imagem %s.n", filePath);
return 0;
}
/* Lê Magic Number do cabecalho e vê se é P6*/
pnm_get_token(file, token, sizeof token);
if (strcmp(token, "P6"))
{
fprintf(stderr, "%s não é um arquivo PPM válido.n", filePath);
fclose(file);
return 0;
}
//Lê widht, height e valor máximo rgb
if (sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageWidth) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageHeight) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &maximumColorValue) != 1)
{
fprintf(stderr, "%s não é um arquivo PNM válido.n", filePath);
fclose(file);
return 0;
}
//Se não for RGB com componentes de 8 bits (0-255) dá erro
if (maximumColorValue != 255)
{
fprintf(stderr, "%s does not have 8-bit components: maximumColorValue=%dn", filePath, maximumColorValue);
fclose(file);
return 0;
}
image = new Image(imageWidth, imageHeight);
numPixels = imageWidth * imageHeight;
RgbPixel* pixelComponents = new RgbPixel [numPixels];
numRead = fread(pixelComponents, sizeof(RgbPixel), numPixels, file);
fclose(file);
if (numRead != numPixels)
{
// Problem!
return 0;
}
RgbaPixel pixel = {0};
for (int i = 0; i < numPixels; i++)
{
pixel.alpha = 255;
pixel.red = pixelComponents[i].red;
pixel.green = pixelComponents[i].green;
pixel.blue = pixelComponents[i].blue;
// Atribuindo os pixels e virando imagem de cabeca para baixo
image->pixels[i] = pixel;
}
printf("Lido arquivo PNM (%s): %dx%d pixels.n", filePath, image->width, image->height);
return image;
}
正确读取文件中的数据(宽度和高度)后,可以执行如下操作(我改编了我之前写的代码):
...
for(int i=0; i < height; ++i)
{
for(int j=0; j < width; ++j)
{
// Get pixel index from the PPM data
int pixelIndex = (i*3) * width + (j*3);
int r = pixelComponents[pixelIndex];
int g = pixelComponents[pixelIndex + 1];
int b = pixelComponents[pixelIndex + 2];
// Calc gray value from RGB
int pixelValue = 0.2126f * r + 0.7152f * g + 0.0722f * b;
// Set pixel (i, j) in the output image
image->pixel[i * width + j] = pixelValue;
}
}
...
我不能保证代码是正确的,但我想它可能会帮助你找到解决问题的方法。
祝你好运!
相关文章:
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 我在 OpenGL 中显示图像时遇到问题
- openCV c++中手动侵蚀图像的问题(二进制图像)
- 问题 (std::bad_alloc) 通过 QThread 中的 QSqlQuery 将大图像(约 36 MB)保存到
- CMake 的测试:找不到图像(可能的 rpath 问题)
- 加载带有stb_image的图像时出现问题
- 使用 ImageMagick 从像素强度数组创建灰度图像时遇到问题
- C :阅读位图图像的问题
- STB图像写问题
- 使用 qt 和 opengl、定时精度和垂直同步问题、c++ 显示图像
- 多模图像对齐问题
- 在 Python 中使用 OpenCV 将打包的 BGRA 图像缓冲区转换为 RGB 时遇到问题
- 滚动条缩略图跟踪长度 基于图像的水平适合调整窗口大小时出现问题
- 将颜色图像转换为OpenCV中的灰度问题
- C++:OpenCV扫描图像的性能问题
- SDL2图像到屏幕问题
- 通过套接字发送的图像流-服务器死锁问题
- 自定义图像格式的奇怪OpenCV问题
- 在c++中处理图像和像素值时出现问题
- 读取 ppm p6 图像完成时出现问题.C++