c - C语言读取并显示灰度图像。

标签 c image imagemagick grayscale

我想在 C 中加载灰度图像,对其进行预处理,然后显示修改后的图像。我的问题是:

用C语言导入灰度图(jpeg、png格式)的正确方法是什么?

在问这个问题之前我自己的搜索。

1- fread 或使用文件管理,我们可以读取图像但数据将被加密(压缩),我想要每个像素的灰度值(0-255)。

2- 有一个 API ImageMagick这可能会有帮助,但它在 Mac OS X 上存在安装问题。

我用python和matlab做过图像处理,但对C语言一窍不通。

谢谢

最佳答案

您有很多选择,但我将从最简单和与 OSX 集成最少的选项开始,逐步与 OSX 集成得更多。

最简单的选择

就个人而言,如果我打算处理灰度图像,我会编写我的软件以使用 NetPBM 的可移植灰度图 (PGM) 格式,因为这是最简单的读取和写入格式,并且很容易与其他格式互换。没有压缩、DCT、量化、色彩空间、EXIF 数据——只有带有简单标题的数据。文档是 here .

PGM 文件基本上是这样的:

enter image description here

P2
# Shows the word "FEEP" (example from Netpbm man page on PGM)
24 7
15
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

您可以看到 P2 表示它采用 ASCII(易于阅读)和灰度图。然后下一行说它是 24 像素宽 x 7 高,最亮的像素是 15。读写非常简单。您可以将 P2 更改为 P5 并将 MAXVAL 之后的所有内容以二进制形式写入以节省空间。

现在您可以像这样在程序外部使用 ImageMagick 将 JPEG、PNG、GIF、TIFF 文件转换为 PGM - 无需任何链接或库或编译器开关:

convert input.png output.pgm

convert input.jpg output.pgm

同样,当您完成处理并创建 PGM 格式的结果输出文件后,您可以通过简单地反转参数将其转换为 JPEG 或 TIFF:

convert result.pgm result.jpg

就个人而言,我会使用 homebrew 安装 ImageMagick。你去the homebrew website并复制单行代码并将其粘贴到终端中以安装 homebrew。然后你可以安装 ImageMagick:

brew install imagemagick

顺便说一句,如果你想在这里尝试其他建议,使用 OpenCV,那么这很简单

brew search opencv
brew install homebrew/science/opencv

如果您想要一个小型 OpenCV 项目的独立示例,请查看我对另一个问题的回答 here - 您还可以在我的其他 answer 中使用 ImageMagick 从命令行查看这样的项目是如何实现的同一个问题。

魔法++

如果您选择使用 homebrew 安装 ImageMagick,您将获得 Magick++,它允许您用 C 和 C++ 编写算法。它非常易于使用,可以在任何平台上运行,包括 OSX、Windows 和 Linux,因此从这个角度来看它很有吸引力。它还内置了许多图像处理功能。有一个很好的教程 here和文档 here .

您的代码将如下所示:

// Read an image from URL
Image url_image("http://www.serverName.com/image.gif");

// Read image from local filesystem
Image local_file_image("my_image.gif"); 

// Modify image
Pixels my_pixel_cache(my_image);
PixelPacket* pixels;
// define the view area that will be accessed via the image pixel cache
int start_x = 10, start_y = 20, size_x = 200, size_y = 100;
// return a pointer to the pixels of the defined pixel cache
pixels = my_pixel_cache.get(start_x, start_y, size_x, size_y);

// set the color of the first pixel from the pixel cache to black (x=10, y=20 on my_image) 
*pixels = Color("black");

// set to green the pixel 200 from the pixel cache:
// this pixel is located at x=0, y=1 in the pixel cache (x=10, y=21 on my_image) 
*(pixels+200) = Color("green");

// now that the operations on my_pixel_cache have been finalized
// ensure that the pixel cache is transferred back to my_image
my_pixel_cache.sync();

// Save results as BMP file
image.write(“result.bmp”);

Apple OSX 选项

另一个完全独立的选择是使用 Apple 提供的用于处理图像的工具 - 它们快速且易于使用,但不适用于 Linux 或 Windows。所以,例如,如果你想

a) 加载 PNG 文件(或 TIFF 或 JPEG,只需更改扩展名)

b) 将其保存为 JPEG 文件

c) 处理单个像素

// Load a PNG file
NSImage * strImage = [[NSImage alloc]initWithContentsOfFile:@"/Users/mark/Desktop/input.png"];

// Save NSImage as JPG
NSData *imageData = [strImage TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
[imageData writeToFile:@"/Users/Mark/Desktop/result.jpg" atomically:YES];

// Access individual pixels
int w=imageRep.pixelsWide;
int h=imageRep.pixelsHigh;
int bps=imageRep.bitsPerSample;

printf("Dimensions: %dx%d\n",w,h);
printf("bps: %d\n",bps);

// Get a pointer to the uncompressed, unencoded pixel data
unsigned char *pixelData = [imageRep bitmapData];

for(int j=0;j<10;j++){
    printf("Pixel %d: %d\n",j,pixelData[j]);
}

当然,您可以采用上面的代码并轻松制作一个小实用程序,将任何文件格式转换为 PGM,然后您可以按照我的第一个建议使用 PGM 格式,并且不需要安装 ImageMagick - 虽然它是使用 homebrew 实际上非常简单。

请记住,您可以使用 clang(Apple 的编译器)在单个项目中将 Objective-C(如上一个示例所示)与 C++ 和 C 混合使用,因此您可以继续使用 C,正如您在问题中指出的那样我上面给出的例子。

如果您不熟悉在 OSX 上进行开发,则需要前往 AppStore 免费下载 Apple 的 Xcode 以获取编译器和库。那你必须做

xcode-select --install 

如果您希望使用 Makefile 和命令行编译/链接进行传统开发,请安装命令行工具。

关于c - C语言读取并显示灰度图像。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33769797/

相关文章:

php - 使用 PHP 从 JPG 中删除 EXIF 数据

r - 将灰度图像转换并保存为例如绿色配色方案

c - 为什么我在以下代码中打印值 3?

安卓。图片按钮。如何旋转按钮上的图像。不是整个按钮

C、读取文件并分割

image - 如何在 Flutter 中嵌入水印(文本或图像)

java - 图像到字节[]到图像

node.js - 产生 ENOENT 错误

c - 正确的字符处理

c - GCC 不提示未初始化的变量