简体   繁体   English

用C语言读取和显示灰度图像。

[英]Read and display gray scale images in C language.

I want to load gray scale images in C, pre process it and then display the modified image. 我想在C中加载灰度图像,对其进行预处理,然后显示修改后的图像。 My question is: 我的问题是:

What is the right way to import gray scale images(jpeg,png formats)in C language ? 用C语言导入灰度图像(jpeg,png格式)的正确方法是什么?

My own search before asking this question. 在问这个问题之前,我自己进行了搜索。

1- fread or with file management, we can read image but data will be encrypted(compressed), I want gray scale values(0-255) of each pixel. 1- fread或使用文件管理,我们可以读取图像,但是数据将被加密(压缩),我想要每个像素的灰度值(0-255)。

2- There is one API ImageMagick which can be helpful but it is having installation problem with Mac OS X. 2-有一个API ImageMagick可能会有所帮助,但Mac OS X存在安装问题。

I have done image processing in python and matlab but have no idea about C language. 我已经在python和matlab中完成了图像处理,但是对C语言一无所知。

Thanks 谢谢

You have a number of options, but I will go through them starting with the easiest and least integrated with OSX, and getting progressively more integrated with OSX. 您有很多选择,但我将首先从与OSX的最简单和最少的集成开始,然后逐步与OSX进行更多的集成。

Easiest Option 最简单的选择

Personally, if I was intent on processing greyscale images, I would write my software to use NetPBM's Portable Greymap (PGM) format as that is the very simplest to read and write and readily interchangeable with other formats. 就个人而言,如果我打算处理灰度图像,我会编写软件以使用NetPBM的可移植灰度图(PGM)格式,因为它是最简单的读写方式,并且很容易与其他格式互换。 There is no compression, DCT, quantisation, colorspaces, EXIF data - just your data with a simple header. 没有压缩,DCT,量化,色彩空间,EXIF数据-只是带有简单标头的数据。 The documentation is here . 文档在这里

Basically a PGM file looks like this: 基本上,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

You can see the P2 says it is in ASCII (easy to read) and a greymap. 您可以看到P2表示为ASCII(易于阅读)和灰度图。 Then the next line says it is 24 pixels wide by 7 tall and that the brightest pixel is 15. Very simple to read and write. 然后下一行说它是24像素宽乘以7高,而最亮的像素是15。读取和写入非常简单。 You can change the P2 to P5 and write everything after the MAXVAL in binary to save space. 您可以将P2更改为P5 ,并将MAXVAL之后的所有内容写入二进制文件以节省空间。

Now you can just use ImageMagick outside your program to convert JPEG, PNG, GIF, TIFF files to PGM like this - without needing any linking or libraries or compiler switches: 现在,您只需在程序外部使用ImageMagick即可将JPEG,PNG,GIF,TIFF文件转换为PGM,就像这样-无需任何链接,库或编译器开关:

convert input.png output.pgm

convert input.jpg output.pgm

Likewise, when you have finished processing and created your resulting output file in PGM format you can convert it to JPEG or TIFF by simply reversing the parameters: 同样,在完成处理并以PGM格式创建结果输出文件后,您只需简单地反转参数即可将其转换为JPEG或TIFF:

convert result.pgm result.jpg

Personally, I would install ImageMagick using homebrew . 就个人而言,我将使用homebrew安装ImageMagick。 You go to the homebrew website and copy the one-liner and paste it into a terminal to install homebrew . 您可以访问homebrew网站并复制单行代码并将其粘贴到终端中以安装homebrew Then you can install ImageMagick with: 然后,您可以使用以下命令安装ImageMagick:

brew install imagemagick

and, by the way, if you want to try out the other suggestion here, using OpenCV, then that is as easy as 顺便说一句,如果您想在这里尝试其他建议(使用OpenCV),那么就像

brew search opencv
brew install homebrew/science/opencv

If you want a small, self-contained example of a little OpenCV project, have a look at my answer to another question here - you can also see how a project like that is possible from the command line with ImageMagick in my other answer to the same question. 如果您想获得一个小的OpenCV项目的独立示例,请在这里查看我对另一个问题的回答-您还可以在我的其他答案中 ,通过ImageMagick在命令行中查看像这样的项目如何实现同样的问题。

Magick++ Magick ++

If you choose to install ImageMagick using homebrew you will get Magick++ which will allow you to write your algorithms in C and C++. 如果选择使用homebrew安装ImageMagick,则将获得Magick ++,它将允许您使用C和C ++编写算法。 It is pretty easy to use and can run on any platforms, including OSX and Windows and Linux so it is attractive from that point of view. 它非常易于使用,并且可以在包括OSX,Windows和Linux在内的任何平台上运行,因此从该角度来看很有吸引力。 It also has many, many image-processing functions built right in. There is a good tutorial here , and documentation here . 它还具有内置了许多,许多图像处理功能。这是一个很好的教程在这里 ,和文档在这里

Your code will look something like this: 您的代码将如下所示:

// 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 Option Apple OSX选件

The other ENTIRELY SEPARATE option would be to use the tools that Apple provides for manipulating images - they are fast and easy to use, but are not going to work on Linux or Windows. 另一个“完全分开”的选项是使用Apple提供的用于处理图像的工具-它们既快速又易于使用,但不适用于Linux或Windows。 So, for example, if you want to 因此,例如,如果您想

a) load a PNG file (or a TIFF or JPEG, just change the extension) a)加载PNG文件(或TIFF或JPEG,只需更改扩展名)

b) save it as a JPEG file b)将其另存为JPEG文件

c) process the individual pixels 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]);
}

Of course, you could take the code above and easily make a little utility that converts any file format to PGM and then you could go with my first suggestion of using PGM format and wouldn't need to install ImageMagick - although it is actually dead simple with homebrew . 当然,您可以使用上面的代码,并轻松地创建一个将任何文件格式转换为PGM的小实用程序,然后您可以接受我的第一个使用PGM格式的建议,并且不需要安装ImageMagick-尽管它实际上非常简单homebrew

Bear in mind that you can mix Objective-C (as in the last example) with C++ and C in a single project using clang (Apple's compiler), so you can go ahead in C as you indicate in your question with any of the examples I have given above. 请记住,您可以使用clang(Apple的编译器)在单个项目中将Objective-C(与上一个示例一样)与C ++和C混合使用,因此您可以使用任何示例在问题中指出的情况下继续使用C我已经在上面给出了。

If you are new to developing on OSX, you need to go to the AppStore and download, for free, Apple's Xcode to get the compiler and libraries. 如果您不熟悉在OSX上进行开发,则需要转到AppStore并免费下载Apple的Xcode以获取编译器和库。 Then you must do 那你必须做

xcode-select --install 

to install the command-line tools if you wish to do traditional development using Makefiles and command-line compilation/linking. 如果希望使用Makefile和命令行编译/链接进行传统开发,请安装命令行工具。

This answer is an attempt to demonstrate how to develop with ImageMagick's MagickWand API with Xcode, and is based on the comments from the OP. 该答案是试图演示如何使用ImageMagick的MagickWand API和Xcode进行开发,并且基于OP的注释。

After installing ImageMagick, start a new Xcode command-line C project. 安装ImageMagick之后,启动一个新的Xcode命令行C项目。 Before writing any code, you need to tell about the ImageMagick resources/libraries/etc. 在编写任何代码之前,您需要告诉有关ImageMagick的资源/库/等。

There are many, many, ways to achieve this, but here's the quickest I can think of. 有很多方法可以实现这一目标,但这是我能想到的最快的方法。

  • Navigate to top-level project's " Build Settings " 导航到顶级项目的“ 构建设置
  • Under "All" (not "Basic") search for " Other Linker Flags " 在“全部”(不是“基本”)下搜索“ 其他链接器标记
  • Outside of Xcode, open up Terminal.app and enter the following 在Xcode之外,打开Terminal.app并输入以下内容
    • MagickWand-config --ldflags
  • Enter the output from Terminal.app as the value for " Other Linker Flags " 输入Terminal.app的输出作为“ 其他链接器标志 ”的值

其他链接器标志

  • Back in the settings search; 返回设置搜索; enter " Other C Flags " 输入“ 其他C标志
  • Back in Terminal.app run the following 回到Terminal.app运行以下命令
    • MagickWand-config --cflags
  • Enter the resulting output as the value for " Other C Flags " 输入结果输出作为“ Other C Flags ”的值

其他C标志

Over in file main.c , you should notice Xcode picking-up MagickWand commands right away. 在文件main.c ,您应该立即注意到Xcode拾取MagickWand命令。

Xcode中的MagickWand

Try the following (needs X11 installed) ... 尝试以下操作(需要安装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;
}

... and build + run to verify. ...并构建+运行以进行验证。

用C语言读取和显示灰度图像

edit 编辑

To get the gray scale (0-255) value for each pixel, you can invoke a pixel iterator (see second example here ), or export the values . 要获取每个像素的灰度(0-255)值,您可以调用像素迭代器(请参见此处的第二个示例 ),或导出这些值 Here is an example of dynamically populating a list of gray values by exporting... 这是通过导出动态填充灰度值列表的示例。

    // 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
     */

You can install ImageMagick on OS/X with this command: 您可以使用以下命令在OS / X上安装ImageMagick:

sudo port install ImageMagick

You can get the macports package from https://www.macports.org 您可以从https://www.macports.org获取macports软件包

Don't have much experience with Mac's but I have quite a lot with OpenCV. 在Mac方面经验不足,但在OpenCV方面我有很多经验。 Now granted a lot of OpenCV is in C++ (which may or may not be a problem) however it definitely supports everything you want to do and more. 现在授予了许多OpenCV使用C ++的权限(这可能是问题也可能不是问题),但是它绝对支持您想做的所有事情以及更多。 It's very easy to work with has lot's of helpful wiki's and a very good community. 拥有很多有用的Wiki和一个非常好的社区,这非常容易使用。

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

Link to some OpenCV wikis: http://opencv.org/documentation.html 链接到一些OpenCV Wiki: http : //opencv.org/documentation.html

EDIT: I should also mention that older versions of OpenCV are in C and a lot of the functions are still supported if you chose to go the C route. 编辑:我还应该提到OpenCV的旧版本在C语言中,如果您选择使用C语言,仍然支持许多功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM