2015-11-18 50 views
1

我想加载C中的灰度图像,预处理它,然后显示修改后的图像。我的问题是:以C语言阅读并显示灰度图像。

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

在问这个问题之前我自己的搜索。我们可以读取图像,但数据会被加密(压缩),我想要每个像素的灰度值(0-255)。

2 - 有一个API ImageMagick可以是有益的,但它是有与Mac OS X

我在Python和MATLAB进行图像处理的安装问题,但没有关于C语言的想法。

感谢

+0

是学习图像处理的意图,还是想要处理一些图像? –

+0

您是否希望您的软件只能在Mac或跨平台上使用? –

+1

你的OS X安装有什么问题? – emcconville

回答

1

此答案试图演示如何使用ImageMagick的MagickWand API与Xcode一起开发,并基于来自OP的评论。

安装ImageMagick后,启动一个新的Xcode命令行C项目。在编写任何代码之前,您需要告诉关于ImageMagick资源/库/等。

实现这个目标的方法有很多种,但这里最快可以想到。

  • 导航到顶级项目的“构建设置
  • 在“所有”(而不是“基本”)搜索“其它链接器标记
  • 外面的Xcode,开拓终端。应用程序,并输入以下
    • MagickWand-config --ldflags
  • 输入从Terminal.app输出为 “其它链接器标记

Other Linker Flags

  • 早在设置搜索的价值;进入 “其他C标志
  • 早在Terminal.app运行以下
    • MagickWand-config --cflags
  • 输入输出结果为 “其他C标志

Other C Flags

在文件main.c中,您应该注意到Xcode立即拾取MagickWand命令。

MagickWand in Xcode

尝试以下操作(需要安装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; 
} 

...和建设+运行来验证。

Read and display gray scale images in C language

编辑

为了得到灰度(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 
    */ 
+0

不错!有没有办法让Xcode自己执行'MagickWand-config'并动态获取正确的标志,这样如果你已经完成了'brew update'并且所有的版本号和潜在的量子深度等都已经改变? –

+0

是的!通过添加一个'run shell'构建步骤,并导出环境变量,但是在Xcode中需要相当多的点击。在每个新项目开始时记住几乎是可怕的。恕我直言,创建一个本地.xcconfig文件并将它拖放到新的Xcode项目中会容易得多。 – emcconville

+0

@emcconville,非常感谢您的详细描述。我有我的构建成功,但我无法获得图像作为输出。我安装了X11。我正在运行你在这里给出的相同的代码。 – skrealworld

0

macports包没有与Mac的,但我多少经验与OpenCV有很大关系。现在,许多OpenCV都在C++中(这可能会也可能不是问题),但它绝对支持您想要做的一切以及更多。有很多有用的wiki和一个非常好的社区,这很容易。

链接到安装在Mac上:http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/

链接到一些OpenCV的维基:http://opencv.org/documentation.html

编辑: 我还要提到的是老版本的OpenCV是用C和大量的功能仍然支持如果你选择走C路线。

3

您有很多选择,但我会从最简单,最少与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像素宽×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的回答 - 你也可以看到如何从ImageMagick的命令行,在我的其他answer到同一个问题的项目。

Magick ++

如果您选择使用homebrew你会得到Magick ++,这将让你写你的算法在C和C++安装ImageMagick的。它非常易于使用,并且可以在任何平台上运行,包括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”); 

苹果OSX选项

另一个完全独立的选项是使用苹果提供了处理图像的工具 - 它们是快速和易于使用,但不能在Linux或Windows上运行。因此,举例来说,如果你想

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

二)将其保存为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的下载,免费,苹果Xcode,让编译器和库。然后,你必须做

xcode-select --install 

安装的命令行工具,如果你想使用Makefile文件和命令行编译/链接做传统的发展。

+0

感谢您提供'xcode-select --install'说明。人们忘记了这个简单的预先要求。 – emcconville