2015-11-18 48 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