我想在C中加载灰度图像,预处理它然后显示修改后的图像。我的问题是:
用C语言导入灰度图像(jpeg,png格式)的正确方法是什么?
在问这个问题之前我自己搜索。
1- fread或文件管理,我们可以读取图像,但数据将被加密(压缩),我想要每个像素的灰度值(0-255)。
2-有一个API ImageMagick可能会有所帮助,但是Mac OS X存在安装问题。
我已经在python和matlab中完成了图像处理,但对C语言却一无所知。
谢谢
答案 0 :(得分:3)
你有很多选择,但我会从最简单和最不集成的OSX开始,逐步与OSX集成。
最简单的选项
就个人而言,如果我打算处理灰度图像,我会编写我的软件以使用NetPBM的Portable Greymap(PGM)格式,因为这是最简单的读写,并且可以与其他格式轻松互换。没有压缩,DCT,量化,颜色空间,EXIF数据 - 只是带有简单标题的数据。文档为here。
基本上PGM文件如下所示:
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像素宽,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
。然后你可以用:
brew install imagemagick
顺便说一下,如果你想尝试使用OpenCV的其他建议,那么就像
一样简单brew search opencv
brew install homebrew/science/opencv
如果你想要一个小的,自包含的一个小OpenCV项目的例子,看看我对另一个问题here的回答 - 你也可以看到这样的项目如何从命令行得到ImageMagick在我的另一个answer中提出同样的问题。
<强> Magick ++ 强>
如果您选择使用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和命令行编译/链接进行传统开发,请安装命令行工具。
答案 1 :(得分:1)
这个答案试图演示如何使用Xcode开发ImageMagick的MagickWand API,并基于OP的评论。
安装ImageMagick后,启动一个新的Xcode命令行C项目。在编写任何代码之前,您需要告诉llvm有关ImageMagick资源/库/等的信息。
有许多方法可以实现这一目标,但这是我能想到的最快的方法。
MagickWand-config --ldflags
MagickWand-config --cflags
在文件main.c
中,您应该注意Xcode立即拾取MagickWand命令。
尝试以下方法(需要安装X11)......
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
MagickWandGenesis();
MagickWand * wand;
wand = NewMagickWand();
MagickReadImage(wand, "wizard:");
MagickQuantizeImage(wand, 255, GRAYColorspace, 0, MagickFalse, MagickTrue);
MagickDisplayImage(wand, ":0");
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
...并构建+运行以验证。
修改的
要获取每个像素的灰度(0-255)值,您可以调用像素迭代器(请参阅second example here)或export the values。以下是通过导出...
动态填充灰度值列表的示例 // Get image size from wand instance
size_t width = MagickGetImageWidth(wand);
size_t height = MagickGetImageHeight(wand);
size_t total_gray_pixels = width * height;
// Allocate memory to hold values (total pixels * size of data type)
unsigned char * blob = malloc(total_gray_pixels);
MagickExportImagePixels(wand, // Image instance
0, // Start X
0, // Start Y
width, // End X
height, // End Y
"I", // Value where "I" = intensity = gray value
CharPixel, // Storage type where "unsigned char == (0 ~ 255)
blob); // Destination pointer
// Dump to stdout
for (int i = 0; i < total_gray_pixels; i++ ) {
printf("Gray value @ %lux%lu = %d\n", i % width, i / height, (int)blob[i]);
}
/** Example output...
* Gray value @ 0x0 = 226
* Gray value @ 1x0 = 189
* Gray value @ 2x0 = 153
* Gray value @ 3x0 = 116
* Gray value @ 4x0 = 80
* ... etc
*/
答案 2 :(得分:0)
您可以使用以下命令在OS / X上安装ImageMagick:
sudo port install ImageMagick
获取macports
个套餐
答案 3 :(得分:0)
对Mac没有太多经验,但我对OpenCV有很多了解。现在授予许多OpenCV使用C ++(这可能是也可能不是问题)但是它肯定支持你想做的一切以及更多。很容易使用有很多有用的维基和非常好的社区。 p>
在Mac上安装的链接:http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/
链接到某些OpenCV wiki:http://opencv.org/documentation.html
编辑: 我还应该提到旧版本的OpenCV在C中,如果你选择使用C路线,仍然支持很多功能。